diff --git a/src/ApplicationInsights.AspNet/ApplicationInsightsExtensions.cs b/src/ApplicationInsights.AspNet/ApplicationInsightsExtensions.cs index 7c64983..9fb6783 100644 --- a/src/ApplicationInsights.AspNet/ApplicationInsightsExtensions.cs +++ b/src/ApplicationInsights.AspNet/ApplicationInsightsExtensions.cs @@ -51,6 +51,7 @@ TelemetryConfiguration.Active.TelemetryInitializers.Add(new WebClientIpHeaderTelemetryInitializer(svcs)); TelemetryConfiguration.Active.TelemetryInitializers.Add(new WebUserAgentTelemetryInitializer(svcs)); TelemetryConfiguration.Active.TelemetryInitializers.Add(new WebOperationNameTelemetryInitializer(svcs)); + TelemetryConfiguration.Active.TelemetryInitializers.Add(new WebOperationIdTelemetryInitializer(svcs)); return new TelemetryClient(); }); diff --git a/src/ApplicationInsights.AspNet/TelemetryInitializers/TelemetryInitializerBase.cs b/src/ApplicationInsights.AspNet/TelemetryInitializers/TelemetryInitializerBase.cs index 6c00a48..52c820d 100644 --- a/src/ApplicationInsights.AspNet/TelemetryInitializers/TelemetryInitializerBase.cs +++ b/src/ApplicationInsights.AspNet/TelemetryInitializers/TelemetryInitializerBase.cs @@ -11,22 +11,27 @@ public abstract class TelemetryInitializerBase : ITelemetryInitializer { - IServiceProvider serviceProvider; + private IServiceProvider serviceProvider; public TelemetryInitializerBase(IServiceProvider serviceProvider) { - if (serviceProvider == null) - { - throw new ArgumentNullException("serviceProvider"); - } - this.serviceProvider = serviceProvider; + + if (this.serviceProvider == null) + { + // TODO: Diagnostics + } } public void Initialize(ITelemetry telemetry) { try { + if (serviceProvider == null) + { + return; + } + var contextHolder = this.serviceProvider.GetService(); if (contextHolder == null) diff --git a/src/ApplicationInsights.AspNet/TelemetryInitializers/WebOperationIdTelemetryInitializer.cs b/src/ApplicationInsights.AspNet/TelemetryInitializers/WebOperationIdTelemetryInitializer.cs new file mode 100644 index 0000000..989915d --- /dev/null +++ b/src/ApplicationInsights.AspNet/TelemetryInitializers/WebOperationIdTelemetryInitializer.cs @@ -0,0 +1,21 @@ +namespace Microsoft.ApplicationInsights.AspNet.TelemetryInitializers +{ + using System; + using Microsoft.ApplicationInsights.Channel; + using Microsoft.ApplicationInsights.DataContracts; + using Microsoft.AspNet.Http; + + public class WebOperationIdTelemetryInitializer : TelemetryInitializerBase + { + public WebOperationIdTelemetryInitializer(IServiceProvider serviceProvider) : base(serviceProvider) + { } + + protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry) + { + if (string.IsNullOrEmpty(telemetry.Context.Operation.Id)) + { + telemetry.Context.Operation.Id = requestTelemetry.Id; + } + } + } +} \ No newline at end of file diff --git a/test/ApplicationInsights.AspNet.Tests/ApplicationInsightsExtensionsTests.cs b/test/ApplicationInsights.AspNet.Tests/ApplicationInsightsExtensionsTests.cs index 3bbc2a9..329c2ec 100644 --- a/test/ApplicationInsights.AspNet.Tests/ApplicationInsightsExtensionsTests.cs +++ b/test/ApplicationInsights.AspNet.Tests/ApplicationInsightsExtensionsTests.cs @@ -105,6 +105,30 @@ } } + [Fact] + public void AddTelemetryWillAddOperationIdTelelemtryInitializerInConfigurationActive() + { + try + { + var serviceCollection = HostingServices.Create(null); + IConfiguration config = new Configuration().AddJsonFile("content\\config.json"); + + serviceCollection.AddApplicationInsightsTelemetry(config); + + var serviceProvider = serviceCollection.BuildServiceProvider(); + + var items = TelemetryConfiguration.Active.TelemetryInitializers + .Select(i => i is WebOperationIdTelemetryInitializer) + .ToList(); + + Assert.Equal(1, items.Count); + } + finally + { + CleanActiveConfiguration(); + } + } + [Fact] public void JSSnippetWillNotThrowWithoutInstrumentationKey() { diff --git a/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationIdTelemetryInitializerTest.cs b/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationIdTelemetryInitializerTest.cs new file mode 100644 index 0000000..718d9d4 --- /dev/null +++ b/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationIdTelemetryInitializerTest.cs @@ -0,0 +1,73 @@ +namespace Microsoft.ApplicationInsights.AspNet.Tests.TelemetryInitializers +{ + using Microsoft.ApplicationInsights.AspNet.Implementation; + using Microsoft.ApplicationInsights.AspNet.TelemetryInitializers; + using Microsoft.ApplicationInsights.AspNet.Tests.Helpers; + using Microsoft.ApplicationInsights.DataContracts; + using Microsoft.AspNet.Http.Core; + using System; + using System.Collections.Generic; + using Xunit; + + public class WebOperationIdTelemetryInitializerTest + { + [Fact] + public void InitializeDoesNotThrowIfHttpContextHolderIsUnavailable() + { + var initializer = new WebOperationIdTelemetryInitializer(new TestServiceProvider()); + + initializer.Initialize(new RequestTelemetry()); + } + + [Fact] + public void InitializeDoesNotThrowIfHttpContextIsUnavailable() + { + var serviceProvider = new TestServiceProvider(new List() { new HttpContextHolder() }); + var initializer = new WebOperationIdTelemetryInitializer(serviceProvider); + + initializer.Initialize(new RequestTelemetry()); + } + + [Fact] + public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable() + { + var contextHolder = new HttpContextHolder(); + contextHolder.Context = new DefaultHttpContext(); + var serviceProvider = new TestServiceProvider(new List() { contextHolder }); + var initializer = new WebOperationIdTelemetryInitializer(serviceProvider); + + initializer.Initialize(new RequestTelemetry()); + } + + [Fact] + public void InitializeDoesNotOverrideOperationIdProvidedInline() + { + var telemetry = new EventTelemetry(); + telemetry.Context.Operation.Id = "123"; + var requestTelemetry = new RequestTelemetry(); + var contextHolder = new HttpContextHolder() { Context = new DefaultHttpContext() }; + + var serviceProvider = new TestServiceProvider(new List() { contextHolder, requestTelemetry }); + var initializer = new WebOperationIdTelemetryInitializer(serviceProvider); + + initializer.Initialize(telemetry); + + Assert.Equal("123", telemetry.Context.Operation.Id); + } + + [Fact] + public void InitializeSetsTelemetryOperationIdToRequestId() + { + var telemetry = new EventTelemetry(); + var requestTelemetry = new RequestTelemetry(); + var contextHolder = new HttpContextHolder() { Context = new DefaultHttpContext() }; + + var serviceProvider = new TestServiceProvider(new List() { contextHolder, requestTelemetry }); + var initializer = new WebOperationIdTelemetryInitializer(serviceProvider); + + initializer.Initialize(telemetry); + + Assert.Equal(requestTelemetry.Id, telemetry.Context.Operation.Id); + } + } +} \ No newline at end of file diff --git a/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationNameTelemetryInitializerTests.cs b/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationNameTelemetryInitializerTests.cs index 8a0e036..9c35e1b 100644 --- a/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationNameTelemetryInitializerTests.cs +++ b/test/ApplicationInsights.AspNet.Tests/TelemetryInitializers/WebOperationNameTelemetryInitializerTests.cs @@ -38,6 +38,22 @@ initializer.Initialize(new RequestTelemetry()); } + [Fact] + public void InitializeDoesNotOverrideOperationNameProvidedInline() + { + var telemetry = new EventTelemetry(); + telemetry.Context.Operation.Name = "Name"; + + var contextHolder = new HttpContextHolder() { Context = new DefaultHttpContext() }; + + var serviceProvider = new TestServiceProvider(new List() { contextHolder, new RequestTelemetry() }); + var initializer = new WebOperationNameTelemetryInitializer(serviceProvider); + + initializer.Initialize(telemetry); + + Assert.Equal("Name", telemetry.Context.Operation.Name); + } + [Fact] public void InitializeSetsTelemetryOperationNameToMethodAndPath() {