public static ITracer Decorate( [NotNull] this ITracer source, [NotNull] TracerDecoration publicDecoration) { var decoration = publicDecoration as ITracerDecoration; var builder = new TracerDecoratorBuilder(source); // For performance, to avoid a level of indirection when not needed bool bypassBuilder = true; // Checking for null to avoid adding them if they're not implemented since the underlying library has optimizations if not subscribed if (decoration.OnSpanStarted != null) { builder = builder.OnSpanStarted(decoration.OnSpanStarted); bypassBuilder = false; } if (decoration.OnSpanFinished != null) { builder = builder.OnSpanFinished(decoration.OnSpanFinished); bypassBuilder = false; } if (decoration.OnSpanLog != null) { builder = builder.OnSpanLog(decoration.OnSpanLog); bypassBuilder = false; } if (decoration.OnSpanSetTag != null) { builder = builder.OnSpanSetTag(decoration.OnSpanSetTag); bypassBuilder = false; } if (decoration.OnSpanActivated != null) { builder = builder.OnSpanActivated(decoration.OnSpanActivated); bypassBuilder = false; } if (decoration.OnSpanStartedWithFinishCallback != null) { builder = builder.OnSpanStartedWithCallback(decoration.OnSpanStartedWithFinishCallback); bypassBuilder = false; } if (bypassBuilder) { return(source); } else { return(builder .Build()); } }
ITracer GetDecoratedTracer(string flavor) { var originalTracer = new MockTracer(); var builder = new TracerDecoratorBuilder(originalTracer); switch (flavor) { case "StartedtAndFinished": builder .OnSpanStarted((span, name) => Interlocked.Increment(ref startedSpanCount)) .OnSpanFinished((span, name) => Interlocked.Decrement(ref startedSpanCount)) ; break; case "StartedWithCallback": builder .OnSpanStartedWithCallback((span, name) => { Interlocked.Increment(ref startedSpanCount); return((s, n) => Interlocked.Decrement(ref startedSpanCount)); }) ; break; case "Both": builder .OnSpanStarted((span, name) => Interlocked.Increment(ref startedSpanCount)) .OnSpanFinished((span, name) => Interlocked.Decrement(ref startedSpanCount)) .OnSpanStartedWithCallback((span, name) => { Interlocked.Increment(ref startedSpanCount); return((s, n) => Interlocked.Decrement(ref startedSpanCount)); }) ; break; case "Five!!": for (int i = 0; i < 5; i++) { builder .OnSpanStarted((span, name) => Interlocked.Increment(ref startedSpanCount)) .OnSpanFinished((span, name) => Interlocked.Decrement(ref startedSpanCount)) ; } break; default: throw new ArgumentOutOfRangeException(nameof(flavor), flavor, "Unknown"); } return(builder.Build()); }
public async Task StartedWithCallbackDecorator() { var builder = new TracerDecoratorBuilder(_tracer) .OnSpanStartedWithCallback( (span, operationName) => { WriteLine($"Span started: {operationName}"); return((sp, op) => { WriteLine($"Span finished: {operationName}"); }); }) ; var decoratedTracer = builder.Build(); using (var scope = decoratedTracer.BuildSpan("main").StartActive(false)) { var span = decoratedTracer.BuildSpan("not_active").Start(); try { WriteLine("--> Doing something 1"); await Task.Delay(10); } finally { span.Finish(); } using (decoratedTracer.BuildSpan("active_child").StartActive()) { await Task.Delay(10); WriteLine("--> Doing something 2"); } scope.Span.Finish(); } }
public async Task WriteSomeSpanStory() { var builder = new TracerDecoratorBuilder(_tracer) .OnSpanStarted((span, operationName) => WriteLine($"Started: {operationName}")) .OnSpanActivated((span, operationName) => WriteLine($"Activated: {operationName}")) .OnSpanFinished((span, operationName) => WriteLine($"Finished: {operationName}")) .OnSpanLog((span, operationName, timestamp, fields) => { WriteLine($"Log: {operationName} : {string.Join(", ", fields.Select(f => $"{f.key}/{f.value}"))}"); }) .OnSpanSetTag((span, operationName, tag) => { WriteLine($"Tag: {operationName} : {tag.key}/{tag.value}"); }); ; var decoratedTracer = builder.Build(); using (var scope = decoratedTracer .BuildSpan("main") .WithTag("tag1", 1) .StartActive(false) ) { scope.Span.SetTag("tag2", 2); var span = decoratedTracer.BuildSpan("not_active").Start(); try { WriteLine("--> Doing something 1"); span.SetTag("tag3", true); await Task.Delay(10); } finally { span.Finish(); } using (decoratedTracer.BuildSpan("active_child").StartActive()) { decoratedTracer.ActiveSpan.Log(new Dictionary <string, object> { { "log1", 42 }, { "log2", "test" } }); await Task.Delay(10); WriteLine("--> Doing something 2"); } scope.Span.Finish(); } var lines = new[] { "Started: main", "Tag: main : tag1/1", "Activated: main", "Tag: main : tag2/2", "Started: not_active", @"--> Doing something 1", "Tag: not_active : tag3/True", "Finished: not_active", "Started: active_child", "Activated: active_child", "Log: active_child : log1/42, log2/test", @"--> Doing something 2", "Finished: active_child", "Finished: main", }; _outputs.Count.ShouldBe(lines.Length); for (int i = 0; i < lines.Length; i++) { _outputs[i].ShouldBe(lines[i]); } }