public void StartSpanFrom_Recorded_ParentSpan() { var tracer = (Tracer)tracerFactory.GetTracer("foo", "semver:1.0.0"); var traceState = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("k1", "v1") }; var grandParentContext = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded, traceState); var parentSpan = (Span)tracer.StartSpan(SpanName, grandParentContext); var startTimestamp = PreciseTimestamp.GetUtcNow(); var span = (Span)tracer.StartSpan(SpanName, parentSpan); Assert.True(span.Context.IsValid); Assert.Equal(parentSpan.Context.TraceId, span.Context.TraceId); Assert.Equal(span.Activity.SpanId, span.Context.SpanId); Assert.Equal(parentSpan.Context.SpanId, span.ParentSpanId); Assert.Equal(parentSpan.Context.TraceOptions, span.Context.TraceOptions); Assert.Same(traceState, span.Context.Tracestate); Assert.True(span.IsRecordingEvents); Assert.Equal(SpanKind.Internal, span.Kind); AssertApproxSameTimestamp(startTimestamp, span.StartTimestamp); Assert.Empty(span.Links); }
/// <summary> /// Initializes a new instance of the <see cref="SamplingPercentageEstimatorTelemetryProcessor"/> class. /// <param name="settings">Dynamic sampling estimator settings.</param> /// <param name="callback">Callback to invoke every time sampling percentage is evaluated.</param> /// <param name="next">Next TelemetryProcessor in call chain.</param> /// </summary> public SamplingPercentageEstimatorTelemetryProcessor( Channel.Implementation.SamplingPercentageEstimatorSettings settings, Channel.Implementation.AdaptiveSamplingPercentageEvaluatedCallback callback, ITelemetryProcessor next) { this.evaluationCallback = callback; this.settings = settings ?? throw new ArgumentNullException(nameof(settings)); this.next = next ?? throw new ArgumentNullException(nameof(next)); this.CurrentSamplingRate = settings.EffectiveInitialSamplingRate; this.CurrentProactiveSamplingRate = settings.EffectiveInitialSamplingRate; this.itemCount = new ExponentialMovingAverageCounter(settings.EffectiveMovingAverageRatio); this.proactivelySampledInCount = new ExponentialMovingAverageCounter(settings.EffectiveMovingAverageRatio); this.samplingPercentageLastChangeDateTime = PreciseTimestamp.GetUtcNow(); // set evaluation interval to default value if it is negative or zero this.evaluationInterval = this.settings.EffectiveEvaluationInterval; // set up timer to run math to estimate sampling percentage this.evaluationTimer = new Timer( this.EstimateSamplingPercentage, null, this.evaluationInterval, this.evaluationInterval); }
/// <inheritdoc/> public void AddEvent(string name, IDictionary <string, object> eventAttributes) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (eventAttributes == null) { throw new ArgumentNullException(nameof(eventAttributes)); } if (!this.IsRecordingEvents) { return; } lock (this.@lock) { if (this.HasEnded) { // logger.log(Level.FINE, "Calling AddEvent() on an ended Span."); return; } this.InitializedEvents.AddEvent(TimedEvent <IEvent> .Create(PreciseTimestamp.GetUtcNow(), Event.Create(name, eventAttributes))); } }
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 ProcessorDoesNotBlockOnExporter() { spanExporter = new TestExporter(_ => Thread.Sleep(500)); spanProcessor = new BatchingSpanProcessor(spanExporter); var sampledActivity = new Activity("foo"); sampledActivity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; sampledActivity.SetIdFormat(ActivityIdFormat.W3C); sampledActivity.Start(); var span = new Span( sampledActivity, Tracestate.Empty, SpanKind.Internal, TraceConfig.Default, spanProcessor, PreciseTimestamp.GetUtcNow(), default); // does not block var sw = Stopwatch.StartNew(); span.End(); sw.Stop(); Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); var exported = WaitForSpans(spanExporter, 1, TimeSpan.FromMilliseconds(600)); Assert.Single(exported); }
/// <inheritdoc/> public void AddEvent(string name, IDictionary <string, object> eventAttributes) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (eventAttributes == null) { throw new ArgumentNullException(nameof(eventAttributes)); } if (!this.IsRecordingEvents) { return; } lock (this.@lock) { if (this.HasEnded) { // logger.log(Level.FINE, "Calling AddEvent() on an ended Span."); return; } if (this.events == null) { this.events = new EvictingQueue <Event>(this.tracerConfiguration.MaxNumberOfEvents); } this.events.AddEvent(new Event(name, PreciseTimestamp.GetUtcNow(), eventAttributes)); } }
/// <inheritdoc/> public void AddEvent(string name) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (!this.IsRecordingEvents) { return; } lock (this.@lock) { if (this.HasEnded) { // logger.log(Level.FINE, "Calling AddEvent() on an ended Span."); return; } if (this.events == null) { this.events = new EvictingQueue <IEvent>(this.traceConfig.MaxNumberOfEvents); } this.events.AddEvent(Event.Create(name, PreciseTimestamp.GetUtcNow())); } }
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 FromDescriptionDefaultTimestampAndAttributes() { var approxTimestamp = PreciseTimestamp.GetUtcNow(); var attributes = new Dictionary <string, object>(); attributes.Add( "MyStringAttributeKey", "MyStringAttributeValue"); var @event = Event.Create("MyEventText", default, attributes);
public void FromDescriptionAndDefaultTimestamp() { var approxTimestamp = PreciseTimestamp.GetUtcNow(); var @event = Event.Create("MyEventText", default); Assert.Equal("MyEventText", @event.Name); Assert.Equal(0, @event.Attributes.Count); Assert.InRange(Math.Abs((approxTimestamp - @event.Timestamp).TotalMilliseconds), double.Epsilon, 20); }
public void StartSpanFrom_Recorded_ParentSpan_Kind_Links() { var tracer = tracerFactory.GetTracer(null); var parentSpan = tracer.StartRootSpan(SpanName); var linkContext = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); var startTimestamp = PreciseTimestamp.GetUtcNow(); var span = (Span)tracer.StartSpan(SpanName, parentSpan, SpanKind.Server, default, new [] { new Link(linkContext) });
public void StartSpanWithImplicitTimestamp() { var timestamp = PreciseTimestamp.GetUtcNow(); var span = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty) .SetSpanKind(SpanKind.Internal) .SetSampler(Samplers.AlwaysSample) .StartSpan(); Assert.InRange(Math.Abs((timestamp - span.StartTimestamp).TotalMilliseconds), 0, 20); }
// [Fact] // public void SettingStateToDisabledWillClearStats_Interval() // { // View intervalView = // View.Create( // VIEW_NAME_2, // VIEW_DESCRIPTION, // MeasureDouble, // Mean, // Arrays.asList(Key), // Interval.Create(Duration.Create(60, 0))); // settingStateToDisabledWillClearStats(intervalView); // } private void SettingStateToDisabledWillClearStats(IView view) { // TODO: deal with timestamp validation var timestamp1 = PreciseTimestamp.GetUtcNow().AddSeconds(-10); //clock.Time = timestamp1; viewManager.RegisterView(view); statsRecorder .NewMeasureMap() .Put(MeasureDouble, 1.1) .Record(tagger.EmptyBuilder.Put(Key, Value).Build()); TagValues tv = TagValues.Create(new List <string>() { Value }); StatsTestUtil.AssertAggregationMapEquals( viewManager.GetView(view.Name).AggregationMap, new Dictionary <TagValues, IAggregationData>() { { tv, StatsTestUtil.CreateAggregationData(view.Aggregation, view.Measure, 1.1) }, }, Epsilon); var timestamp2 = timestamp1.AddSeconds(2); //clock.Time = timestamp2; Stats.State = StatsCollectionState.DISABLED; // This will clear stats. Assert.Equal(StatsTestUtil.CreateEmptyViewData(view), viewManager.GetView(view.Name)); var timestamp3 = timestamp1.AddSeconds(3); //clock.Time = timestamp3; Stats.State = StatsCollectionState.ENABLED; var timestamp4 = timestamp1.AddSeconds(4); //clock.Time = timestamp4; // This ViewData does not have any stats, but it should not be an empty ViewData, since it has // non-zero TimeStamps. IViewData viewData = viewManager.GetView(view.Name); Assert.Empty(viewData.AggregationMap); //Assert.Equal(timestamp3, viewData.Start); //Assert.Equal(timestamp4, viewData.End); // if (windowData instanceof CumulativeData) { // Assert.Equal(windowData).isEqualTo(CumulativeData.Create(timestamp3, timestamp4)); // } else { // Assert.Equal(windowData).isEqualTo(IntervalData.Create(timestamp4)); // } }
public void StartSpanFrom_Recorded_ParentSpan_Kind() { var tracer = tracerFactory.GetTracer(null); var parentSpan = tracer.StartRootSpan(SpanName); var startTimestamp = PreciseTimestamp.GetUtcNow(); var span = (Span)tracer.StartSpan(SpanName, parentSpan, SpanKind.Client); Assert.True(span.IsRecordingEvents); Assert.Equal(SpanKind.Client, span.Kind); AssertApproxSameTimestamp(startTimestamp, span.StartTimestamp); Assert.Empty(span.Links); }
/// <inheritdoc/> public ISpan StartRootSpan(string operationName, SpanKind kind, DateTimeOffset startTimestamp, IEnumerable <Link> links) { if (operationName == null) { throw new ArgumentNullException(nameof(operationName)); } if (startTimestamp == default) { startTimestamp = PreciseTimestamp.GetUtcNow(); } return(Span.CreateRoot(operationName, kind, startTimestamp, links, this.tracerConfiguration, this.spanProcessor, this.LibraryResource)); }
private Span CreateSampledEndedSpan(string spanName, SpanProcessor spanProcessor) { var sampledActivity = new Activity(spanName); sampledActivity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; sampledActivity.SetIdFormat(ActivityIdFormat.W3C); sampledActivity.Start(); var span = new Span( sampledActivity, Enumerable.Empty <KeyValuePair <string, string> >(), SpanKind.Internal, new TracerConfiguration(), spanProcessor, PreciseTimestamp.GetUtcNow(),
public void NoEventsRecordedAfterEnd() { var activityLink = new Activity(SpanName) .SetIdFormat(ActivityIdFormat.W3C) .Start(); activityLink.Stop(); var activity = new Activity(SpanName).Start(); activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; var spanStartTime = PreciseTimestamp.GetUtcNow(); var span = Span.StartSpan( activity, Tracestate.Empty, SpanKind.Internal, TraceParams.Default, startEndHandler); var spaEndTime = PreciseTimestamp.GetUtcNow(); span.End(); // Check that adding trace events after Span#End() does not throw any exception and are not // recorded. foreach (var attribute in attributes) { span.SetAttribute(attribute); } span.SetAttribute( "MySingleStringAttributeKey", "MySingleStringAttributeValue"); span.AddEvent(Event.Create(EventDescription)); span.AddEvent(EventDescription, attributes); span.AddLink(Link.FromActivity(activityLink)); var spanData = ((Span)span).ToSpanData(); AssertApproxSameTimestamp(spanData.StartTimestamp, spanStartTime); Assert.Empty(spanData.Attributes.AttributeMap); Assert.Empty(spanData.Events.Events); Assert.Empty(spanData.Links.Links); Assert.Equal(Status.Ok, spanData.Status); AssertApproxSameTimestamp(spaEndTime, spanData.EndTimestamp); }
public void StartSpanFrom_Recorded_ParentSpan_Kind_Links_Enumerable() { var tracer = tracerFactory.GetTracer(null); var parentSpan = tracer.StartRootSpan(SpanName); var linkContext = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); var startTimestamp = PreciseTimestamp.GetUtcNow(); var span = (Span)tracer.StartSpan(SpanName, parentSpan, SpanKind.Server, new SpanCreationOptions { Links = new[] { new Link(linkContext) } }); Assert.True(span.IsRecording); Assert.Equal(SpanKind.Server, span.Kind); AssertApproxSameTimestamp(startTimestamp, span.StartTimestamp); Assert.Single(span.Links); Assert.Same(linkContext, span.Links.Single().Context); }
private Span CreateNotSampledEndedSpan(string spanName) { var notSampledActivity = new Activity(spanName); notSampledActivity.SetIdFormat(ActivityIdFormat.W3C); notSampledActivity.Start(); var span = new Span( notSampledActivity, Tracestate.Empty, SpanKind.Internal, TraceConfig.Default, spanProcessor, PreciseTimestamp.GetUtcNow(), false); span.End(); return(span); }
private Span CreateSampledEndedSpan(string spanName) { var sampledActivity = new Activity(spanName); sampledActivity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; sampledActivity.SetIdFormat(ActivityIdFormat.W3C); sampledActivity.Start(); var span = new Span( sampledActivity, Tracestate.Empty, SpanKind.Internal, TraceConfig.Default, spanProcessor, PreciseTimestamp.GetUtcNow(), default); span.End(); return(span); }
public void StartSpanFrom_NotRecorded_ParentSpan() { var tracer = tracerFactory.GetTracer(null); var grandParentContext = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None); var parentSpan = (Span)tracer.StartSpan(SpanName, grandParentContext); var startTimestamp = PreciseTimestamp.GetUtcNow(); var span = (Span)tracer.StartSpan(SpanName, parentSpan); Assert.True(span.Context.IsValid); Assert.Equal(parentSpan.Context.TraceId, span.Context.TraceId); Assert.Equal(span.Activity.SpanId, span.Context.SpanId); Assert.Equal(parentSpan.Context.SpanId, span.ParentSpanId); Assert.Equal(parentSpan.Context.TraceOptions, span.Context.TraceOptions); Assert.Empty(span.Context.Tracestate); Assert.False(span.IsRecordingEvents); Assert.Equal(SpanKind.Internal, span.Kind); AssertApproxSameTimestamp(startTimestamp, span.StartTimestamp); Assert.Empty(span.Links); }
public void StartSpanNullParent() { var span = new SpanBuilder(SpanName, spanBuilderOptions) .SetSpanKind(SpanKind.Internal) .SetNoParent() .StartSpan(); Assert.True(span.Context.IsValid); Assert.True(span.IsRecordingEvents); Assert.True((span.Context.TraceOptions & ActivityTraceFlags.Recorded) != 0); var spanData = ((Span)span).ToSpanData(); Assert.True(spanData.ParentSpanId == default); Assert.InRange(spanData.StartTimestamp, PreciseTimestamp.GetUtcNow().AddSeconds(-1), PreciseTimestamp.GetUtcNow().AddSeconds(1)); Assert.Equal(SpanName, spanData.Name); var activity = ((Span)span).Activity; Assert.Null(Activity.Current); Assert.Equal(activity.TraceId, span.Context.TraceId); Assert.Equal(activity.SpanId, span.Context.SpanId); }
public void ThrowsInExporter() { spanExporter = new TestExporter(_ => throw new ArgumentException("123")); spanProcessor = new SimpleSpanProcessor(spanExporter); var sampledActivity = new Activity("foo"); sampledActivity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; sampledActivity.SetIdFormat(ActivityIdFormat.W3C); sampledActivity.Start(); var span = new Span( sampledActivity, Tracestate.Empty, SpanKind.Internal, TraceConfig.Default, spanProcessor, PreciseTimestamp.GetUtcNow(), default); // does not throw span.End(); }
/// <inheritdoc/> public void AddEvent(string name) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (!this.IsRecordingEvents || this.hasEnded) { return; } lock (this.@lock) { if (this.events == null) { this.events = new EvictingQueue <Event>(this.tracerConfiguration.MaxNumberOfEvents); } this.events.AddEvent(new Event(name, PreciseTimestamp.GetUtcNow())); } }
/// <inheritdoc/> public void AddEvent(IEvent addEvent) { if (addEvent == null) { throw new ArgumentNullException(nameof(addEvent)); } if (!this.IsRecordingEvents) { return; } lock (this.@lock) { if (this.HasEnded) { // logger.log(Level.FINE, "Calling AddEvent() on an ended Span."); return; } this.InitializedEvents.AddEvent(TimedEvent <IEvent> .Create(PreciseTimestamp.GetUtcNow(), addEvent)); } }
/// <summary> /// Initializes a new instance of the <see cref="Event"/> class. /// </summary> /// <param name="name">Event name.</param> public Event(string name) : this(name, PreciseTimestamp.GetUtcNow(), EmptyAttributes) { }
/// <summary> /// Initializes a new instance of the <see cref="Event"/> class. /// </summary> /// <param name="name">Event name.</param> /// <param name="timestamp">Event timestamp. Timestamp MUST only be used for the events that happened in the past, not at the moment of this call.</param> /// <param name="attributes">Event attributes.</param> public Event(string name, DateTimeOffset timestamp, IDictionary <string, object> attributes) { this.Name = name ?? throw new ArgumentNullException(nameof(name)); this.Attributes = attributes ?? throw new ArgumentNullException(nameof(attributes)); this.Timestamp = timestamp != default ? timestamp : PreciseTimestamp.GetUtcNow(); }
/// <inheritdoc/> public void End() { this.End(PreciseTimestamp.GetUtcNow()); }
/// <summary> /// Initializes a new instance of the <see cref="Event"/> class. /// </summary> /// <param name="name">Event name.</param> /// <param name="timestamp">Event timestamp. Timestamp MUST only be used for the events that happened in the past, not at the moment of this call.</param> /// <param name="attributes">Event attributes.</param> public Event(string name, DateTimeOffset timestamp, IDictionary <string, object> attributes) { this.Name = name ?? string.Empty; this.Attributes = attributes ?? EmptyAttributes; this.Timestamp = timestamp != default ? timestamp : PreciseTimestamp.GetUtcNow(); }
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); } }