diff --git a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/ApplicationInsightsLoggerOptions.cs b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/ApplicationInsightsLoggerOptions.cs index 49604e673..88f284206 100644 --- a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/ApplicationInsightsLoggerOptions.cs +++ b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/ApplicationInsightsLoggerOptions.cs @@ -69,7 +69,8 @@ public string QuickPulseAuthenticationApiKey /// can result in decreased application startup time. Default value is 15 seconds. /// [Obsolete("Use LiveMetricsInitializationDelay instead.")] - public TimeSpan QuickPulseInitializationDelay { + public TimeSpan QuickPulseInitializationDelay + { get { return LiveMetricsInitializationDelay; @@ -105,6 +106,8 @@ public TimeSpan QuickPulseInitializationDelay { /// public bool EnableDependencyTracking { get; set; } = true; + public DependencyTrackingOptions DependencyTrackingOptions { get; set; } + /// /// Gets or sets HTTP request collection options. /// @@ -159,6 +162,18 @@ public string Format() { nameof(HttpAutoCollectionOptions.EnableResponseHeaderInjection), HttpAutoCollectionOptions.EnableResponseHeaderInjection } }; + JObject dependencyTrackingOptions = new JObject + { + { nameof(DependencyTrackingOptions.DisableRuntimeInstrumentation), DependencyTrackingOptions.DisableRuntimeInstrumentation }, + { nameof(DependencyTrackingOptions.DisableDiagnosticSourceInstrumentation), DependencyTrackingOptions.DisableDiagnosticSourceInstrumentation}, + { nameof(DependencyTrackingOptions.EnableLegacyCorrelationHeadersInjection), DependencyTrackingOptions.EnableLegacyCorrelationHeadersInjection}, + { nameof(DependencyTrackingOptions.EnableRequestIdHeaderInjectionInW3CMode), DependencyTrackingOptions.EnableRequestIdHeaderInjectionInW3CMode}, + { nameof(DependencyTrackingOptions.EnableSqlCommandTextInstrumentation), DependencyTrackingOptions.EnableSqlCommandTextInstrumentation}, + { nameof(DependencyTrackingOptions.SetComponentCorrelationHttpHeaders), DependencyTrackingOptions.SetComponentCorrelationHttpHeaders}, + { nameof(DependencyTrackingOptions.EnableAzureSdkTelemetryListener), DependencyTrackingOptions.EnableAzureSdkTelemetryListener} + }; + + JObject options = new JObject { { nameof(SamplingSettings), sampling }, @@ -169,7 +184,8 @@ public string Format() { nameof(HttpAutoCollectionOptions), httpOptions }, { nameof(LiveMetricsInitializationDelay), LiveMetricsInitializationDelay }, { nameof(EnableLiveMetrics), EnableLiveMetrics }, - { nameof(EnableDependencyTracking), EnableDependencyTracking } + { nameof(EnableDependencyTracking), EnableDependencyTracking }, + { nameof(DependencyTrackingOptions), dependencyTrackingOptions } }; return options.ToString(Formatting.Indented); diff --git a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DependencyTrackingOptions.cs b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DependencyTrackingOptions.cs new file mode 100644 index 000000000..7b7ce30f1 --- /dev/null +++ b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DependencyTrackingOptions.cs @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.Azure.WebJobs.Logging.ApplicationInsights +{ + public class DependencyTrackingOptions + { + /// + /// Gets or sets a value indicating whether to disable runtime instrumentation. + /// + public bool DisableRuntimeInstrumentation { get; set; } + + /// + /// Gets or sets a value indicating whether to disable Http Desktop DiagnosticSource instrumentation. + /// + public bool DisableDiagnosticSourceInstrumentation { get; set; } + + /// + /// Gets or sets a value indicating whether to enable legacy (x-ms*) correlation headers injection. + /// + public bool EnableLegacyCorrelationHeadersInjection { get; set; } + + /// + /// Gets or sets a value indicating whether to enable Request-Id correlation headers injection. + /// + public bool EnableRequestIdHeaderInjectionInW3CMode { get; set; } + + /// + /// Gets or sets a value indicating whether to track the SQL command text in SQL + /// dependencies. + /// + public bool EnableSqlCommandTextInstrumentation { get; set; } + + /// + /// Gets or sets a value indicating whether the correlation headers would be set + /// on outgoing http requests. + /// + public bool SetComponentCorrelationHttpHeaders { get; set; } + + /// + /// Gets or sets a value indicating whether telemetry would be produced for Azure + /// SDK methods calls and requests. + /// + public bool EnableAzureSdkTelemetryListener { get; set; } + } +} diff --git a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/Extensions/ApplicationInsightsServiceCollectionExtensions.cs b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/Extensions/ApplicationInsightsServiceCollectionExtensions.cs index 7cc91d84a..208cdfbbd 100644 --- a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/Extensions/ApplicationInsightsServiceCollectionExtensions.cs +++ b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/Extensions/ApplicationInsightsServiceCollectionExtensions.cs @@ -108,9 +108,10 @@ public static IServiceCollection AddApplicationInsights(this IServiceCollection { var options = provider.GetService>().Value; + DependencyTrackingTelemetryModule dependencyCollector = null; if (options.EnableDependencyTracking) { - var dependencyCollector = new DependencyTrackingTelemetryModule(); + dependencyCollector = new DependencyTrackingTelemetryModule(); var excludedDomains = dependencyCollector.ExcludeComponentCorrelationHttpHeadersOnDomains; excludedDomains.Add("core.windows.net"); excludedDomains.Add("core.chinacloudapi.cn"); @@ -123,6 +124,17 @@ public static IServiceCollection AddApplicationInsights(this IServiceCollection includedActivities.Add("Microsoft.Azure.ServiceBus"); includedActivities.Add("Microsoft.Azure.EventHubs"); + if (options.DependencyTrackingOptions != null) + { + dependencyCollector.DisableRuntimeInstrumentation = options.DependencyTrackingOptions.DisableRuntimeInstrumentation; + dependencyCollector.DisableDiagnosticSourceInstrumentation = options.DependencyTrackingOptions.DisableDiagnosticSourceInstrumentation; + dependencyCollector.EnableLegacyCorrelationHeadersInjection = options.DependencyTrackingOptions.EnableLegacyCorrelationHeadersInjection; + dependencyCollector.EnableRequestIdHeaderInjectionInW3CMode = options.DependencyTrackingOptions.EnableRequestIdHeaderInjectionInW3CMode; + dependencyCollector.EnableSqlCommandTextInstrumentation = options.DependencyTrackingOptions.EnableSqlCommandTextInstrumentation; + dependencyCollector.SetComponentCorrelationHttpHeaders = options.DependencyTrackingOptions.SetComponentCorrelationHttpHeaders; + dependencyCollector.EnableAzureSdkTelemetryListener = options.DependencyTrackingOptions.EnableAzureSdkTelemetryListener; + } + return dependencyCollector; } diff --git a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsConfigurationTests.cs b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsConfigurationTests.cs index e0c08fbe7..dfccb9932 100644 --- a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsConfigurationTests.cs +++ b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsConfigurationTests.cs @@ -275,7 +275,7 @@ public void DependencyInjectionConfiguration_NoClientIpInitializerWithoutContext public void DependencyInjectionConfiguration_NoClientIpInitializerWithoutExtendedHttpOptions() { using (var host = new HostBuilder() - .ConfigureServices(b => + .ConfigureServices(b => b.AddHttpContextAccessor()) .ConfigureLogging(b => { @@ -296,7 +296,7 @@ public void DependencyInjectionConfiguration_NoClientIpInitializerWithoutExtende public void DependencyInjectionConfiguration_ConfiguresClientIpInitializer() { using (var host = new HostBuilder() - .ConfigureServices(b => + .ConfigureServices(b => b.AddHttpContextAccessor()) .ConfigureLogging(b => { @@ -308,7 +308,7 @@ public void DependencyInjectionConfiguration_ConfiguresClientIpInitializer() .Build()) { var config = host.Services.GetServices().Single(); - + Assert.Contains(config.TelemetryInitializers, ti => ti is ClientIpHeaderTelemetryInitializer); } } @@ -404,6 +404,50 @@ public void DependencyInjectionConfiguration_DisablesDependencyTracking() } } + [Fact] + public void DependencyInjectionConfiguration_EnableSqlCommandTextInstrumentation() + { + using (var host = new HostBuilder() + .ConfigureLogging(b => + { + b.AddApplicationInsights(o => + { + o.InstrumentationKey = "KI"; + o.EnableDependencyTracking = true; + o.DependencyTrackingOptions = new DependencyTrackingOptions() { EnableSqlCommandTextInstrumentation = true }; + }); + }) + .Build()) + { + var modules = host.Services.GetServices(); + var matchingModules = modules.Where(m => m is DependencyTrackingTelemetryModule); + Assert.True(matchingModules.Count() == 1); + + var module = matchingModules.First() as DependencyTrackingTelemetryModule; + Assert.True(module.EnableSqlCommandTextInstrumentation); + } + } + + [Fact] + public void DependencyInjectionConfiguration_SqlCommandTextInstrumentation_DisabledByDefault() + { + using (var host = new HostBuilder() + .ConfigureLogging(b => + { + b.AddApplicationInsights(o => + { + o.InstrumentationKey = "KI"; + o.EnableDependencyTracking = false; + o.DependencyTrackingOptions = new DependencyTrackingOptions() { EnableSqlCommandTextInstrumentation = true }; + }); + }) + .Build()) + { + var modules = host.Services.GetServices(); + Assert.True(modules.Count(m => m is DependencyTrackingTelemetryModule) == 0); + } + } + [Fact] public void DependencyInjectionConfiguration_DisablesQuickPulseTelemetry() { diff --git a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsLoggerTests.cs b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsLoggerTests.cs index 312f0e14a..c2988a0ed 100644 --- a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsLoggerTests.cs +++ b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/ApplicationInsightsLoggerTests.cs @@ -691,6 +691,16 @@ public void ApplicationInsightsLoggerOptions_Format() EnableResponseHeaderInjection = false, EnableW3CDistributedTracing = false, EnableHttpTriggerExtendedInfoCollection = true + }, + DependencyTrackingOptions = new DependencyTrackingOptions() + { + DisableDiagnosticSourceInstrumentation = true, + DisableRuntimeInstrumentation = true, + EnableSqlCommandTextInstrumentation = true, + EnableAzureSdkTelemetryListener = true, + EnableLegacyCorrelationHeadersInjection = true, + EnableRequestIdHeaderInjectionInW3CMode = true, + SetComponentCorrelationHttpHeaders = true } }; @@ -726,6 +736,14 @@ public void ApplicationInsightsLoggerOptions_Format() Assert.Equal(options.SnapshotConfiguration.SnapshotsPerTenMinutesLimit, deserializedOptions.SnapshotConfiguration.SnapshotsPerTenMinutesLimit); Assert.Equal(options.SnapshotConfiguration.TempFolder, deserializedOptions.SnapshotConfiguration.TempFolder); Assert.Equal(options.SnapshotConfiguration.ThresholdForSnapshotting, deserializedOptions.SnapshotConfiguration.ThresholdForSnapshotting); + + Assert.Equal(options.DependencyTrackingOptions.SetComponentCorrelationHttpHeaders, deserializedOptions.DependencyTrackingOptions.SetComponentCorrelationHttpHeaders); + Assert.Equal(options.DependencyTrackingOptions.DisableDiagnosticSourceInstrumentation, deserializedOptions.DependencyTrackingOptions.DisableDiagnosticSourceInstrumentation); + Assert.Equal(options.DependencyTrackingOptions.DisableRuntimeInstrumentation, deserializedOptions.DependencyTrackingOptions.DisableRuntimeInstrumentation); + Assert.Equal(options.DependencyTrackingOptions.EnableAzureSdkTelemetryListener, deserializedOptions.DependencyTrackingOptions.EnableAzureSdkTelemetryListener); + Assert.Equal(options.DependencyTrackingOptions.EnableLegacyCorrelationHeadersInjection, deserializedOptions.DependencyTrackingOptions.EnableLegacyCorrelationHeadersInjection); + Assert.Equal(options.DependencyTrackingOptions.EnableRequestIdHeaderInjectionInW3CMode, deserializedOptions.DependencyTrackingOptions.EnableRequestIdHeaderInjectionInW3CMode); + Assert.Equal(options.DependencyTrackingOptions.EnableSqlCommandTextInstrumentation, deserializedOptions.DependencyTrackingOptions.EnableSqlCommandTextInstrumentation); } [Fact]