Example #1
0
        private Activity?StartActivity(string name, ActivityKind kind, ActivityContext context, string?parentId, IEnumerable <KeyValuePair <string, string?> >?tags, IEnumerable <ActivityLink>?links, DateTimeOffset startTime)
        {
            // _listeners can get assigned to null in Dispose.
            SynchronizedList <ActivityListener>?listeners = _listeners;

            if (listeners == null || listeners.Count == 0)
            {
                return(null);
            }

            Activity?activity = null;

            ActivityDataRequest dateRequest = ActivityDataRequest.None;

            if (parentId != null)
            {
                listeners.EnumWithFunc(listener => {
                    var getRequestedDataUsingParentId = listener.GetRequestedDataUsingParentId;
                    if (getRequestedDataUsingParentId != null)
                    {
                        ActivityCreationOptions <string> aco = new ActivityCreationOptions <string>(this, name, parentId, kind, tags, links);
                        ActivityDataRequest dr = getRequestedDataUsingParentId(ref aco);
                        if (dr > dateRequest)
                        {
                            dateRequest = dr;
                        }

                        // Stop the enumeration if we get the max value RecordingAndSampling.
                        return(dateRequest != ActivityDataRequest.AllDataAndRecorded);
                    }
                    return(true);
                });
            }
            else
            {
                listeners.EnumWithFunc(listener => {
                    var getRequestedDataUsingContext = listener.GetRequestedDataUsingContext;
                    if (getRequestedDataUsingContext != null)
                    {
                        ActivityCreationOptions <ActivityContext> aco = new ActivityCreationOptions <ActivityContext>(this, name, context, kind, tags, links);
                        ActivityDataRequest dr = getRequestedDataUsingContext(ref aco);
                        if (dr > dateRequest)
                        {
                            dateRequest = dr;
                        }

                        // Stop the enumeration if we get the max value RecordingAndSampling.
                        return(dateRequest != ActivityDataRequest.AllDataAndRecorded);
                    }
                    return(true);
                });
            }

            if (dateRequest != ActivityDataRequest.None)
            {
                activity = Activity.CreateAndStart(this, name, kind, parentId, context, tags, links, startTime, dateRequest);
                listeners.EnumWithAction(listener => {
                    var activityStarted = listener.ActivityStarted;
                    if (activityStarted != null)
                    {
                        activityStarted(activity);
                    }
                });
            }

            return(activity);
        }
