Beispiel #1
0
        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]);
            }
        }