diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs b/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs index a5d2e85be9b..ebc752faba2 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs @@ -115,6 +115,14 @@ namespace Microsoft.Extensions.Hosting // Add the EventLogLoggerProvider on windows machines logging.AddEventLog(); } + + logging.Configure(options => + { + options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId + | ActivityTrackingOptions.TraceId + | ActivityTrackingOptions.ParentId; + }); + }) .UseDefaultServiceProvider((context, options) => { diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs index 5d403428540..5a8e418e8b3 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Tracing; using System.IO; using System.Linq; @@ -60,6 +61,45 @@ namespace Microsoft.Extensions.Hosting args.Payload.OfType().Any(p => p.Contains("Request starting"))); } + [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/34580", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] + public void CreateDefaultBuilder_EnablesActivityTracking() + { + var parentActivity = new Activity("ParentActivity"); + parentActivity.Start(); + var activity = new Activity("ChildActivity"); + activity.Start(); + var id = activity.Id; + var logger = new ScopeDelegateLogger((scopeObjectList) => + { + Assert.Equal(1, scopeObjectList.Count); + var activityDictionary = (scopeObjectList.FirstOrDefault() as IEnumerable>) + .ToDictionary(x => x.Key, x => x.Value); + switch (activity.IdFormat) + { + case ActivityIdFormat.Hierarchical: + Assert.Equal(activity.Id, activityDictionary["SpanId"]); + Assert.Equal(activity.RootId, activityDictionary["TraceId"]); + Assert.Equal(activity.ParentId, activityDictionary["ParentId"]); + break; + case ActivityIdFormat.W3C: + Assert.Equal(activity.SpanId.ToHexString(), activityDictionary["SpanId"]); + Assert.Equal(activity.TraceId.ToHexString(), activityDictionary["TraceId"]); + Assert.Equal(activity.ParentSpanId.ToHexString(), activityDictionary["ParentId"]); + break; + } + }); + var loggerProvider = new ScopeDelegateLoggerProvider(logger); + var host = Host.CreateDefaultBuilder() + .ConfigureLogging(logging => + { + logging.AddProvider(loggerProvider); + }) + .Build(); + + logger.LogInformation("Dummy log"); + } + [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/34580", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void CreateDefaultBuilder_EnablesScopeValidation() @@ -178,6 +218,65 @@ namespace Microsoft.Extensions.Hosting internal class ServiceC { } + private class ScopeDelegateLoggerProvider : ILoggerProvider, ISupportExternalScope + { + private ScopeDelegateLogger _logger; + private IExternalScopeProvider _scopeProvider; + public ScopeDelegateLoggerProvider(ScopeDelegateLogger logger) + { + _logger = logger; + } + public ILogger CreateLogger(string categoryName) + { + _logger.ScopeProvider = _scopeProvider; + return _logger; + } + + public void Dispose() + { + } + + public void SetScopeProvider(IExternalScopeProvider scopeProvider) + { + _scopeProvider = scopeProvider; + } + } + + private class ScopeDelegateLogger : ILogger + { + private Action> _logDelegate; + internal IExternalScopeProvider ScopeProvider { get; set; } + public ScopeDelegateLogger(Action> logDelegate) + { + _logDelegate = logDelegate; + } + public IDisposable BeginScope(TState state) + { + Scopes.Add(state); + return new Scope(); + } + + public List Scopes { get; set; } = new List(); + + public bool IsEnabled(LogLevel logLevel) => true; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + ScopeProvider.ForEachScope((scopeObject, state) => + { + Scopes.Add(scopeObject); + }, 0); + _logDelegate(Scopes); + } + + private class Scope : IDisposable + { + public void Dispose() + { + } + } + } + private class TestEventListener : EventListener { private volatile bool _disposed;