Example #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());
        }
Example #3
0
        /// <summary>
        ///     Would be better if we didn't need an input tracer, but there isn't a BasicTracer
        ///     in OpenTracing for C# quite yet, and we need SOMEONE to be supplying us a working
        ///     <see cref="IScopeManager"/> and <see cref="ISpanContext"/>.
        /// </summary>
        public static (ITracer connectedTracer, IObservable <TraceEvent> eventStream) CreateTracerEventStreamPair(
            ITracer tracer)
        {
            ISubject <TraceEvent> subject = new Subject <TraceEvent>();

            var connectedTracer = new TracerDecoratorBuilder(tracer)
                                  .OnSpanActivated((span, operationName) => subject.OnNext(new TraceEvent.ActivatedEvent(span, operationName)))
                                  .OnSpanFinished((span, operationName) => subject.OnNext(new TraceEvent.FinishedEvent(span, operationName)))
                                  .OnSpanSetTag((span, operationName, tagKeyValue) => subject.OnNext(new TraceEvent.SetTagsEvent(span, operationName, tagKeyValue)))
                                  .OnSpanLog((span, operationName, timestamp, logKeyValues) => subject.OnNext(new TraceEvent.LogEvent(span, operationName, timestamp, logKeyValues)))
                                  //.OnSpanStarted((span, operationName) => new TraceEvent.StartedEvent())
                                  .Build();

            return(connectedTracer, eventStream : subject.AsObservable());
        }
        public void Test()
        {
            // jaeger tracer
            var originalTracer = new Tracer.Builder("Test")
                                 // DO SOME CONFIGURATION HERE
                                 .Build();

            var count  = 0;
            var tracer = new TracerDecoratorBuilder(originalTracer)
                         .OnSpanStarted((span, name) => count++)
                         .OnSpanActivated((span, name) => count++)
                         .OnSpanFinished((span, name) => count++)
                         .Build();

            using (tracer.BuildSpan("test").StartActive())
            {
            }

            count.ShouldBe(3);
        }
        public void ShouldCounterSpan()
        {
            var options = OpenTracingAppMetricsDecoratorOptions.Default;

            var tracer = new TracerDecoratorBuilder(new MockTracer())
                         .WithAppMetrics(_metrics, options)
                         .Build();

            using (tracer.BuildSpan("Operation").StartActive())
            {
                var snap    = _metrics.Snapshot.Get();
                var counter = snap.Contexts.Single().Counters.Single();
                counter.Name.Should().Be(options.SpansCounterName);
                counter.Value.Count.Should().Be(1);
                counter.Value.Items.Single().Item.Should().Equals("Operation");
                counter.Value.Items.Single().Count.Should().Equals(1);
                counter.Value.Items.Single().Percent.Should().Equals(100D);
            }

            using (tracer.BuildSpan("ParentSpan").StartActive())
                using (tracer.BuildSpan("Childspan").StartActive())
                {
                    var snap    = _metrics.Snapshot.Get();
                    var counter = snap.Contexts.Single().Counters.Single();
                    counter.Name.Should().Be(options.SpansCounterName);
                    counter.Value.Count.Should().Be(2);
                    counter.Value.Items.First().Item.Should().Equals("ParentSpan");
                    counter.Value.Items.First().Count.Should().Equals(1);
                    counter.Value.Items.First().Percent.Should().Equals(50D);
                    counter.Value.Items.Last().Item.Should().Equals("Childspan");
                    counter.Value.Items.Last().Count.Should().Equals(1);
                    counter.Value.Items.Last().Percent.Should().Equals(50D);
                }

            {
                var snap    = _metrics.Snapshot.Get();
                var counter = snap.Contexts.Single().Counters.Single();
                counter.Name.Should().Be(options.SpansCounterName);
                counter.Value.Count.Should().Be(0);
            }
        }
        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]);
            }
        }
Example #8
0
        private static TracerDecoratorBuilder WithAppMetrics(this TracerDecoratorBuilder builder, IMetrics metrics, OpenTracingAppMetricsDecoratorOptions options, Action <OpenTracingAppMetricsDecoratorOptions> setupOptions)
        {
            options = options ?? throw new ArgumentNullException(nameof(options));
            setupOptions?.Invoke(options);

            if (options.SpansCountersEnabled)
            {
                var spansCounter = new CounterOptions
                {
                    Name = options.SpansCounterName
                };

                builder.OnSpanStarted((span, operationName) =>
                {
                    metrics.Measure.Counter.Increment(spansCounter, operationName);

                    if (options.DistinctOperationsCountersEnabled)
                    {
                        var distinctCounter = new CounterOptions {
                            Name = options.DistinctOperationCountersName + operationName
                        };
                        metrics.Measure.Counter.Increment(distinctCounter);
                    }
                });

                builder.OnSpanFinished((span, operationName) =>
                {
                    metrics.Measure.Counter.Decrement(spansCounter, operationName);

                    if (options.DistinctOperationsCountersEnabled)
                    {
                        var distinctCounter = new CounterOptions {
                            Name = options.DistinctOperationCountersName + operationName
                        };
                        metrics.Measure.Counter.Decrement(distinctCounter);
                    }
                });
            }

            if (options.SpansMetersEnabled)
            {
                var spansMeter = new MeterOptions
                {
                    Name = options.SpansMeterName
                };

                builder.OnSpanStarted((span, operationName) =>
                {
                    metrics.Measure.Meter.Mark(spansMeter, operationName);

                    if (options.DistinctOperationsMetersEnabled)
                    {
                        var distinctMeter = new MeterOptions {
                            Name = options.DistinctOperationMetersName + operationName
                        };
                        metrics.Measure.Meter.Mark(distinctMeter);
                    }
                });
            }

            if (options.SpansTimersEnabled)
            {
                var spansTimer = new TimerOptions
                {
                    Name         = options.SpansTimerName,
                    DurationUnit = TimeUnit.Milliseconds,
                    RateUnit     = TimeUnit.Milliseconds
                };

                builder.OnSpanStartedWithCallback((span, operationName) =>
                {
                    var timerContext = metrics.Measure.Timer.Time(spansTimer, operationName);

                    TimerContext distinctTimerContext = default(TimerContext);
                    if (options.DistinctOperationsTimersEnabled)
                    {
                        var distinctTimer = new TimerOptions
                        {
                            Name         = options.DistinctOperationTimersName + operationName,
                            DurationUnit = TimeUnit.Milliseconds,
                            RateUnit     = TimeUnit.Milliseconds
                        };
                        distinctTimerContext = metrics.Measure.Timer.Time(distinctTimer);
                    }

                    return((sp, op) =>
                    {
                        timerContext.Dispose();
                        distinctTimerContext.Dispose();
                    });
                });
            }

            return(builder);
        }
Example #9
0
 public static TracerDecoratorBuilder WithAppMetrics(this TracerDecoratorBuilder builder, IMetrics metrics, OpenTracingAppMetricsDecoratorOptions options)
 => WithAppMetrics(builder, metrics, options, opts => { });
Example #10
0
 public static TracerDecoratorBuilder WithAppMetrics(this TracerDecoratorBuilder builder, IMetrics metrics, bool allEnabled = true, Action <OpenTracingAppMetricsDecoratorOptions> setupOptions = null)
 => WithAppMetrics(builder, metrics, OpenTracingAppMetricsDecoratorOptions.Default, setupOptions ?? (opts => { }));