|
5 | 5 | using System; |
6 | 6 | using System.Collections.Concurrent; |
7 | 7 | using System.Collections.Generic; |
| 8 | +using System.Diagnostics; |
8 | 9 | using System.Diagnostics.Tracing; |
9 | 10 | using System.IO; |
10 | 11 | using System.Linq; |
@@ -60,6 +61,45 @@ public void CreateDefaultBuilder_RegistersEventSourceLogger() |
60 | 61 | args.Payload.OfType<string>().Any(p => p.Contains("Request starting"))); |
61 | 62 | } |
62 | 63 |
|
| 64 | + [Fact] |
| 65 | + [ActiveIssue("https://github.com/dotnet/runtime/issues/34580", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] |
| 66 | + public void CreateDefaultBuilder_EnablesActivityTracking() |
| 67 | + { |
| 68 | + var parentActivity = new Activity("ParentActivity"); |
| 69 | + parentActivity.Start(); |
| 70 | + var activity = new Activity("ChildActivity"); |
| 71 | + activity.Start(); |
| 72 | + var id = activity.Id; |
| 73 | + var logger = new ScopeDelegateLogger((scopeObjectList) => |
| 74 | + { |
| 75 | + Assert.Equal(1, scopeObjectList.Count); |
| 76 | + var activityDictionary = (scopeObjectList.FirstOrDefault() as IEnumerable<KeyValuePair<string, object>>) |
| 77 | + .ToDictionary(x => x.Key, x => x.Value); |
| 78 | + switch (activity.IdFormat) |
| 79 | + { |
| 80 | + case ActivityIdFormat.Hierarchical: |
| 81 | + Assert.Equal(activity.Id, activityDictionary["SpanId"]); |
| 82 | + Assert.Equal(activity.RootId, activityDictionary["TraceId"]); |
| 83 | + Assert.Equal(activity.ParentId, activityDictionary["ParentId"]); |
| 84 | + break; |
| 85 | + case ActivityIdFormat.W3C: |
| 86 | + Assert.Equal(activity.SpanId.ToHexString(), activityDictionary["SpanId"]); |
| 87 | + Assert.Equal(activity.TraceId.ToHexString(), activityDictionary["TraceId"]); |
| 88 | + Assert.Equal(activity.ParentSpanId.ToHexString(), activityDictionary["ParentId"]); |
| 89 | + break; |
| 90 | + } |
| 91 | + }); |
| 92 | + var loggerProvider = new ScopeDelegateLoggerProvider(logger); |
| 93 | + var host = Host.CreateDefaultBuilder() |
| 94 | + .ConfigureLogging(logging => |
| 95 | + { |
| 96 | + logging.AddProvider(loggerProvider); |
| 97 | + }) |
| 98 | + .Build(); |
| 99 | + |
| 100 | + logger.LogInformation("Dummy log"); |
| 101 | + } |
| 102 | + |
63 | 103 | [Fact] |
64 | 104 | [ActiveIssue("https://github.com/dotnet/runtime/issues/34580", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] |
65 | 105 | public void CreateDefaultBuilder_EnablesScopeValidation() |
@@ -178,6 +218,65 @@ public ServiceB(ServiceC c) |
178 | 218 |
|
179 | 219 | internal class ServiceC { } |
180 | 220 |
|
| 221 | + private class ScopeDelegateLoggerProvider : ILoggerProvider, ISupportExternalScope |
| 222 | + { |
| 223 | + private ScopeDelegateLogger _logger; |
| 224 | + private IExternalScopeProvider _scopeProvider; |
| 225 | + public ScopeDelegateLoggerProvider(ScopeDelegateLogger logger) |
| 226 | + { |
| 227 | + _logger = logger; |
| 228 | + } |
| 229 | + public ILogger CreateLogger(string categoryName) |
| 230 | + { |
| 231 | + _logger.ScopeProvider = _scopeProvider; |
| 232 | + return _logger; |
| 233 | + } |
| 234 | + |
| 235 | + public void Dispose() |
| 236 | + { |
| 237 | + } |
| 238 | + |
| 239 | + public void SetScopeProvider(IExternalScopeProvider scopeProvider) |
| 240 | + { |
| 241 | + _scopeProvider = scopeProvider; |
| 242 | + } |
| 243 | + } |
| 244 | + |
| 245 | + private class ScopeDelegateLogger : ILogger |
| 246 | + { |
| 247 | + private Action<List<object>> _logDelegate; |
| 248 | + internal IExternalScopeProvider ScopeProvider { get; set; } |
| 249 | + public ScopeDelegateLogger(Action<List<object>> logDelegate) |
| 250 | + { |
| 251 | + _logDelegate = logDelegate; |
| 252 | + } |
| 253 | + public IDisposable BeginScope<TState>(TState state) |
| 254 | + { |
| 255 | + Scopes.Add(state); |
| 256 | + return new Scope(); |
| 257 | + } |
| 258 | + |
| 259 | + public List<object> Scopes { get; set; } = new List<object>(); |
| 260 | + |
| 261 | + public bool IsEnabled(LogLevel logLevel) => true; |
| 262 | + |
| 263 | + public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) |
| 264 | + { |
| 265 | + ScopeProvider.ForEachScope((scopeObject, state) => |
| 266 | + { |
| 267 | + Scopes.Add(scopeObject); |
| 268 | + }, 0); |
| 269 | + _logDelegate(Scopes); |
| 270 | + } |
| 271 | + |
| 272 | + private class Scope : IDisposable |
| 273 | + { |
| 274 | + public void Dispose() |
| 275 | + { |
| 276 | + } |
| 277 | + } |
| 278 | + } |
| 279 | + |
181 | 280 | private class TestEventListener : EventListener |
182 | 281 | { |
183 | 282 | private volatile bool _disposed; |
|
0 commit comments