private static SpanData CreateSpanData(string name, SpanContext parentContext, SpanKind kind, DateTimeOffset startTimestamp, IEnumerable <Link> links, IDictionary <string, object> attributes, IEnumerable <Event> events, Status status, DateTimeOffset endTimestamp) { var processor = new Mock <SpanProcessor>(); processor.Setup(p => p.OnEnd(It.IsAny <SpanData>())); var tracer = TracerFactory.Create(b => b.AddProcessorPipeline(p => p.AddProcessor(_ => processor.Object))) .GetTracer(null); SpanCreationOptions spanOptions = null; if (links != null || attributes != null || startTimestamp != default) { spanOptions = new SpanCreationOptions { Links = links, Attributes = attributes, StartTimestamp = startTimestamp, }; } var span = tracer.StartSpan(name, parentContext, kind, spanOptions); if (events != null) { foreach (var evnt in events) { span.AddEvent(evnt); } } span.Status = status.IsValid ? status : Status.Ok; if (endTimestamp == default) { span.End(); } else { span.End(endTimestamp); } return((SpanData)processor.Invocations[0].Arguments[0]); }
/// <inheritdoc/> public abstract ISpanBuilder SpanBuilderWithParentContext(string spanName, SpanKind spanKind = SpanKind.Internal, SpanContext remoteParentSpanContext = null);
/// <summary> /// Initializes a new instance of the <see cref="Link"/> class. /// </summary> /// <param name="spanContext">Span context of a linked span.</param> public Link(SpanContext spanContext) : this(spanContext, EmptyAttributes) { }
private Span( string name, SpanContext parentSpanContext, ActivityAndTracestate activityAndTracestate, bool createdFromActivity, SpanKind spanKind, SpanCreationOptions spanCreationOptions, Sampler sampler, 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.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); } }
/// <inheritdoc/> public override ISpanBuilder SpanBuilderWithParentContext(string name, SpanKind kind = SpanKind.Internal, SpanContext parentContext = null) { return(Trace.SpanBuilder.Create(name, kind, parentContext, this.spanBuilderOptions)); }
private Activity CreateActivityForSpan(ContextSource contextSource, ISpan explicitParent, SpanContext remoteParent, Activity explicitParentActivity, Activity fromActivity) { Activity spanActivity = null; Activity originalActivity = Activity.Current; bool needRestoreOriginal = true; switch (contextSource) { case ContextSource.CurrentActivityParent: { // Activity will figure out its parent spanActivity = new Activity(this.name) .SetIdFormat(ActivityIdFormat.W3C) .Start(); // chances are, Activity.Current has span attached if (CurrentSpanUtils.CurrentSpan is Span currentSpan) { this.parentSpanContext = currentSpan.Context; } else { this.parentSpanContext = ParentContextFromActivity(spanActivity); } break; } case ContextSource.ExplicitActivityParent: { spanActivity = new Activity(this.name) .SetParentId(this.parentActivity.TraceId, this.parentActivity.SpanId, this.parentActivity.ActivityTraceFlags) .Start(); spanActivity.TraceStateString = this.parentActivity.TraceStateString; this.parentSpanContext = ParentContextFromActivity(spanActivity); break; } case ContextSource.NoParent: { spanActivity = new Activity(this.name) .SetIdFormat(ActivityIdFormat.W3C) .SetParentId(" ") .Start(); this.parentSpanContext = null; break; } case ContextSource.Activity: { this.parentSpanContext = ParentContextFromActivity(this.fromActivity); spanActivity = this.fromActivity; needRestoreOriginal = false; break; } case ContextSource.ExplicitRemoteParent: { spanActivity = new Activity(this.name); if (this.parentSpanContext != null && this.parentSpanContext.IsValid) { spanActivity.SetParentId(this.parentSpanContext.TraceId, this.parentSpanContext.SpanId, this.parentSpanContext.TraceOptions); spanActivity.TraceStateString = TracestateUtils.GetString(this.parentSpanContext.Tracestate); } spanActivity.SetIdFormat(ActivityIdFormat.W3C); spanActivity.Start(); break; } case ContextSource.ExplicitSpanParent: { spanActivity = new Activity(this.name); if (this.parentSpan.Context.IsValid) { spanActivity.SetParentId(this.parentSpan.Context.TraceId, this.parentSpan.Context.SpanId, this.parentSpan.Context.TraceOptions); spanActivity.TraceStateString = TracestateUtils.GetString(this.parentSpan.Context.Tracestate); } spanActivity.SetIdFormat(ActivityIdFormat.W3C); spanActivity.Start(); this.parentSpanContext = this.parentSpan.Context; break; } default: throw new ArgumentException($"Unknown parentType {contextSource}"); } if (needRestoreOriginal) { // Activity Start always puts Activity on top of Current stack // in OpenTelemetry we ask users to enable implicit propagation by calling WithSpan // it will set Current Activity and attach span to it. // we need to work with .NET team to allow starting Activities without updating Current // As a workaround here we are undoing updating Current Activity.Current = originalActivity; } return(spanActivity); }
/// <inheritdoc/> public ISpanBuilder AddLink(SpanContext spanContext, IDictionary <string, object> attributes) { // let link validate arguments return(this.AddLink(new Link(spanContext, attributes))); }
/// <inheritdoc/> public ISpanBuilder AddLink(SpanContext spanContext) { // let link validate arguments return(this.AddLink(new Link(spanContext))); }
/// <summary> /// Starts active span. /// </summary> /// <param name="tracer">Tracer instance.</param> /// <param name="operationName">Span name.</param> /// <param name="parent">Parent for new span.</param> /// <param name="span">Created span.</param> /// <returns>Scope.</returns> public static IDisposable StartActiveSpan(this Tracer tracer, string operationName, SpanContext parent, out TelemetrySpan span) { span = tracer.StartSpan(operationName, parent, SpanKind.Internal, null); return(tracer.WithSpan(span, true)); }
/// <summary> /// Starts active span. /// </summary> /// <param name="tracer">Tracer instance.</param> /// <param name="operationName">Span name.</param> /// <param name="parent">Parent for new span.</param> /// <param name="kind">Kind.</param> /// <param name="options">Advanced span creation options.</param> /// <param name="span">Created span.</param> /// <returns>Scope.</returns> public static IDisposable StartActiveSpan(this Tracer tracer, string operationName, SpanContext parent, SpanKind kind, SpanCreationOptions options, out TelemetrySpan span) { span = tracer.StartSpan(operationName, parent, kind, options); return(tracer.WithSpan(span, true)); }
public static ILink FromSpanContext(SpanContext context) { return(new Link(context, EmptyAttributes)); }
private Link(SpanContext context, IDictionary <string, object> attributes) { this.Context = context ?? throw new ArgumentNullException(nameof(context)); this.Attributes = attributes ?? throw new ArgumentNullException(nameof(attributes)); }
/// <summary> /// Starts active span. /// </summary> /// <param name="tracer">Tracer instance.</param> /// <param name="operationName">Span name.</param> /// <param name="parent">Parent for new span.</param> /// <param name="kind">Kind.</param> /// <param name="span">Created span.</param> /// <returns>Scope.</returns> public static IDisposable StartActiveSpan(this ITracer tracer, string operationName, SpanContext parent, SpanKind kind, out ISpan span) { span = tracer.StartSpan(operationName, parent, kind, null); return(tracer.WithSpan(span, true)); }
private ISpan StartSpanInternal( ISpanContext parent, bool hasRemoteParent, string name, ISampler sampler, IEnumerable <ISpan> parentLinks, bool recordEvents, Timer timestampConverter) { ITraceParams activeTraceParams = this.Options.TraceConfig.ActiveTraceParams; IRandomGenerator random = this.Options.RandomHandler; ITraceId traceId; ISpanId spanId = SpanId.GenerateRandomId(random); ISpanId parentSpanId = null; TraceOptionsBuilder traceOptionsBuilder; if (parent == null || !parent.IsValid) { // New root span. traceId = TraceId.GenerateRandomId(random); traceOptionsBuilder = TraceOptions.Builder(); // This is a root span so no remote or local parent. // hasRemoteParent = null; hasRemoteParent = false; } else { // New child span. traceId = parent.TraceId; parentSpanId = parent.SpanId; traceOptionsBuilder = TraceOptions.Builder(parent.TraceOptions); } traceOptionsBuilder.SetIsSampled( MakeSamplingDecision( parent, hasRemoteParent, name, sampler, parentLinks, traceId, spanId, activeTraceParams)); TraceOptions traceOptions = traceOptionsBuilder.Build(); SpanOptions spanOptions = SpanOptions.None; if (traceOptions.IsSampled || recordEvents) { spanOptions = SpanOptions.RecordEvents; } ISpan span = Span.StartSpan( SpanContext.Create(traceId, spanId, traceOptions, parent?.Tracestate ?? Tracestate.Empty), spanOptions, name, parentSpanId, hasRemoteParent, activeTraceParams, this.Options.StartEndHandler, timestampConverter); LinkSpans(span, parentLinks); span.Kind = this.Kind; return(span); }
/// <inheritdoc/> public override ISpanBuilder SpanBuilderWithParentContext(string name, SpanKind kind = SpanKind.Internal, SpanContext parentContext = null) { return(NoopSpanBuilder.SetParent(name, kind, parentContext)); }