public async Task DroppingEvents() { var maxNumberOfEvents = 8; var traceConfig = new TracerConfiguration(32, maxNumberOfEvents, 32); var tracer = TracerFactory.Create(b => b .AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor)) .SetTracerOptions(traceConfig) .SetSampler(new AlwaysSampleSampler())) .GetTracer(null); var span = (Span)tracer.StartRootSpan(SpanName); var eventTimestamps = new DateTimeOffset[2 * maxNumberOfEvents]; for (int i = 0; i < 2 * maxNumberOfEvents; i++) { eventTimestamps[i] = PreciseTimestamp.GetUtcNow(); span.AddEvent(new Event("foo", eventTimestamps[i])); await Task.Delay(10); } Assert.Equal(maxNumberOfEvents, span.Events.Count()); var events = span.Events.ToArray(); for (int i = 0; i < maxNumberOfEvents; i++) { Assert.Equal(eventTimestamps[i + maxNumberOfEvents], events[i].Timestamp); } span.End(); Assert.Equal(maxNumberOfEvents, span.Events.Count()); }
public void GetActiveConfig() { var config = new TracerConfiguration(Samplers.NeverSample); var tracer = new Tracer(spanProcessor, config, Resource.Empty); Assert.Equal(config, tracer.ActiveTracerConfiguration); }
public void SetActiveConfig() { var config = new TracerConfiguration(Samplers.NeverSample); tracer.ActiveTracerConfiguration = config; Assert.Equal(config, tracer.ActiveTracerConfiguration); }
internal Span( Activity activity, IEnumerable <KeyValuePair <string, string> > tracestate, SpanKind spanKind, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, DateTimeOffset startTimestamp, bool ownsActivity, Resource libraryResource) { this.Activity = activity; this.spanContext = new Lazy <SpanContext>(() => new SpanContext( this.Activity.TraceId, this.Activity.SpanId, this.Activity.ActivityTraceFlags, tracestate)); this.Name = this.Activity.OperationName; this.tracerConfiguration = tracerConfiguration; this.spanProcessor = spanProcessor; this.Kind = spanKind; this.OwnsActivity = ownsActivity; this.IsRecordingEvents = this.Activity.Recorded; this.startTimestamp = startTimestamp; this.LibraryResource = libraryResource; if (this.IsRecordingEvents) { this.spanProcessor.OnStart(this); } }
internal SpanBuilder(string name, SpanProcessor spanProcessor, TracerConfiguration tracerConfiguration, Resource libraryResource) { this.name = name ?? throw new ArgumentNullException(nameof(name)); this.spanProcessor = spanProcessor ?? throw new ArgumentNullException(nameof(spanProcessor)); this.tracerConfiguration = tracerConfiguration ?? throw new ArgumentNullException(nameof(tracerConfiguration)); this.libraryResource = libraryResource ?? throw new ArgumentNullException(nameof(libraryResource)); }
private static bool MakeSamplingDecision( SpanContext parent, string name, ISampler sampler, IEnumerable <Link> parentLinks, ActivityTraceId traceId, ActivitySpanId spanId, TracerConfiguration tracerConfiguration) { // If users set a specific sampler in the SpanBuilder, use it. if (sampler != null) { return(sampler.ShouldSample(parent, traceId, spanId, name, parentLinks).IsSampled); } // Use the default sampler if this is a root Span or this is an entry point Span (has remote // parent). if (parent == null || !parent.IsValid) { return(tracerConfiguration .Sampler .ShouldSample(parent, traceId, spanId, name, parentLinks).IsSampled); } // Parent is always different than null because otherwise we use the default sampler. return((parent.TraceOptions & ActivityTraceFlags.Recorded) != 0 || IsAnyParentLinkSampled(parentLinks)); }
/// <summary> /// Initializes a new instance of the <see cref="TracerSdk"/> class. /// </summary> /// <param name="spanProcessor">Span processor.</param> /// <param name="sampler">Sampler to use.</param> /// <param name="tracerConfiguration">Trace configuration.</param> /// <param name="libraryResource">Resource describing the instrumentation library.</param> internal TracerSdk(SpanProcessor spanProcessor, Sampler sampler, TracerConfiguration tracerConfiguration, Resource libraryResource) { this.spanProcessor = spanProcessor ?? throw new ArgumentNullException(nameof(spanProcessor)); this.tracerConfiguration = tracerConfiguration ?? throw new ArgumentNullException(nameof(tracerConfiguration)); this.LibraryResource = libraryResource ?? throw new ArgumentNullException(nameof(libraryResource)); this.sampler = sampler ?? throw new ArgumentNullException(nameof(sampler)); }
private Span( string name, SpanContext parentSpanContext, ActivityAndTracestate activityAndTracestate, bool ownsActivity, SpanKind spanKind, SpanCreationOptions spanCreationOptions, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, Resource libraryResource) { this.Name = name; this.LibraryResource = libraryResource; IEnumerable <Link> links = null; if (spanCreationOptions != null) { links = spanCreationOptions.Links ?? spanCreationOptions.LinksFactory?.Invoke(); this.startTimestamp = spanCreationOptions.StartTimestamp; } if (this.startTimestamp == default) { this.startTimestamp = PreciseTimestamp.GetUtcNow(); } this.tracerConfiguration = tracerConfiguration; this.spanProcessor = spanProcessor; this.Kind = spanKind; this.OwnsActivity = ownsActivity; this.Activity = activityAndTracestate.Activity; var tracestate = activityAndTracestate.Tracestate; this.IsRecording = MakeSamplingDecision( parentSpanContext, name, null, links, // we'll enumerate again, but double enumeration over small collection is cheaper than allocation this.Activity.TraceId, this.Activity.SpanId, this.tracerConfiguration); if (this.IsRecording) { this.Activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; this.SetLinks(links); this.spanProcessor.OnStart(this); } else { this.Activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; } // this context is definitely not remote, setting isRemote to false this.Context = new SpanContext(this.Activity.TraceId, this.Activity.SpanId, this.Activity.ActivityTraceFlags, false, tracestate); }
public void UpdateTraceParams_All() { var traceParams = new TracerConfiguration(8, 9, 11); Assert.Equal(8, traceParams.MaxNumberOfAttributes); Assert.Equal(9, traceParams.MaxNumberOfEvents); Assert.Equal(11, traceParams.MaxNumberOfLinks); }
public TracerTest() { spanProcessor = new SimpleSpanProcessor(new TestExporter(null)); tracerConfiguration = new TracerConfiguration(); tracerFactory = TracerFactory.Create(b => b .AddProcessorPipeline(p => p.AddProcessor(_ => spanProcessor))); this.tracerSdk = (TracerSdk)tracerFactory.GetTracer(null); }
/// <summary> /// Creates an instance of <see cref="Tracer"/>. /// </summary> /// <param name="spanProcessor">Span processor.</param> /// <param name="tracerConfiguration">Trace configuration.</param> /// <param name="binaryFormat">Binary format context propagator.</param> /// <param name="textFormat">Text format context propagator.</param> /// <param name="libraryResource">Resource describing the instrumentation library.</param> internal Tracer(SpanProcessor spanProcessor, TracerConfiguration tracerConfiguration, IBinaryFormat binaryFormat, ITextFormat textFormat, Resource libraryResource) { this.spanProcessor = spanProcessor ?? throw new ArgumentNullException(nameof(spanProcessor)); this.tracerConfiguration = tracerConfiguration ?? throw new ArgumentNullException(nameof(tracerConfiguration)); this.BinaryFormat = binaryFormat ?? throw new ArgumentNullException(nameof(binaryFormat)); this.TextFormat = textFormat ?? throw new ArgumentNullException(nameof(textFormat)); this.LibraryResource = libraryResource ?? throw new ArgumentNullException(nameof(libraryResource)); }
public void DefaultTraceConfig() { var options = new TracerConfiguration(); Assert.Equal(32, options.MaxNumberOfAttributes); Assert.Equal(128, options.MaxNumberOfEvents); Assert.Equal(32, options.MaxNumberOfLinks); }
public TracerFactory(SpanProcessor spanProcessor = null, TracerConfiguration tracerConfiguration = null, ITextFormat textFormat = null, IBinaryFormat binaryFormat = null) { this.spanProcessor = spanProcessor ?? Tracing.SpanProcessor; this.tracerConfiguration = tracerConfiguration ?? Tracing.TracerConfiguration; this.textFormat = textFormat ?? new TraceContextFormat(); this.binaryFormat = binaryFormat ?? new BinaryFormat(); this.defaultTracer = new Tracer(this.spanProcessor, this.tracerConfiguration, this.binaryFormat, this.textFormat, Resource.Empty); }
public void DefaultTraceConfig() { var config = new TracerConfiguration(); Assert.Equal(Samplers.AlwaysSample, config.Sampler); Assert.Equal(32, config.MaxNumberOfAttributes); Assert.Equal(128, config.MaxNumberOfEvents); Assert.Equal(32, config.MaxNumberOfLinks); }
public void TracerBuilder_ValidArgs() { var builder = new TracerBuilder(); bool processorFactoryCalled = false; bool collectorFactoryCalled = true; var sampler = new ProbabilitySampler(0.1); var exporter = new TestExporter(_ => { }); var options = new TracerConfiguration(1, 1, 1); var binaryFormat = new BinaryFormat(); var textFormat = new TraceContextFormat(); builder .SetSampler(sampler) .AddProcessorPipeline(p => p .SetExporter(exporter) .SetExportingProcessor(e => { processorFactoryCalled = true; Assert.Same(e, exporter); return(new SimpleSpanProcessor(e)); })) .SetTracerOptions(options) .SetBinaryFormat(binaryFormat) .SetTextFormat(textFormat) .AddCollector(t => { Assert.NotNull(t); return(new TestCollector(t)); }); Assert.Same(sampler, builder.Sampler); Assert.NotNull(builder.ProcessingPipelines); Assert.Single(builder.ProcessingPipelines); Assert.Same(exporter, builder.ProcessingPipelines[0].Exporter); Assert.NotNull(builder.ProcessingPipelines[0].Build()); Assert.True(processorFactoryCalled); Assert.Same(options, builder.TracerConfigurationOptions); Assert.Same(binaryFormat, builder.BinaryFormat); Assert.Same(textFormat, builder.TextFormat); Assert.Single(builder.CollectorFactories); var collectorFactory = builder.CollectorFactories.Single(); Assert.Equal(nameof(TestCollector), collectorFactory.Name); Assert.Equal("semver:" + typeof(TestCollector).Assembly.GetName().Version, collectorFactory.Version); Assert.NotNull(collectorFactory.Factory); collectorFactory.Factory(new Tracer(new SimpleSpanProcessor(exporter), new AlwaysSampleSampler(), options, binaryFormat, textFormat, Resource.Empty)); Assert.True(collectorFactoryCalled); }
public void DefaultTraceConfig() { var options = new TracerConfiguration(); Assert.IsType <AlwaysSampleSampler>(options.Sampler); Assert.Equal(32, options.MaxNumberOfAttributes); Assert.Equal(128, options.MaxNumberOfEvents); Assert.Equal(32, options.MaxNumberOfLinks); }
internal static Span CreateFromParentSpan( string name, ISpan parentSpan, SpanKind spanKind, DateTimeOffset startTimestamp, IEnumerable <Link> links, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, Resource libraryResource) { if (parentSpan.Context.IsValid) { return(new Span( name, parentSpan.Context, FromParentSpan(name, parentSpan), true, spanKind, startTimestamp, links, tracerConfiguration, spanProcessor, libraryResource)); } var currentActivity = Activity.Current; if (currentActivity == null) { return(new Span( name, SpanContext.Blank, CreateRoot(name), true, spanKind, startTimestamp, links, tracerConfiguration, spanProcessor, libraryResource)); } return(new Span( name, new SpanContext( currentActivity.TraceId, currentActivity.SpanId, currentActivity.ActivityTraceFlags), FromCurrentParentActivity(name, currentActivity), true, spanKind, startTimestamp, links, tracerConfiguration, spanProcessor, libraryResource)); }
public TracerTest() { spanProcessor = new SimpleSpanProcessor(new NoopSpanExporter()); tracerConfiguration = new TracerConfiguration(); tracerFactory = TracerFactory.Create(b => b .SetExporter(new NoopSpanExporter()) .SetProcessor(e => new SimpleSpanProcessor(e))); tracer = (Tracer)tracerFactory.GetTracer(null); }
public OpenTelemetryTracing(ITracingOptions options, Action <TracerBuilder> configureTracer = null) { var maxAttributes = options.MaxNumberOfAttributes > 0 ? options.MaxNumberOfAttributes : DefaultMaxAttributes; var maxEvents = options.MaxNumberOfMessageEvents > 0 ? options.MaxNumberOfMessageEvents : DefaultMaxEvents; var maxLinks = options.MaxNumberOfLinks > 0 ? options.MaxNumberOfLinks : DefaultMaxLinks; TracerConfiguration = new TracerConfiguration(maxAttributes, maxEvents, maxLinks); var factory = TracerFactory.Create(ConfigureOptions(options, configureTracer)); Tracer = factory.GetTracer(options.Name); }
private Span( string name, SpanContext parentSpanContext, ActivityAndTracestate activityAndTracestate, bool ownsActivity, SpanKind spanKind, DateTimeOffset startTimestamp, IEnumerable <Link> links, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, Resource libraryResource) { this.Name = name; this.LibraryResource = libraryResource; this.startTimestamp = startTimestamp; this.tracerConfiguration = tracerConfiguration; this.spanProcessor = spanProcessor; this.Kind = spanKind; this.OwnsActivity = ownsActivity; this.Activity = activityAndTracestate.Activity; var tracestate = activityAndTracestate.Tracestate; this.IsRecordingEvents = MakeSamplingDecision( parentSpanContext, name, null, links, // we'll enumerate again, but double enumeration over small collection is cheaper than allocation this.Activity.TraceId, this.Activity.SpanId, this.tracerConfiguration); if (this.IsRecordingEvents) { this.Activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; if (links != null) { foreach (var link in links) { this.AddLink(link); } } this.spanProcessor.OnStart(this); } else { this.Activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; } this.Context = new SpanContext(this.Activity.TraceId, this.Activity.SpanId, this.Activity.ActivityTraceFlags, tracestate); }
public void TracerBuilder_ValidArgs() { var builder = new TracerBuilder(); bool processorFactoryCalled = false; bool instrumentationFactoryCalled = true; var sampler = new ProbabilitySampler(0.1); var exporter = new TestSpanExporter(_ => { }); var options = new TracerConfiguration(1, 1, 1); builder .SetSampler(sampler) .AddProcessorPipeline(p => p .SetExporter(exporter) .SetExportingProcessor(e => { processorFactoryCalled = true; Assert.Same(e, exporter); return(new SimpleSpanProcessor(e)); })) .SetTracerOptions(options) .AddInstrumentation(t => { Assert.NotNull(t); return(new TestInstrumentation(t)); }); Assert.Same(sampler, builder.Sampler); Assert.NotNull(builder.ProcessingPipelines); Assert.Single(builder.ProcessingPipelines); Assert.Same(exporter, builder.ProcessingPipelines[0].Exporter); Assert.NotNull(builder.ProcessingPipelines[0].Build()); Assert.True(processorFactoryCalled); Assert.Same(options, builder.TracerConfigurationOptions); Assert.Single(builder.InstrumentationFactories); var instrumentationFactory = builder.InstrumentationFactories.Single(); Assert.Equal(nameof(TestInstrumentation), instrumentationFactory.Name); Assert.Equal("semver:" + typeof(TestInstrumentation).Assembly.GetName().Version, instrumentationFactory.Version); Assert.NotNull(instrumentationFactory.Factory); instrumentationFactory.Factory(new TracerSdk(new SimpleSpanProcessor(exporter), new AlwaysOnSampler(), options, Resource.Empty)); Assert.True(instrumentationFactoryCalled); }
public void DroppingAndAddingAttributes() { var maxNumberOfAttributes = 8; var traceConfig = new TracerConfiguration(maxNumberOfAttributes, 128, 32); var tracer = TracerFactory.Create(b => b .AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor)) .SetTracerOptions(traceConfig) .SetSampler(new AlwaysSampleSampler())) .GetTracer(null); var span = (Span)tracer.StartRootSpan(SpanName); for (long i = 0; i < 2 * maxNumberOfAttributes; i++) { span.SetAttribute("MyStringAttributeKey" + i, i); } Assert.Equal(maxNumberOfAttributes, span.Attributes.Count()); for (long i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( i + maxNumberOfAttributes, span .Attributes .GetValue("MyStringAttributeKey" + (i + maxNumberOfAttributes))); } for (long i = 0; i < maxNumberOfAttributes / 2; i++) { span.SetAttribute("MyStringAttributeKey" + i, i); } Assert.Equal(maxNumberOfAttributes, span.Attributes.Count()); // Test that we still have in the attributes map the latest maxNumberOfAttributes / 2 entries. for (long i = 0; i < maxNumberOfAttributes / 2; i++) { Assert.Equal( i + maxNumberOfAttributes * 3 / 2, span .Attributes .GetValue("MyStringAttributeKey" + (i + maxNumberOfAttributes * 3 / 2))); } // Test that we have the newest re-added initial entries. for (long i = 0; i < maxNumberOfAttributes / 2; i++) { Assert.Equal(i, span.Attributes.GetValue("MyStringAttributeKey" + i)); } }
internal static Span CreateFromActivity( string name, Activity activity, SpanKind spanKind, IEnumerable <Link> links, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, Resource libraryResource) { return(new Span( name, ParentContextFromActivity(activity), FromActivity(name, activity), false, spanKind, new DateTimeOffset(activity.StartTimeUtc), links, tracerConfiguration, spanProcessor, libraryResource)); }
internal static Span CreateRoot( string name, SpanKind spanKind, DateTimeOffset startTimestamp, IEnumerable <Link> links, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, Resource libraryResource) { return(new Span( name, SpanContext.Blank, CreateRoot(name), true, spanKind, startTimestamp, links, tracerConfiguration, spanProcessor, libraryResource)); }
public void DroppingLinksEnumerable() { var contextLink = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None); var maxNumberOfLinks = 8; var traceConfig = new TracerConfiguration(32, 128, maxNumberOfLinks); var tracer = TracerFactory.Create(b => b .AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor)) .SetTracerOptions(traceConfig) .SetSampler(new AlwaysSampleSampler())) .GetTracer(null); var overflowedLinks = new List <Link>(); var link = new Link(contextLink); for (var i = 0; i < 2 * maxNumberOfLinks; i++) { overflowedLinks.Add(link); } var span = (Span)tracer.StartSpan(SpanName, SpanKind.Client, new SpanCreationOptions { Links = overflowedLinks, }); Assert.Equal(maxNumberOfLinks, span.Links.Count()); foreach (var actualLink in span.Links) { Assert.Equal(link, actualLink); } span.End(); Assert.Equal(maxNumberOfLinks, span.Links.Count()); foreach (var actualLink in span.Links) { Assert.Equal(link, actualLink); } }
public void DroppingAttributes() { var maxNumberOfAttributes = 8; var traceConfig = new TracerConfiguration(maxNumberOfAttributes, 128, 32); var tracer = TracerFactory.Create(b => b .AddProcessorPipeline(p => p.AddProcessor(_ => this.spanProcessor)) .SetTracerOptions(traceConfig) .SetSampler(new AlwaysSampleSampler())) .GetTracer(null); var span = (Span)tracer.StartRootSpan(SpanName); for (var i = 0; i < 2 * maxNumberOfAttributes; i++) { span.SetAttribute("MyStringAttributeKey" + i, i); } Assert.Equal(maxNumberOfAttributes, span.Attributes.Count()); for (long i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( i + maxNumberOfAttributes, span .Attributes .GetValue("MyStringAttributeKey" + (i + maxNumberOfAttributes))); } span.End(); Assert.Equal(maxNumberOfAttributes, span.Attributes.Count()); for (long i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( i + maxNumberOfAttributes, span .Attributes .GetValue("MyStringAttributeKey" + (i + maxNumberOfAttributes))); } }
static Tracing() { TracerConfiguration = new TracerConfiguration(); SpanProcessor = new BatchingSpanProcessor(new NoopSpanExporter()); tracerFactory = new TracerFactory(SpanProcessor, TracerConfiguration); }
private Span( string name, SpanContext parentSpanContext, ActivityAndTracestate activityAndTracestate, bool createdFromActivity, SpanKind spanKind, SpanCreationOptions spanCreationOptions, Sampler sampler, TracerConfiguration tracerConfiguration, SpanProcessor spanProcessor, Resource libraryResource) { if (name != null) { this.Name = name; } else { OpenTelemetrySdkEventSource.Log.InvalidArgument("StartSpan", "span name is null"); this.Name = string.Empty; } this.LibraryResource = libraryResource; IEnumerable <Link> links = null; if (spanCreationOptions != null) { links = spanCreationOptions.Links ?? spanCreationOptions.LinksFactory?.Invoke(); this.startTimestamp = spanCreationOptions.StartTimestamp; } if (this.startTimestamp == default) { this.startTimestamp = PreciseTimestamp.GetUtcNow(); } this.sampler = sampler; this.tracerConfiguration = tracerConfiguration; this.spanProcessor = spanProcessor; this.Kind = spanKind; this.createdFromActivity = createdFromActivity; this.Activity = activityAndTracestate.Activity; var tracestate = activityAndTracestate.Tracestate; this.IsRecording = MakeSamplingDecision( parentSpanContext, name, spanCreationOptions?.Attributes, links, // we'll enumerate again, but double enumeration over small collection is cheaper than allocation this.Activity.TraceId, this.Activity.SpanId, this.sampler); this.Activity.ActivityTraceFlags = this.IsRecording ? this.Activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded : this.Activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; // this context is definitely not remote, setting isRemote to false this.Context = new SpanContext(this.Activity.TraceId, this.Activity.SpanId, this.Activity.ActivityTraceFlags, false, tracestate); if (this.IsRecording) { this.SetLinks(links); if (spanCreationOptions?.Attributes != null) { foreach (var attribute in spanCreationOptions.Attributes) { this.SetAttribute(attribute); } } this.spanProcessor.OnStart(this); } }
/// <summary> /// Creates an instance of <see cref="ITracer"/>. /// </summary> /// <param name="spanProcessor">Span processor.</param> /// <param name="tracerConfiguration">Trace configuration.</param> /// <param name="libraryResource">Resource describing the instrumentation library.</param> public Tracer(SpanProcessor spanProcessor, TracerConfiguration tracerConfiguration, Resource libraryResource) : this(spanProcessor, tracerConfiguration, new BinaryFormat(), new TraceContextFormat(), libraryResource) { }
public TracerTest() { spanProcessor = new SimpleSpanProcessor(new NoopSpanExporter()); tracerConfiguration = new TracerConfiguration(); tracer = new Tracer(spanProcessor, tracerConfiguration, Resource.Empty); }