Example #2
0
        private Activity?StartActivity(string name, ActivityKind kind, ActivityContext context, string?parentId, IEnumerable <KeyValuePair <string, object?> >?tags, IEnumerable <ActivityLink>?links, DateTimeOffset startTime)
        {
            // _listeners can get assigned to null in Dispose.
            SynchronizedList <ActivityListener>?listeners = _listeners;

            if (listeners == null || listeners.Count == 0)
            {
                return(null);
            }

            Activity?activity = null;

            ActivityDataRequest dataRequest = ActivityDataRequest.None;
            bool?useContext = default;
            ActivityCreationOptions <ActivityContext> optionsWithContext = default;

            if (parentId != null)
            {
                var aco = new ActivityCreationOptions <string>(this, name, parentId, kind, tags, links);
                listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions <string> data, ref ActivityDataRequest request, ref bool?canUseContext, ref ActivityCreationOptions <ActivityContext> dataWithContext) => {
                    GetRequestedData <string>?getRequestedDataUsingParentId = listener.GetRequestedDataUsingParentId;
                    if (getRequestedDataUsingParentId != null)
                    {
                        ActivityDataRequest dr = getRequestedDataUsingParentId(ref data);
                        if (dr > request)
                        {
                            request = dr;
                        }

                        // Stop the enumeration if we get the max value RecordingAndSampling.
                        return(request != ActivityDataRequest.AllDataAndRecorded);
                    }
                    else
                    {
                        // In case we have a parent Id and the listener not providing the GetRequestedDataUsingParentId, we'll try to find out if the following conditions are true:
                        //   - The listener is providing the GetRequestedDataUsingContext callback
                        //   - Can convert the parent Id to a Context
                        // Then we can call the listener GetRequestedDataUsingContext callback with the constructed context.
                        GetRequestedData <ActivityContext>?getRequestedDataUsingContext = listener.GetRequestedDataUsingContext;
                        if (getRequestedDataUsingContext != null)
                        {
                            if (!canUseContext.HasValue)
                            {
                                canUseContext = Activity.TryConvertIdToContext(parentId, out ActivityContext ctx);
                                if (canUseContext.Value)
                                {
                                    dataWithContext = new ActivityCreationOptions <ActivityContext>(data.Source, data.Name, ctx, data.Kind, data.Tags, data.Links);
                                }
                            }

                            if (canUseContext.Value)
                            {
                                ActivityDataRequest dr = getRequestedDataUsingContext(ref dataWithContext);
                                if (dr > request)
                                {
                                    request = dr;
                                }
                                // Stop the enumeration if we get the max value RecordingAndSampling.
                                return(request != ActivityDataRequest.AllDataAndRecorded);
                            }
                        }
                    }
                    return(true);
                }, ref aco, ref dataRequest, ref useContext, ref optionsWithContext);
            }
            else
            {
                ActivityContext initializedContext = context == default && Activity.Current != null ? Activity.Current.Context : context;
                optionsWithContext = new ActivityCreationOptions <ActivityContext>(this, name, initializedContext, kind, tags, links);
                listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions <ActivityContext> data, ref ActivityDataRequest request, ref bool?canUseContext, ref ActivityCreationOptions <ActivityContext> dataWithContext) => {
                    GetRequestedData <ActivityContext>?getRequestedDataUsingContext = listener.GetRequestedDataUsingContext;
                    if (getRequestedDataUsingContext != null)
                    {
                        if (listener.AutoGenerateRootContextTraceId && !canUseContext.HasValue && data.Parent == default)
                        {
                            ActivityContext ctx = new ActivityContext(ActivityTraceId.CreateRandom(), default, default);
Example #3
0
        private Activity?CreateActivity(string name, ActivityKind kind, ActivityContext context, string?parentId, IEnumerable <KeyValuePair <string, object?> >?tags,
                                        IEnumerable <ActivityLink>?links, DateTimeOffset startTime, bool startIt = true, ActivityIdFormat idFormat = ActivityIdFormat.Unknown)
        {
            // _listeners can get assigned to null in Dispose.
            SynchronizedList <ActivityListener>?listeners = _listeners;

            if (listeners == null || listeners.Count == 0)
            {
                return(null);
            }

            Activity?activity = null;
            ActivityTagsCollection?samplerTags;
            string?traceState;

            ActivitySamplingResult samplingResult = ActivitySamplingResult.None;

            if (parentId != null)
            {
                ActivityCreationOptions <string>          aco        = default;
                ActivityCreationOptions <ActivityContext> acoContext = default;

                aco = new ActivityCreationOptions <string>(this, name, parentId, kind, tags, links, idFormat);
                if (aco.IdFormat == ActivityIdFormat.W3C)
                {
                    // acoContext is used only in the Sample calls which called only when we have W3C Id format.
                    acoContext = new ActivityCreationOptions <ActivityContext>(this, name, aco.GetContext(), kind, tags, links, ActivityIdFormat.W3C);
                }

                listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions <string> data, ref ActivitySamplingResult result, ref ActivityCreationOptions <ActivityContext> dataWithContext) => {
                    SampleActivity <string>?sampleUsingParentId = listener.SampleUsingParentId;
                    if (sampleUsingParentId != null)
                    {
                        ActivitySamplingResult sr = sampleUsingParentId(ref data);
                        dataWithContext.SetTraceState(data.TraceState); // Keep the trace state in sync between data and dataWithContext

                        if (sr > result)
                        {
                            result = sr;
                        }
                    }
                    else if (data.IdFormat == ActivityIdFormat.W3C)
                    {
                        // In case we have a parent Id and the listener not providing the SampleUsingParentId, we'll try to find out if the following conditions are true:
                        //   - The listener is providing the Sample callback
                        //   - Can convert the parent Id to a Context. ActivityCreationOptions.TraceId != default means parent id converted to a valid context.
                        // Then we can call the listener Sample callback with the constructed context.
                        SampleActivity <ActivityContext>?sample = listener.Sample;
                        if (sample != null)
                        {
                            ActivitySamplingResult sr = sample(ref dataWithContext);
                            data.SetTraceState(dataWithContext.TraceState); // Keep the trace state in sync between data and dataWithContext

                            if (sr > result)
                            {
                                result = sr;
                            }
                        }
                    }
                }, ref aco, ref samplingResult, ref acoContext);

                if (context == default)
                {
                    if (aco.GetContext() != default)
                    {
                        context  = aco.GetContext();
                        parentId = null;
                    }
                    else if (acoContext.GetContext() != default)
                    {
                        context  = acoContext.GetContext();
                        parentId = null;
                    }
                }

                samplerTags = aco.GetSamplingTags();
                ActivityTagsCollection?atc = acoContext.GetSamplingTags();
                if (atc != null)
                {
                    if (samplerTags == null)
                    {
                        samplerTags = atc;
                    }
                    else
                    {
                        foreach (KeyValuePair <string, object?> tag in atc)
                        {
                            samplerTags.Add(tag);
                        }
                    }
                }

                idFormat   = aco.IdFormat;
                traceState = aco.TraceState;
            }
            else
            {
                bool useCurrentActivityContext = context == default && Activity.Current != null;
                var  aco = new ActivityCreationOptions <ActivityContext>(this, name, useCurrentActivityContext ? Activity.Current !.Context : context, kind, tags, links, idFormat);
                listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions <ActivityContext> data, ref ActivitySamplingResult result, ref ActivityCreationOptions <ActivityContext> unused) => {
                    SampleActivity <ActivityContext>?sample = listener.Sample;
                    if (sample != null)
                    {
                        ActivitySamplingResult dr = sample(ref data);
                        if (dr > result)
                        {
                            result = dr;
                        }
                    }
                }, ref aco, ref samplingResult, ref aco);

                if (!useCurrentActivityContext)
                {
                    // We use the context stored inside ActivityCreationOptions as it is possible the trace id get automatically generated during the sampling.
                    // We don't use the context stored inside ActivityCreationOptions only in case if we used Activity.Current context, the reason is we need to
                    // create the new child activity with Parent set to Activity.Current.
                    context = aco.GetContext();
                }

                samplerTags = aco.GetSamplingTags();
                idFormat    = aco.IdFormat;
                traceState  = aco.TraceState;
            }

            if (samplingResult != ActivitySamplingResult.None)
            {
                activity = Activity.Create(this, name, kind, parentId, context, tags, links, startTime, samplerTags, samplingResult, startIt, idFormat, traceState);
            }

            return(activity);
        }
        private Activity?StartActivity(string name, ActivityKind kind, ActivityContext context, string?parentId, IEnumerable <KeyValuePair <string, string?> >?tags, IEnumerable <ActivityLink>?links, DateTimeOffset startTime)
        {
            // _listeners can get assigned to null in Dispose.
            SynchronizedList <ActivityListener>?listeners = _listeners;

            if (listeners == null || listeners.Count == 0)
            {
                return(null);
            }

            Activity?activity = null;

            ActivityDataRequest dataRequest = ActivityDataRequest.None;

            if (parentId != null)
            {
                var aco = new ActivityCreationOptions <string>(this, name, parentId, kind, tags, links);
                listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions <string> data, ref ActivityDataRequest request) => {
                    GetRequestedData <string>?getRequestedDataUsingParentId = listener.GetRequestedDataUsingParentId;
                    if (getRequestedDataUsingParentId != null)
                    {
                        ActivityDataRequest dr = getRequestedDataUsingParentId(ref data);
                        if (dr > request)
                        {
                            request = dr;
                        }

                        // Stop the enumeration if we get the max value RecordingAndSampling.
                        return(request != ActivityDataRequest.AllDataAndRecorded);
                    }
                    return(true);
                }, ref aco, ref dataRequest);
            }
            else
            {
                ActivityContext initializedContext = context == default && Activity.Current != null ? Activity.Current.Context : context;
                var             aco = new ActivityCreationOptions <ActivityContext>(this, name, initializedContext, kind, tags, links);
                listeners.EnumWithFunc((ActivityListener listener, ref ActivityCreationOptions <ActivityContext> data, ref ActivityDataRequest request) => {
                    GetRequestedData <ActivityContext>?getRequestedDataUsingContext = listener.GetRequestedDataUsingContext;
                    if (getRequestedDataUsingContext != null)
                    {
                        ActivityDataRequest dr = getRequestedDataUsingContext(ref data);
                        if (dr > request)
                        {
                            request = dr;
                        }

                        // Stop the enumeration if we get the max value RecordingAndSampling.
                        return(request != ActivityDataRequest.AllDataAndRecorded);
                    }
                    return(true);
                }, ref aco, ref dataRequest);
            }

            if (dataRequest != ActivityDataRequest.None)
            {
                activity = Activity.CreateAndStart(this, name, kind, parentId, context, tags, links, startTime, dataRequest);
                listeners.EnumWithAction((listener, obj) => listener.ActivityStarted?.Invoke((Activity)obj), activity);
            }

            return(activity);
        }