diff --git a/CHANGELOG.md b/CHANGELOG.md index 137712e3..89ef81d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## Version 2.12.0-beta1 - Skipping version numbers to keep in sync with Base SDK. - +- [Fix Null/Empty Ikey from ApplicationInsightsServiceOptions overrding one from appsettings.json](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/989) +- [Provide ApplicationInsightsServiceOptions for easy disabling of any default TelemetryModules](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/988) ## Version 2.8.0 - Updated Bask SDK/Web SDK/Logging Adaptor SDK to 2.11.0 diff --git a/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs b/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs index 7d2658e1..e4a37d3c 100644 --- a/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs +++ b/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs @@ -31,6 +31,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; + using Shared.Implementation; /// /// Extension methods for that allow adding Application Insights services to application. @@ -109,19 +110,7 @@ public static IServiceCollection AddApplicationInsightsTelemetry( ApplicationInsightsServiceOptions options) { services.AddApplicationInsightsTelemetry(); - services.Configure((ApplicationInsightsServiceOptions o) => - { - o.ApplicationVersion = options.ApplicationVersion; - o.DeveloperMode = options.DeveloperMode; - o.EnableAdaptiveSampling = options.EnableAdaptiveSampling; - o.EnableAuthenticationTrackingJavaScript = options.EnableAuthenticationTrackingJavaScript; - o.EnableDebugLogger = options.EnableDebugLogger; - o.EnableQuickPulseMetricStream = options.EnableQuickPulseMetricStream; - o.EndpointAddress = options.EndpointAddress; - o.InstrumentationKey = options.InstrumentationKey; - o.EnableHeartbeat = options.EnableHeartbeat; - o.AddAutoCollectedMetricExtractor = options.AddAutoCollectedMetricExtractor; - }); + ConfigureAiServiceOption(services, options); return services; } @@ -143,10 +132,27 @@ public static IServiceCollection AddApplicationInsightsTelemetry(this IServiceCo AddCommonInitializers(services); // Request Tracking. - services.AddSingleton(); + services.AddSingleton(provider => + { + var options = provider.GetRequiredService>().Value; + var appIdProvider = provider.GetService(); + + if (options.EnableRequestTrackingTelemetryModule) + { + return new RequestTrackingTelemetryModule(appIdProvider); + } + else + { + return new NoOpTelemetryModule(); + } + }); + services.ConfigureTelemetryModule((module, options) => { - module.CollectionOptions = options.RequestCollectionOptions; + if(options.EnableRequestTrackingTelemetryModule) + { + module.CollectionOptions = options.RequestCollectionOptions; + } }); AddCommonTelemetryModules(services); diff --git a/src/Microsoft.ApplicationInsights.WorkerService/ApplicationInsightsExtensions.cs b/src/Microsoft.ApplicationInsights.WorkerService/ApplicationInsightsExtensions.cs index 87ce2c91..2317e3c7 100644 --- a/src/Microsoft.ApplicationInsights.WorkerService/ApplicationInsightsExtensions.cs +++ b/src/Microsoft.ApplicationInsights.WorkerService/ApplicationInsightsExtensions.cs @@ -86,19 +86,7 @@ public static IServiceCollection AddApplicationInsightsTelemetryWorkerService( ApplicationInsightsServiceOptions options) { services.AddApplicationInsightsTelemetryWorkerService(); - services.Configure((ApplicationInsightsServiceOptions o) => - { - o.ApplicationVersion = options.ApplicationVersion; - o.DeveloperMode = options.DeveloperMode; - o.EnableAdaptiveSampling = options.EnableAdaptiveSampling; - o.EnableAuthenticationTrackingJavaScript = options.EnableAuthenticationTrackingJavaScript; - o.EnableDebugLogger = options.EnableDebugLogger; - o.EnableQuickPulseMetricStream = options.EnableQuickPulseMetricStream; - o.EndpointAddress = options.EndpointAddress; - o.InstrumentationKey = options.InstrumentationKey; - o.EnableHeartbeat = options.EnableHeartbeat; - o.AddAutoCollectedMetricExtractor = options.AddAutoCollectedMetricExtractor; - }); + ConfigureAiServiceOption(services, options); return services; } diff --git a/src/Shared/Extensions/ApplicationInsightsExtensions.cs b/src/Shared/Extensions/ApplicationInsightsExtensions.cs index 14c37f0d..a23a6ed4 100644 --- a/src/Shared/Extensions/ApplicationInsightsExtensions.cs +++ b/src/Shared/Extensions/ApplicationInsightsExtensions.cs @@ -32,6 +32,7 @@ #endif using Microsoft.Extensions.Options; using Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId; + using Shared.Implementation; /// /// Extension methods for that allow adding Application Insights services to application. @@ -274,13 +275,77 @@ private static void AddCommonInitializers(IServiceCollection services) private static void AddCommonTelemetryModules(IServiceCollection services) { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(provider => + { + var options = provider.GetRequiredService>().Value; + + if(options.EnablePerformanceCounterCollectionModule) + { + return new PerformanceCollectorModule(); + } + else + { + return new NoOpTelemetryModule(); + } + }); + + services.AddSingleton(provider => + { + var options = provider.GetRequiredService>().Value; + + if (options.EnableAppServicesHeartbeatTelemetryModule) + { + return new AppServicesHeartbeatTelemetryModule(); + } + else + { + return new NoOpTelemetryModule(); + } + }); + + services.AddSingleton(provider => + { + var options = provider.GetRequiredService>().Value; + + if (options.EnableAzureInstanceMetadataTelemetryModule) + { + return new AzureInstanceMetadataTelemetryModule(); + } + else + { + return new NoOpTelemetryModule(); + } + }); + + services.AddSingleton(provider => + { + var options = provider.GetRequiredService>().Value; + + if (options.EnableQuickPulseMetricStream) + { + return new QuickPulseTelemetryModule(); + } + else + { + return new NoOpTelemetryModule(); + } + }); + AddAndConfigureDependencyTracking(services); #if NETSTANDARD2_0 - services.AddSingleton(); + services.AddSingleton(provider => + { + var options = provider.GetRequiredService>().Value; + + if (options.EnableEventCounterCollectionModule) + { + return new EventCounterCollectionModule(); + } + else + { + return new NoOpTelemetryModule(); + } + }); #endif } @@ -306,27 +371,43 @@ private static void AddTelemetryConfigAndClient(IServiceCollection services) private static void AddAndConfigureDependencyTracking(IServiceCollection services) { - services.AddSingleton(); - services.ConfigureTelemetryModule((module, o) => + services.AddSingleton(provider => { - module.EnableLegacyCorrelationHeadersInjection = - o.DependencyCollectionOptions.EnableLegacyCorrelationHeadersInjection; - - var excludedDomains = module.ExcludeComponentCorrelationHttpHeadersOnDomains; - excludedDomains.Add("core.windows.net"); - excludedDomains.Add("core.chinacloudapi.cn"); - excludedDomains.Add("core.cloudapi.de"); - excludedDomains.Add("core.usgovcloudapi.net"); + var options = provider.GetRequiredService>().Value; - if (module.EnableLegacyCorrelationHeadersInjection) + if (options.EnableDependencyTrackingTelemetryModule) { - excludedDomains.Add("localhost"); - excludedDomains.Add("127.0.0.1"); + return new DependencyTrackingTelemetryModule(); } + else + { + return new NoOpTelemetryModule(); + } + }); + + services.ConfigureTelemetryModule((module, o) => + { + if(o.EnableDependencyTrackingTelemetryModule) + { + module.EnableLegacyCorrelationHeadersInjection = + o.DependencyCollectionOptions.EnableLegacyCorrelationHeadersInjection; + + var excludedDomains = module.ExcludeComponentCorrelationHttpHeadersOnDomains; + excludedDomains.Add("core.windows.net"); + excludedDomains.Add("core.chinacloudapi.cn"); + excludedDomains.Add("core.cloudapi.de"); + excludedDomains.Add("core.usgovcloudapi.net"); + + if (module.EnableLegacyCorrelationHeadersInjection) + { + excludedDomains.Add("localhost"); + excludedDomains.Add("127.0.0.1"); + } - var includedActivities = module.IncludeDiagnosticSourceActivities; - includedActivities.Add("Microsoft.Azure.EventHubs"); - includedActivities.Add("Microsoft.Azure.ServiceBus"); + var includedActivities = module.IncludeDiagnosticSourceActivities; + includedActivities.Add("Microsoft.Azure.EventHubs"); + includedActivities.Add("Microsoft.Azure.ServiceBus"); + } }); } @@ -341,43 +422,88 @@ private static void AddEventCounterIfNotExist(EventCounterCollectionModule event private static void ConfigureEventCounterModuleWithSystemCounters(IServiceCollection services) { services.ConfigureTelemetryModule((eventCounterModule, options) => - { - // Ref this code for actual names. https://github.com/dotnet/coreclr/blob/dbc5b56c48ce30635ee8192c9814c7de998043d5/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "cpu-usage"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "working-set"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gc-heap-size"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-0-gc-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-1-gc-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-2-gc-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "time-in-gc"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-0-size"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-1-size"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-2-size"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "loh-size"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "alloc-rate"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "assembly-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "exception-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "threadpool-thread-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "monitor-lock-contention-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "threadpool-queue-length"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "threadpool-completed-items-count"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "active-timer-count"); - }); + { + if(options.EnableEventCounterCollectionModule) + { + // Ref this code for actual names. https://github.com/dotnet/coreclr/blob/dbc5b56c48ce30635ee8192c9814c7de998043d5/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "cpu-usage"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "working-set"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gc-heap-size"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-0-gc-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-1-gc-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-2-gc-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "time-in-gc"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-0-size"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-1-size"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "gen-2-size"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "loh-size"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "alloc-rate"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "assembly-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "exception-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "threadpool-thread-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "monitor-lock-contention-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "threadpool-queue-length"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "threadpool-completed-items-count"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForSystemRuntime, "active-timer-count"); + } + }); } private static void ConfigureEventCounterModuleWithAspNetCounters(IServiceCollection services) { - services.ConfigureTelemetryModule((eventCounterModule, options) => - { - // Ref this code for actual names. https://github.com/aspnet/AspNetCore/blob/f3f9a1cdbcd06b298035b523732b9f45b1408461/src/Hosting/Hosting/src/Internal/HostingEventSource.cs - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "requests-per-second"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "total-requests"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "current-requests"); - AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "failed-requests"); - }); + services.ConfigureTelemetryModule((eventCounterModule, options) => + { + if (options.EnableEventCounterCollectionModule) + { + // Ref this code for actual names. https://github.com/aspnet/AspNetCore/blob/f3f9a1cdbcd06b298035b523732b9f45b1408461/src/Hosting/Hosting/src/Internal/HostingEventSource.cs + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "requests-per-second"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "total-requests"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "current-requests"); + AddEventCounterIfNotExist(eventCounterModule, EventSourceNameForAspNetCoreHosting, "failed-requests"); + } + }); } #endif + private static void ConfigureAiServiceOption(IServiceCollection services, ApplicationInsightsServiceOptions options) + { + services.Configure((ApplicationInsightsServiceOptions o) => + { + if (options.DeveloperMode != null) + { + o.DeveloperMode = options.DeveloperMode; + } + + if (!string.IsNullOrEmpty(options.EndpointAddress)) + { + o.EndpointAddress = options.EndpointAddress; + } + + if (!string.IsNullOrEmpty(options.InstrumentationKey)) + { + o.InstrumentationKey = options.InstrumentationKey; + } + + o.ApplicationVersion = options.ApplicationVersion; + o.EnableAdaptiveSampling = options.EnableAdaptiveSampling; + o.EnableDebugLogger = options.EnableDebugLogger; + o.EnableQuickPulseMetricStream = options.EnableQuickPulseMetricStream; + o.EnableHeartbeat = options.EnableHeartbeat; + o.AddAutoCollectedMetricExtractor = options.AddAutoCollectedMetricExtractor; + o.EnablePerformanceCounterCollectionModule = options.EnablePerformanceCounterCollectionModule; + o.EnableDependencyTrackingTelemetryModule = options.EnableDependencyTrackingTelemetryModule; + o.EnableAppServicesHeartbeatTelemetryModule = options.EnableAppServicesHeartbeatTelemetryModule; + o.EnableAzureInstanceMetadataTelemetryModule = options.EnableAzureInstanceMetadataTelemetryModule; +#if NETSTANDARD2_0 + o.EnableEventCounterCollectionModule = options.EnableEventCounterCollectionModule; +#endif +#if AI_ASPNETCORE_WEB + o.EnableAuthenticationTrackingJavaScript = options.EnableAuthenticationTrackingJavaScript; + o.EnableRequestTrackingTelemetryModule = options.EnableRequestTrackingTelemetryModule; +#endif + }); + } + private static void AddApplicationInsightsLoggerProvider(IServiceCollection services) { #if NETSTANDARD2_0 diff --git a/src/Shared/Extensions/ApplicationInsightsServiceOptions.cs b/src/Shared/Extensions/ApplicationInsightsServiceOptions.cs index ac9d81ea..94eb0a23 100644 --- a/src/Shared/Extensions/ApplicationInsightsServiceOptions.cs +++ b/src/Shared/Extensions/ApplicationInsightsServiceOptions.cs @@ -18,15 +18,24 @@ public class ApplicationInsightsServiceOptions /// public ApplicationInsightsServiceOptions() { + this.EnablePerformanceCounterCollectionModule = true; this.EnableQuickPulseMetricStream = true; this.EnableAdaptiveSampling = true; - this.EnableDebugLogger = true; - this.EnableAuthenticationTrackingJavaScript = false; + this.EnableDebugLogger = true; this.EnableHeartbeat = true; this.AddAutoCollectedMetricExtractor = true; #if AI_ASPNETCORE_WEB + this.EnableRequestTrackingTelemetryModule = true; + this.EnableAuthenticationTrackingJavaScript = false; this.RequestCollectionOptions = new RequestCollectionOptions(); #endif + +#if NETSTANDARD2_0 + this.EnableEventCounterCollectionModule = true; +#endif + this.EnableDependencyTrackingTelemetryModule = true; + this.EnableAzureInstanceMetadataTelemetryModule = true; + this.EnableAppServicesHeartbeatTelemetryModule = true; this.DependencyCollectionOptions = new DependencyCollectionOptions(); this.ApplicationVersion = Assembly.GetEntryAssembly()?.GetName().Version.ToString(); } @@ -37,6 +46,38 @@ public ApplicationInsightsServiceOptions() /// public bool EnableQuickPulseMetricStream { get; set; } + /// + /// Gets or sets a value indicating whether PerformanceCollectorModule should be enabled. + /// Defaults to true. + /// + public bool EnablePerformanceCounterCollectionModule { get; set; } + + /// + /// Gets or sets a value indicating whether AppServicesHeartbeatTelemetryModule should be enabled. + /// Defaults to true. + /// + public bool EnableAppServicesHeartbeatTelemetryModule { get; set; } + + /// + /// Gets or sets a value indicating whether AzureInstanceMetadataTelemetryModule should be enabled. + /// Defaults to true. + /// + public bool EnableAzureInstanceMetadataTelemetryModule { get; set; } + + /// + /// Gets or sets a value indicating whether DependencyTrackingTelemetryModule should be enabled. + /// Defaults to true. + /// + public bool EnableDependencyTrackingTelemetryModule { get; set; } + +#if NETSTANDARD2_0 + /// + /// Gets or sets a value indicating whether EventCounterCollectionModule should be enabled. + /// Defaults to true. + /// + public bool EnableEventCounterCollectionModule { get; set; } +#endif + /// /// Gets or sets a value indicating whether telemetry processor that controls sampling is added to the service. /// Setting EnableAdaptiveSampling to false, will disable the default adaptive sampling feature. Defaults to true. @@ -66,13 +107,7 @@ public ApplicationInsightsServiceOptions() /// /// Gets or sets a value indicating whether a logger would be registered automatically in debug mode. /// - public bool EnableDebugLogger { get; set; } - - /// - /// Gets or sets a value indicating whether a JavaScript snippet to track the current authenticated user should - /// be printed along with the main ApplicationInsights tracking script. - /// - public bool EnableAuthenticationTrackingJavaScript { get; set; } + public bool EnableDebugLogger { get; set; } /// /// Gets or sets a value indicating whether heartbeats are enabled. @@ -89,6 +124,18 @@ public ApplicationInsightsServiceOptions() /// Gets that allow to manage /// public RequestCollectionOptions RequestCollectionOptions { get; } + + /// + /// Gets or sets a value indicating whether RequestTrackingTelemetryModule should be enabled. + /// Defaults to true. + /// + public bool EnableRequestTrackingTelemetryModule { get; set; } + + /// + /// Gets or sets a value indicating whether a JavaScript snippet to track the current authenticated user should + /// be printed along with the main ApplicationInsights tracking script. + /// + public bool EnableAuthenticationTrackingJavaScript { get; set; } #endif diff --git a/src/Shared/Implementation/NoOpTelemetryModule.cs b/src/Shared/Implementation/NoOpTelemetryModule.cs new file mode 100644 index 00000000..42afa273 --- /dev/null +++ b/src/Shared/Implementation/NoOpTelemetryModule.cs @@ -0,0 +1,17 @@ +using Microsoft.ApplicationInsights.Extensibility; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Shared.Implementation +{ + /// + /// No-op telemetry module that is added instead of actual one, when the actual module is disabled + /// + internal class NoOpTelemetryModule : ITelemetryModule + { + public void Initialize(TelemetryConfiguration configuration) + { + } + } +} diff --git a/src/Shared/Shared.projitems b/src/Shared/Shared.projitems index 2bc37416..e8f1db50 100644 --- a/src/Shared/Shared.projitems +++ b/src/Shared/Shared.projitems @@ -14,6 +14,7 @@ + diff --git a/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs b/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs index 3f7ab1e1..c2e50214 100644 --- a/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs +++ b/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs @@ -334,6 +334,39 @@ public static void AddApplicationInsightsTelemetryDoesNotReadInstrumentationKeyF } } + /// + /// Validates that while using services.AddApplicationInsightsTelemetry(ApplicationInsightsServiceOptions), with null ikey + /// and endpoint, ikey and endpoint from AppSettings.Json is NOT overwritten with the null/empty ones from + /// ApplicationInsightsServiceOptions + /// + [Fact] + public static void AddApplicationInsightsTelemetryDoesNotOverrideEmptyInstrumentationKeyFromAiOptions() + { + // Create new options, which will be default have null ikey and endpoint. + var options = new ApplicationInsightsServiceOptions(); + string ikey = Guid.NewGuid().ToString(); + string text = File.ReadAllText("appsettings.json"); + try + { + text = text.Replace("ikeyhere", ikey); + text = text.Replace("hosthere", "newhost"); + File.WriteAllText("appsettings.json", text); + + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + services.AddApplicationInsightsTelemetry(options); + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); + Assert.Equal(ikey, telemetryConfiguration.InstrumentationKey); + Assert.Equal("http://newhost/v2/track/", telemetryConfiguration.DefaultTelemetrySink.TelemetryChannel.EndpointAddress); + } + finally + { + text = text.Replace(ikey, "ikeyhere"); + text = text.Replace("newhost", "hosthere"); + File.WriteAllText("appsettings.json", text); + } + } + [Fact] public static void RegistersTelemetryConfigurationFactoryMethodThatReadsDeveloperModeFromEnvironment() { @@ -498,29 +531,28 @@ public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesItWi Assert.Equal(6, modules.Count()); #endif - - var perfCounterModule = services.FirstOrDefault(t => t.ImplementationType == typeof(PerformanceCollectorModule)); + var perfCounterModule = modules.OfType().Single(); Assert.NotNull(perfCounterModule); #if NETCOREAPP2_0 - var eventCounterModule = services.FirstOrDefault(t => t.ImplementationType == typeof(EventCounterCollectionModule)); + var eventCounterModule = modules.OfType().Single(); Assert.NotNull(eventCounterModule); #endif - var dependencyModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(DependencyTrackingTelemetryModule)); + var dependencyModuleDescriptor = modules.OfType().Single(); Assert.NotNull(dependencyModuleDescriptor); - var reqModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(RequestTrackingTelemetryModule)); + var reqModuleDescriptor = modules.OfType().Single(); Assert.NotNull(reqModuleDescriptor); - var appServiceHeartBeatModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(AppServicesHeartbeatTelemetryModule)); + var appServiceHeartBeatModuleDescriptor = modules.OfType().Single(); Assert.NotNull(appServiceHeartBeatModuleDescriptor); - var azureMetadataHeartBeatModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(AzureInstanceMetadataTelemetryModule)); + var azureMetadataHeartBeatModuleDescriptor = modules.OfType().Single(); Assert.NotNull(azureMetadataHeartBeatModuleDescriptor); - var quickPulseModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(QuickPulseTelemetryModule)); + var quickPulseModuleDescriptor = modules.OfType().Single(); Assert.NotNull(quickPulseModuleDescriptor); } @@ -557,6 +589,113 @@ public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesEven } #endif + [Fact] + public static void UserCanDisablePerfCollectorModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnablePerformanceCounterCollectionModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } + +#if NETCOREAPP2_0 + [Fact] + public static void UserCanDisableEventCounterCollectorModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnableEventCounterCollectionModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } +#endif + + [Fact] + public static void UserCanDisableRequestCounterCollectorModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnableRequestTrackingTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } + + [Fact] + public static void UserCanDisableDependencyCollectorModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnableDependencyTrackingTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } + + [Fact] + public static void UserCanDisableQuickPulseCollectorModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnableQuickPulseMetricStream = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } + + [Fact] + public static void UserCanDisableAppServiceHeartbeatModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnableAppServicesHeartbeatTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } + + [Fact] + public static void UserCanDisableAzureInstanceMetadataModule() + { + var services = ApplicationInsightsExtensionsTests.GetServiceCollectionWithContextAccessor(); + var aiOptions = new ApplicationInsightsServiceOptions(); + aiOptions.EnableAzureInstanceMetadataTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var modules = serviceProvider.GetServices(); + Assert.NotNull(modules); + + Assert.Empty(modules.OfType()); + } + [Fact] public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesDependencyCollectorWithDefaultValues() { diff --git a/test/WebApi20.FunctionalTests/FunctionalTest/RequestCorrelationTests.cs b/test/WebApi20.FunctionalTests/FunctionalTest/RequestCorrelationTests.cs index afef7fb7..3f9f2c9a 100644 --- a/test/WebApi20.FunctionalTests/FunctionalTest/RequestCorrelationTests.cs +++ b/test/WebApi20.FunctionalTests/FunctionalTest/RequestCorrelationTests.cs @@ -12,6 +12,7 @@ using System.Linq; using Microsoft.ApplicationInsights.DependencyCollector; using System.Text.RegularExpressions; + using Microsoft.ApplicationInsights.AspNetCore.Extensions; public class RequestCorrelationTests : TelemetryTestsBase { @@ -27,9 +28,10 @@ IWebHostBuilder Config(IWebHostBuilder builder) { return builder.ConfigureServices(services => { - services.AddApplicationInsightsTelemetry(); + var aiOptions = new ApplicationInsightsServiceOptions(); // disable Dependency tracking (i.e. header injection) - services.Remove(services.FirstOrDefault(sd => sd.ImplementationType == typeof(DependencyTrackingTelemetryModule))); + aiOptions.EnableDependencyTrackingTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); }); } @@ -65,9 +67,10 @@ IWebHostBuilder Config(IWebHostBuilder builder) { return builder.ConfigureServices(services => { - services.AddApplicationInsightsTelemetry(); + var aiOptions = new ApplicationInsightsServiceOptions(); // disable Dependency tracking (i.e. header injection) - services.Remove(services.FirstOrDefault(sd => sd.ImplementationType == typeof(DependencyTrackingTelemetryModule))); + aiOptions.EnableDependencyTrackingTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); }); } @@ -105,9 +108,10 @@ IWebHostBuilder Config(IWebHostBuilder builder) { return builder.ConfigureServices(services => { - services.AddApplicationInsightsTelemetry(); + var aiOptions = new ApplicationInsightsServiceOptions(); // disable Dependency tracking (i.e. header injection) - services.Remove(services.FirstOrDefault(sd => sd.ImplementationType == typeof(DependencyTrackingTelemetryModule))); + aiOptions.EnableDependencyTrackingTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); }); } @@ -146,9 +150,10 @@ IWebHostBuilder Config(IWebHostBuilder builder) { return builder.ConfigureServices(services => { - services.AddApplicationInsightsTelemetry(); + var aiOptions = new ApplicationInsightsServiceOptions(); // disable Dependency tracking (i.e. header injection) - services.Remove(services.FirstOrDefault(sd => sd.ImplementationType == typeof(DependencyTrackingTelemetryModule))); + aiOptions.EnableDependencyTrackingTelemetryModule = false; + services.AddApplicationInsightsTelemetry(aiOptions); }); }