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]);
        }
Пример #2
0
 /// <inheritdoc/>
 public abstract ISpanBuilder SpanBuilderWithParentContext(string spanName, SpanKind spanKind = SpanKind.Internal, SpanContext remoteParentSpanContext = null);
Пример #3
0
 /// <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)
 {
 }
Пример #4
0
        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);
            }
        }
Пример #5
0
 /// <inheritdoc/>
 public override ISpanBuilder SpanBuilderWithParentContext(string name, SpanKind kind = SpanKind.Internal, SpanContext parentContext = null)
 {
     return(Trace.SpanBuilder.Create(name, kind, parentContext, this.spanBuilderOptions));
 }
Пример #6
0
        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);
        }
Пример #7
0
 /// <inheritdoc/>
 public ISpanBuilder AddLink(SpanContext spanContext, IDictionary <string, object> attributes)
 {
     // let link validate arguments
     return(this.AddLink(new Link(spanContext, attributes)));
 }
Пример #8
0
 /// <inheritdoc/>
 public ISpanBuilder AddLink(SpanContext spanContext)
 {
     // let link validate arguments
     return(this.AddLink(new Link(spanContext)));
 }
Пример #9
0
 /// <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));
 }
Пример #10
0
 /// <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));
 }
Пример #11
0
 public static ILink FromSpanContext(SpanContext context)
 {
     return(new Link(context, EmptyAttributes));
 }
Пример #12
0
 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));
 }
Пример #14
0
        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);
        }
Пример #15
0
 /// <inheritdoc/>
 public override ISpanBuilder SpanBuilderWithParentContext(string name, SpanKind kind = SpanKind.Internal, SpanContext parentContext = null)
 {
     return(NoopSpanBuilder.SetParent(name, kind, parentContext));
 }