Пример #1
0
        internal void NotifyActivityStop(Activity activity)
        {
            Debug.Assert(activity != null);

            // _listeners can get assigned to null in Dispose.
            SynchronizedList <ActivityListener>?listeners = _listeners;

            if (listeners != null && listeners.Count > 0)
            {
                listeners.EnumWithAction(listener => {
                    listeners.EnumWithAction(listener => listener.ActivityStopped?.Invoke(activity));
                });
            }
        }
Пример #2
0
        /// <summary>
        /// Construct an ActivitySource object with the input name
        /// </summary>
        /// <param name="name">The name of the ActivitySource object</param>
        /// <param name="version">The version of the component publishing the tracing info.</param>
        public ActivitySource(string name, string?version = "")
        {
            Name    = name ?? throw new ArgumentNullException(nameof(name));
            Version = version;

            s_activeSources.Add(this);

            if (s_allListeners.Count > 0)
            {
                s_allListeners.EnumWithAction((listener, source) =>
                {
                    Func <ActivitySource, bool>?shouldListenTo = listener.ShouldListenTo;
                    if (shouldListenTo != null)
                    {
                        var activitySource = (ActivitySource)source;
                        if (shouldListenTo(activitySource))
                        {
                            activitySource.AddListener(listener);
                        }
                    }
                }, this);
            }

            GC.KeepAlive(DiagnosticSourceEventSource.Log);
        }
Пример #3
0
        /// <summary>
        /// Add a listener to the <see cref="Activity"/> starting and stopping events.
        /// </summary>
        /// <param name="listener"> The <see cref="ActivityListener"/> object to use for listeneing to the <see cref="Activity"/> events.</param>
        public static void AddActivityListener(ActivityListener listener)
        {
            if (listener == null)
            {
                throw new ArgumentNullException(nameof(listener));
            }

            if (s_allListeners.AddIfNotExist(listener))
            {
                s_activeSources.EnumWithAction(source => {
                    var shouldListenTo = listener.ShouldListenTo;
                    if (shouldListenTo != null && shouldListenTo(source))
                    {
                        source.AddListener(listener);
                    }
                });
            }
        }
Пример #4
0
        /// <summary>
        /// Construct an ActivitySource object with the input name
        /// </summary>
        /// <param name="name">The name of the ActivitySource object</param>
        /// <param name="version">The version of the component publishing the tracing info.</param>
        public ActivitySource(string name, string?version = "")
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            Name    = name;
            Version = version;

            s_activeSources.Add(this);

            if (s_allListeners.Count > 0)
            {
                s_allListeners.EnumWithAction(listener => {
                    var shouldListenTo = listener.ShouldListenTo;
                    if (shouldListenTo != null && shouldListenTo(this))
                    {
                        AddListener(listener);
                    }
                });
            }
        }
Пример #5
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);
        }
Пример #6
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;
            ActivityTagsCollection?samplerTags;

            ActivitySamplingResult samplingResult = ActivitySamplingResult.None;

            if (parentId != null)
            {
                var aco        = new ActivityCreationOptions <string>(this, name, parentId, kind, tags, links);
                var acoContext = new ActivityCreationOptions <ActivityContext>(this, name, aco.GetContext(), kind, tags, links);

                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);
                        if (sr > result)
                        {
                            result = sr;
                        }
                    }
                    else
                    {
                        // 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 && data.GetContext() != default) // data.GetContext() != default means parent Id parsed correctly to a context
                        {
                            ActivitySamplingResult sr = sample(ref dataWithContext);
                            if (sr > result)
                            {
                                result = sr;
                            }
                        }
                    }
                }, ref aco, ref samplingResult, ref acoContext);

                if (context == default && aco.GetContext() != default)
                {
                    context  = aco.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);
                        }
                    }
                }
            }
            else
            {
                bool useCurrentActivityContext = context == default && Activity.Current != null;
                var  aco = new ActivityCreationOptions <ActivityContext>(this, name, useCurrentActivityContext ? Activity.Current !.Context : context, kind, tags, links);
                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();
            }

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

            return(activity);
        }
Пример #7
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 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;
                var             aco = 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)
                    {
                        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, ref useContext, ref optionsWithContext);
            }

            if (dataRequest != ActivityDataRequest.None)
            {
                if (useContext.HasValue && useContext.Value)
                {
                    context  = optionsWithContext.Parent;
                    parentId = null;
                }

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

            return(activity);
        }
Пример #8
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 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);
        }