public void ActivityImportExport()
        {
            using (DiagnosticListener listener = new DiagnosticListener("TestingBasicIsEnabled"))
            {
                DiagnosticSource source = listener;
                var result = new List <KeyValuePair <string, object> >();

                bool seenPredicate = false;
                Func <string, object, object, bool> predicate = delegate(string name, object obj1, object obj2)
                {
                    seenPredicate = true;
                    return(true);
                };

                Activity importerActivity   = new Activity("activityImporter");
                object   importer           = "MyImporterObject";
                bool     seenActivityImport = false;
                Action <Activity, object> activityImport = delegate(Activity activity, object payload)
                {
                    Assert.Equal(activity.GetHashCode(), importerActivity.GetHashCode());
                    Assert.Equal(importer, payload);
                    seenActivityImport = true;
                };

                Activity exporterActivity   = new Activity("activityExporter");
                object   exporter           = "MyExporterObject";
                bool     seenActivityExport = false;
                Action <Activity, object> activityExport = delegate(Activity activity, object payload)
                {
                    Assert.Equal(activity.GetHashCode(), exporterActivity.GetHashCode());
                    Assert.Equal(exporter, payload);
                    seenActivityExport = true;
                };

                // Use the Subscribe that allows you to hook the OnActivityImport and OnActivityExport calls.
                using (listener.Subscribe(new ObserverToList <TelemData>(result), predicate, activityImport, activityExport))
                {
                    if (listener.IsEnabled("IntPayload"))
                    {
                        listener.Write("IntPayload", 5);
                    }

                    Assert.True(seenPredicate);
                    Assert.Equal(1, result.Count);
                    Assert.Equal("IntPayload", result[0].Key);
                    Assert.Equal(5, result[0].Value);

                    listener.OnActivityImport(importerActivity, importer);
                    Assert.True(seenActivityImport);

                    listener.OnActivityExport(exporterActivity, exporter);
                    Assert.True(seenActivityExport);
                }
            }
        }
Exemple #2
0
        private Activity StartActivity(HttpContext httpContext, out bool hasDiagnosticListener)
        {
            var activity = new Activity(ActivityName);

            hasDiagnosticListener = false;

            var headers = httpContext.Request.Headers;

            if (!headers.TryGetValue(HeaderNames.TraceParent, out var requestId))
            {
                headers.TryGetValue(HeaderNames.RequestId, out requestId);
            }

            if (!StringValues.IsNullOrEmpty(requestId))
            {
                activity.SetParentId(requestId);
                if (headers.TryGetValue(HeaderNames.TraceState, out var traceState))
                {
                    activity.TraceStateString = traceState;
                }

                // We expect baggage to be empty by default
                // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
                var baggage = headers.GetCommaSeparatedValues(HeaderNames.Baggage);
                if (baggage.Length == 0)
                {
                    baggage = headers.GetCommaSeparatedValues(HeaderNames.CorrelationContext);
                }

                // AddBaggage adds items at the beginning  of the list, so we need to add them in reverse to keep the same order as the client
                // An order could be important if baggage has two items with the same key (that is allowed by the contract)
                for (var i = baggage.Length - 1; i >= 0; i--)
                {
                    if (NameValueHeaderValue.TryParse(baggage[i], out var baggageItem))
                    {
                        activity.AddBaggage(baggageItem.Name.ToString(), HttpUtility.UrlDecode(baggageItem.Value.ToString()));
                    }
                }
            }

            _diagnosticListener.OnActivityImport(activity, httpContext);

            if (_diagnosticListener.IsEnabled(ActivityStartKey))
            {
                hasDiagnosticListener = true;
                StartActivity(activity, httpContext);
            }
            else
            {
                activity.Start();
            }

            return(activity);
        }
Exemple #3
0
        private Activity StartActivity(HttpContext httpContext, out bool hasDiagnosticListener)
        {
            var activity = new Activity(ActivityName);

            hasDiagnosticListener = false;

            var headers = httpContext.Request.Headers;

            if (!headers.TryGetValue(HeaderNames.TraceParent, out var requestId))
            {
                headers.TryGetValue(HeaderNames.RequestId, out requestId);
            }

            if (!StringValues.IsNullOrEmpty(requestId))
            {
                activity.SetParentId(requestId);
                if (headers.TryGetValue(HeaderNames.TraceState, out var traceState))
                {
                    activity.TraceStateString = traceState;
                }

                // We expect baggage to be empty by default
                // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
                string[] baggage = headers.GetCommaSeparatedValues(HeaderNames.CorrelationContext);
                if (baggage.Length > 0)
                {
                    foreach (var item in baggage)
                    {
                        if (NameValueHeaderValue.TryParse(item, out var baggageItem))
                        {
                            activity.AddBaggage(baggageItem.Name.ToString(), HttpUtility.UrlDecode(baggageItem.Value.ToString()));
                        }
                    }
                }
            }

            _diagnosticListener.OnActivityImport(activity, httpContext);

            if (_diagnosticListener.IsEnabled(ActivityStartKey))
            {
                hasDiagnosticListener = true;
                StartActivity(activity, httpContext);
            }
            else
            {
                activity.Start();
            }

            return(activity);
        }
        private Activity StartActivity(HttpContext httpContext)
        {
            var activity = new Activity(ActivityName);

            if (!httpContext.Request.Headers.TryGetValue(TraceParentHeaderName, out var requestId))
            {
                httpContext.Request.Headers.TryGetValue(RequestIdHeaderName, out requestId);
            }

            if (!StringValues.IsNullOrEmpty(requestId))
            {
                activity.SetParentId(requestId);
                if (httpContext.Request.Headers.TryGetValue(TraceStateHeaderName, out var traceState))
                {
                    activity.TraceStateString = traceState;
                }

                // We expect baggage to be empty by default
                // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
                string[] baggage = httpContext.Request.Headers.GetCommaSeparatedValues(CorrelationContextHeaderName);
                if (baggage != StringValues.Empty)
                {
                    foreach (var item in baggage)
                    {
                        if (NameValueHeaderValue.TryParse(item, out var baggageItem))
                        {
                            activity.AddBaggage(baggageItem.Name.ToString(), baggageItem.Value.ToString());
                        }
                    }
                }
            }

            _diagnosticListener.OnActivityImport(activity, httpContext);

            if (_diagnosticListener.IsEnabled(ActivityStartKey))
            {
                _diagnosticListener.StartActivity(activity, new { HttpContext = httpContext });
            }
            else
            {
                activity.Start();
            }

            return(activity);
        }
        /// <summary>
        /// Creates root (first level) activity that describes incoming request.
        /// </summary>
        /// <param name="context">Current HttpContext.</param>
        /// <param name="parseHeaders">Determines if headers should be parsed get correlation ids.</param>
        /// <returns>New root activity.</returns>
        public static Activity CreateRootActivity(HttpContext context, bool parseHeaders)
        {
            if (AspNetListener.IsEnabled() && AspNetListener.IsEnabled(AspNetActivityName))
            {
                var rootActivity = new Activity(AspNetActivityName);

                if (parseHeaders)
                {
                    rootActivity.Extract(context.Request.Unvalidated.Headers);
                }

                AspNetListener.OnActivityImport(rootActivity, null);

                if (StartAspNetActivity(rootActivity))
                {
                    context.Items[ActivityKey] = rootActivity;
                    AspNetTelemetryCorrelationEventSource.Log.ActivityStarted(rootActivity.Id);
                    return(rootActivity);
                }
            }

            return(null);
        }