/// <summary> /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item. /// </summary> /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param> internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient) { var telemetry = new DependencyTelemetry(); telemetry.Start(); Activity activity; Activity currentActivity = Activity.Current; // On .NET46 without profiler, outgoing requests are instrumented with reflection hook in DiagnosticSource //// see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs // it creates an Activity and injects standard 'Request-Id' and 'Correlation-Context' headers itself, so we should not start Activity in this case if (currentActivity != null && currentActivity.OperationName == "System.Net.Http.Desktop.HttpRequestOut") { activity = currentActivity; } else { // Every operation must have its own Activity // if dependency is tracked with profiler of event source, we need to generate a proper Id for it // in case of HTTP it will be propagated into the request header. // So, we will create a new Activity for the dependency, just to generate an Id. activity = new Activity(DependencyActivityName); activity.Start(); } // OperationCorrelationTelemetryInitializer will initialize telemetry as a child of current activity: // But we need to initialize dependency telemetry from the current Activity: // Activity was created for this dependency in the Http Desktop DiagnosticSource if (activity.IdFormat == ActivityIdFormat.W3C) { var context = telemetry.Context; context.Operation.Id = activity.TraceId.ToHexString(); if (activity.Parent != null || activity.ParentSpanId != default) { context.Operation.ParentId = activity.ParentSpanId.ToHexString(); } telemetry.Id = activity.SpanId.ToHexString(); } else { var context = telemetry.Context; context.Operation.Id = activity.RootId; context.Operation.ParentId = activity.ParentId; telemetry.Id = activity.Id; } foreach (var item in activity.Baggage) { if (!telemetry.Properties.ContainsKey(item.Key)) { telemetry.Properties.Add(item); } } telemetryClient.Initialize(telemetry); PretendProfilerIsAttached = false; return(telemetry); }
public void OnBeginTelemetryCreatedWithinRequestScopeIsRequestChild() { var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string> { ["Request-Id"] = "|guid1.1", ["Correlation-Context"] = "k=v" }); var config = this.CreateDefaultConfig(context); var module = this.RequestTrackingTelemetryModuleFactory(config); module.OnBeginRequest(context); var requestTelemetry = context.GetRequestTelemetry(); var telemetryClient = new TelemetryClient(config); var exceptionTelemetry = new ExceptionTelemetry(); telemetryClient.Initialize(exceptionTelemetry); module.OnEndRequest(context); Assert.Equal("guid1", exceptionTelemetry.Context.Operation.Id); Assert.Equal(requestTelemetry.Id, exceptionTelemetry.Context.Operation.ParentId); Assert.Equal("v", exceptionTelemetry.Context.Properties["k"]); }
private static RequestTelemetry SetUpRequestActivity( string requestId, string requestName, IEnumerable <KeyValuePair <string, string> > correlationContext, string activityName) { var activity = new Activity(activityName); activity.SetParentId(requestId); RequestTelemetry rt = new RequestTelemetry(); rt.Context.Operation.ParentId = requestId; foreach (KeyValuePair <string, string> pair in correlationContext) { activity.AddBaggage(pair.Key, pair.Value); } activity.Start(); rt.Id = activity.Id; rt.Context.Operation.Id = activity.RootId; rt.Name = requestName; telemetryClient.Initialize(rt); rt.Start(Stopwatch.GetTimestamp()); return(rt); }
/// <summary> /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item. /// </summary> /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param> internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient) { var telemetry = new DependencyTelemetry(); telemetry.Start(); telemetryClient.Initialize(telemetry); PretendProfilerIsAttached = false; return telemetry; }
/// <summary> /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item. /// </summary> /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param> internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient) { var telemetry = new DependencyTelemetry(); telemetry.Start(); telemetryClient.Initialize(telemetry); #if NET45 Activity activity; Activity currentActivity = Activity.Current; // On .NET46 without profiler, outgoing requests are instrumented with reflection hook in DiagnosticSource //// see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs // it creates an Activity and injects standard 'Request-Id' and 'Correlation-Context' headers itself, so we should not start Activity in this case if (currentActivity != null && currentActivity.OperationName == "System.Net.Http.Desktop.HttpRequestOut") { activity = currentActivity; } else { // Every operation must have its own Activity // if dependency is tracked with profiler of event source, we need to generate a proper hierarchical Id for it // in case of HTTP it will be propagated into the requert header. // So, we will create a new Activity for the dependency, jut to generate an Id. activity = new Activity(DependencyActivityName); // This is workaround for the issue https://github.com/Microsoft/ApplicationInsights-dotnet/issues/538 // if there is no parent Activity, ID Activity generates is not random enough to work well with // ApplicationInsights sampling algorithm // This code should go away when Activity is fixed: https://github.com/dotnet/corefx/issues/18418 if (Activity.Current == null) { activity.SetParentId(telemetry.Id); } //// end of workaround activity.Start(); activity.Stop(); } // telemetry is initialized from current Activity (root and parent Id, but not the Id) telemetry.Id = activity.Id; // set operation root Id in case there was no parent activity (e.g. HttpRequest in background thread) if (string.IsNullOrEmpty(telemetry.Context.Operation.Id)) { telemetry.Context.Operation.Id = activity.RootId; } #else // telemetry is initialized by Base SDK OperationCorrealtionTelemetryInitializer // however it does not know about Activity on .NET40 and does not know how to properly generate Ids // let's fix it telemetry.Id = ApplicationInsightsActivity.GenerateDependencyId(telemetry.Context.Operation.ParentId); telemetry.Context.Operation.Id = ApplicationInsightsActivity.GetRootId(telemetry.Id); #endif PretendProfilerIsAttached = false; return(telemetry); }
/// <summary> /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item. /// </summary> /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param> internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient) { var telemetry = new DependencyTelemetry(); telemetry.Start(); telemetryClient.Initialize(telemetry); PretendProfilerIsAttached = false; return(telemetry); }
public void OnBeginTelemetryCreatedWithinRequestScopeIsRequestChildW3COff() { var context = HttpModuleHelper.GetFakeHttpContext(); var config = this.CreateDefaultConfig(context); var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context)); Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical; Activity.ForceDefaultIdFormat = true; module.OnBeginRequest(context); var activity = Activity.Current; var requestTelemetry = context.GetRequestTelemetry(); var telemetryClient = new TelemetryClient(config); var exceptionTelemetry = new ExceptionTelemetry(); telemetryClient.Initialize(exceptionTelemetry); module.OnEndRequest(context); Assert.Equal(activity.RootId, exceptionTelemetry.Context.Operation.Id); Assert.Equal(requestTelemetry.Context.Operation.Id, exceptionTelemetry.Context.Operation.Id); Assert.Equal(requestTelemetry.Id, exceptionTelemetry.Context.Operation.ParentId); }
/// <summary> /// The function that needs to be called before sending a request to the server. Creates and initializes dependency telemetry item. /// </summary> /// <param name="telemetryClient">Telemetry client object to initialize the context of the telemetry item.</param> internal static DependencyTelemetry BeginTracking(TelemetryClient telemetryClient) { var telemetry = new DependencyTelemetry(); telemetry.Start(); Activity activity; Activity currentActivity = Activity.Current; // On .NET46 without profiler, outgoing requests are instrumented with reflection hook in DiagnosticSource //// see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs // it creates an Activity and injects standard 'Request-Id' and 'Correlation-Context' headers itself, so we should not start Activity in this case if (currentActivity != null && currentActivity.OperationName == "System.Net.Http.Desktop.HttpRequestOut") { activity = currentActivity; // OperationCorrelationTelemetryInitializer will initialize telemetry as a child of current activity: // But we need to initialize dependency telemetry from the current Activity: // Activity was created for this dependency in the Http Desktop DiagnosticSource var context = telemetry.Context; context.Operation.Id = activity.RootId; context.Operation.ParentId = activity.ParentId; foreach (var item in activity.Baggage) { if (!telemetry.Properties.ContainsKey(item.Key)) { telemetry.Properties.Add(item); } } telemetryClient.Initialize(telemetry); } else { telemetryClient.Initialize(telemetry); // Every operation must have its own Activity // if dependency is tracked with profiler of event source, we need to generate a proper Id for it // in case of HTTP it will be propagated into the requert header. // So, we will create a new Activity for the dependency, just to generate an Id. activity = new Activity(DependencyActivityName); // As a first step in supporting W3C protocol in ApplicationInsights, // we want to generate Activity Ids in the W3C compatible format. // While .NET changes to Activity are pending, we want to ensure trace starts with W3C compatible Id // as early as possible, so that everyone has a chance to upgrade and have compatibility with W3C systems once they arrive. // So if there is no parent Activity (i.e. this request has happened in the background, without parent scope), we'll override // the current Activity with the one with properly formatted Id. This workaround should go away // with W3C support on .NET https://github.com/dotnet/corefx/issues/30331 (TODO) if (currentActivity == null) { activity.SetParentId(StringUtilities.GenerateTraceId()); } // end of workaround activity.Start(); } // telemetry is initialized from current Activity (root and parent Id, but not the Id) telemetry.Id = activity.Id; // set operation root Id in case there was no parent activity (e.g. HttpRequest in background thread) if (string.IsNullOrEmpty(telemetry.Context.Operation.Id)) { telemetry.Context.Operation.Id = activity.RootId; } #pragma warning disable 612, 618 if (IsW3CEnabled) { W3COperationCorrelationTelemetryInitializer.UpdateTelemetry(telemetry, activity, true); } #pragma warning restore 612, 618 PretendProfilerIsAttached = false; return(telemetry); }