private static string GetApplicationId(IApplicationIdProvider applicationIdProvider, string instrumentationKey)
        {
            string currentComponentAppId = null;

            applicationIdProvider?.TryGetApplicationId(instrumentationKey, out currentComponentAppId);
            return(currentComponentAppId);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:HostingDiagnosticListener"/> class.
 /// </summary>
 /// <param name="client"><see cref="TelemetryClient"/> to post traces to.</param>
 /// <param name="applicationIdProvider">Provider for resolving application Id to be used in multiple instruemntation keys scenarios.</param>
 /// <param name="injectResponseHeaders">Flag that indicates that response headers should be injected.</param>
 /// <param name="trackExceptions">Flag that indicates that exceptions should be tracked.</param>
 public HostingDiagnosticListener(TelemetryClient client, IApplicationIdProvider applicationIdProvider, bool injectResponseHeaders, bool trackExceptions)
 {
     this.client = client ?? throw new ArgumentNullException(nameof(client));
     this.applicationIdProvider = applicationIdProvider;
     this.injectResponseHeaders = injectResponseHeaders;
     this.trackExceptions       = trackExceptions;
 }
예제 #3
0
 public void TestInitialize()
 {
     applicationIdProvider = new DictionaryApplicationIdProvider()
     {
         Defined = new Dictionary <string, string>
         {
             { testInstrumentationKey1, testApplicationId1 },
             { testInstrumentationKey2, testApplicationId2 }
         }
     };
 }
 private static string GetApplicationId(IApplicationIdProvider applicationIdProvider)
 {
     try
     {
         return applicationIdProvider.GetApplicationId();
     }
     catch
     {
         return null;
     }
 }
 private static string GetApplicationId(IApplicationIdProvider applicationIdProvider)
 {
     try
     {
         return(applicationIdProvider.GetApplicationId());
     }
     catch
     {
         return(null);
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="HostingDiagnosticListener"/> class.
 /// </summary>
 /// <param name="configuration"><see cref="TelemetryConfiguration"/> as a settings source.</param>
 /// <param name="client"><see cref="TelemetryClient"/> to post traces to.</param>
 /// <param name="applicationIdProvider">Provider for resolving application Id to be used in multiple instruemntation keys scenarios.</param>
 /// <param name="injectResponseHeaders">Flag that indicates that response headers should be injected.</param>
 /// <param name="trackExceptions">Flag that indicates that exceptions should be tracked.</param>
 /// <param name="enableW3CHeaders">Flag that indicates that W3C header parsing should be enabled.</param>
 /// <param name="enableNewDiagnosticEvents">Flag that indicates that new diagnostic events are supported by AspNetCore</param>
 public HostingDiagnosticListener(
     TelemetryConfiguration configuration,
     TelemetryClient client,
     IApplicationIdProvider applicationIdProvider,
     bool injectResponseHeaders,
     bool trackExceptions,
     bool enableW3CHeaders,
     bool enableNewDiagnosticEvents = true)
     : this(client, applicationIdProvider, injectResponseHeaders, trackExceptions, enableW3CHeaders, enableNewDiagnosticEvents)
 {
     this.configuration            = configuration ?? throw new ArgumentNullException(nameof(configuration));
     this.proactiveSamplingEnabled = this.configuration.EvaluateExperimentalFeature(ProactiveSamplingFeatureFlagName);
     this.conditionalAppIdEnabled  = this.configuration.EvaluateExperimentalFeature(ConditionalAppIdFeatureFlagName);
 }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HostingDiagnosticListener"/> class.
 /// </summary>
 /// <param name="client"><see cref="TelemetryClient"/> to post traces to.</param>
 /// <param name="applicationIdProvider">Provider for resolving application Id to be used in multiple instruemntation keys scenarios.</param>
 /// <param name="injectResponseHeaders">Flag that indicates that response headers should be injected.</param>
 /// <param name="trackExceptions">Flag that indicates that exceptions should be tracked.</param>
 /// <param name="enableW3CHeaders">Flag that indicates that W3C header parsing should be enabled.</param>
 /// <param name="aspNetCoreMajorVersion">Major version of AspNetCore.</param>
 public HostingDiagnosticListener(
     TelemetryClient client,
     IApplicationIdProvider applicationIdProvider,
     bool injectResponseHeaders,
     bool trackExceptions,
     bool enableW3CHeaders,
     AspNetCoreMajorVersion aspNetCoreMajorVersion)
 {
     this.aspNetCoreMajorVersion = aspNetCoreMajorVersion;
     this.client = client ?? throw new ArgumentNullException(nameof(client));
     this.applicationIdProvider = applicationIdProvider;
     this.injectResponseHeaders = injectResponseHeaders;
     this.trackExceptions       = trackExceptions;
     this.enableW3CHeaders      = enableW3CHeaders;
     AspNetCoreEventSource.Instance.HostingListenerInformational(this.aspNetCoreMajorVersion, "HostingDiagnosticListener constructed.");
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:TelemetryConfigurationOptionsSetup"/> class.
 /// </summary>
 public TelemetryConfigurationOptionsSetup(
     IServiceProvider serviceProvider,
     IOptions <ApplicationInsightsServiceOptions> applicationInsightsServiceOptions,
     IEnumerable <ITelemetryInitializer> initializers,
     IEnumerable <ITelemetryModule> modules,
     IEnumerable <ITelemetryProcessorFactory> telemetryProcessorFactories,
     IEnumerable <ITelemetryModuleConfigurator> telemetryModuleConfigurators)
 {
     this.applicationInsightsServiceOptions = applicationInsightsServiceOptions.Value;
     this.initializers = initializers;
     this.modules      = modules;
     this.telemetryProcessorFactories  = telemetryProcessorFactories;
     this.telemetryModuleConfigurators = telemetryModuleConfigurators;
     this.telemetryChannel             = serviceProvider.GetService <ITelemetryChannel>();
     this.applicationIdProvider        = serviceProvider.GetService <IApplicationIdProvider>();
 }
예제 #9
0
 /// <summary>
 /// This will check the ApplicationIdProvider and attempt to set the endpoint.
 /// This only supports our first party providers <see cref="ApplicationInsightsApplicationIdProvider"/> and <see cref="DictionaryApplicationIdProvider"/>.
 /// </summary>
 /// <param name="applicationIdProvider">ApplicationIdProvider to set.</param>
 /// <param name="endpoint">Endpoint value to set.</param>
 /// <param name="force">When the ConnectionString is set, ApplicationId Endpoint should be forced to update. If the ApplicationId has been set separately, we will only set endpoint if it is null.</param>
 private static void SetApplicationIdEndpoint(IApplicationIdProvider applicationIdProvider, string endpoint, bool force = false)
 {
     if (applicationIdProvider != null)
     {
         if (applicationIdProvider is ApplicationInsightsApplicationIdProvider applicationInsightsApplicationIdProvider)
         {
             if (force || applicationInsightsApplicationIdProvider.ProfileQueryEndpoint == null)
             {
                 applicationInsightsApplicationIdProvider.ProfileQueryEndpoint = endpoint;
             }
         }
         else if (applicationIdProvider is DictionaryApplicationIdProvider dictionaryApplicationIdProvider)
         {
             if (dictionaryApplicationIdProvider.Next is ApplicationInsightsApplicationIdProvider innerApplicationIdProvider)
             {
                 if (force || innerApplicationIdProvider.ProfileQueryEndpoint == null)
                 {
                     innerApplicationIdProvider.ProfileQueryEndpoint = endpoint;
                 }
             }
         }
     }
 }
예제 #10
0
        public static IServiceCollection AddApplicationInsights(this IServiceCollection services)
        {
            // Bind to the configuration section registered with
            services.AddOptions <ApplicationInsightsLoggerOptions>()
            .Configure <ILoggerProviderConfiguration <ApplicationInsightsLoggerProvider> >((options, config) =>
            {
                config.Configuration?.Bind(options);
            });

            services.AddSingleton <ITelemetryInitializer, HttpDependenciesParsingTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsRoleEnvironmentTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsSanitizingInitializer>();
            services.AddSingleton <ITelemetryModule, QuickPulseTelemetryModule>();

            services.AddSingleton <IApplicationIdProvider, ApplicationInsightsApplicationIdProvider>();

            services.AddSingleton <ITelemetryModule, DependencyTrackingTelemetryModule>(provider =>
            {
                var dependencyCollector = new DependencyTrackingTelemetryModule();
                var excludedDomains     = dependencyCollector.ExcludeComponentCorrelationHttpHeadersOnDomains;
                excludedDomains.Add("core.windows.net");
                excludedDomains.Add("core.chinacloudapi.cn");
                excludedDomains.Add("core.cloudapi.de");
                excludedDomains.Add("core.usgovcloudapi.net");
                excludedDomains.Add("localhost");
                excludedDomains.Add("127.0.0.1");

                var includedActivities = dependencyCollector.IncludeDiagnosticSourceActivities;
                includedActivities.Add("Microsoft.Azure.ServiceBus");

                return(dependencyCollector);
            });
            services.AddSingleton <ITelemetryModule, AppServicesHeartbeatTelemetryModule>();

            services.AddSingleton <ITelemetryChannel, ServerTelemetryChannel>();
            services.AddSingleton <TelemetryConfiguration>(provider =>
            {
                ApplicationInsightsLoggerOptions options = provider.GetService <IOptions <ApplicationInsightsLoggerOptions> >().Value;
                LoggerFilterOptions filterOptions        = CreateFilterOptions(provider.GetService <IOptions <LoggerFilterOptions> >().Value);

                ITelemetryChannel channel     = provider.GetService <ITelemetryChannel>();
                TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();

                IApplicationIdProvider appIdProvider = provider.GetService <IApplicationIdProvider>();

                SetupTelemetryConfiguration(
                    config,
                    options.InstrumentationKey,
                    options.SamplingSettings,
                    options.SnapshotConfiguration,
                    channel,
                    provider.GetServices <ITelemetryInitializer>(),
                    provider.GetServices <ITelemetryModule>(),
                    appIdProvider,
                    filterOptions);

                return(config);
            });

            services.AddSingleton <TelemetryClient>(provider =>
            {
                TelemetryConfiguration configuration = provider.GetService <TelemetryConfiguration>();
                TelemetryClient client = new TelemetryClient(configuration);

                string assemblyVersion = GetAssemblyFileVersion(typeof(JobHost).Assembly);
                client.Context.GetInternalContext().SdkVersion = $"webjobs: {assemblyVersion}";

                return(client);
            });

            services.AddSingleton <ILoggerProvider, ApplicationInsightsLoggerProvider>();

            return(services);
        }
예제 #11
0
        private static void SetupTelemetryConfiguration(
            TelemetryConfiguration configuration,
            string instrumentationKey,
            SamplingPercentageEstimatorSettings samplingSettings,
            SnapshotCollectorConfiguration snapshotCollectorConfiguration,
            ITelemetryChannel channel,
            IEnumerable <ITelemetryInitializer> telemetryInitializers,
            IEnumerable <ITelemetryModule> telemetryModules,
            IApplicationIdProvider applicationIdProvider,
            LoggerFilterOptions filterOptions)
        {
            if (instrumentationKey != null)
            {
                configuration.InstrumentationKey = instrumentationKey;

                // Because of https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/943
                // we have to touch (and create) Active configuration before initializing telemetry modules
                TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
            }

            configuration.TelemetryChannel = channel;

            foreach (ITelemetryInitializer initializer in telemetryInitializers)
            {
                configuration.TelemetryInitializers.Add(initializer);
            }

            (channel as ServerTelemetryChannel)?.Initialize(configuration);

            QuickPulseTelemetryModule quickPulseModule = null;

            foreach (ITelemetryModule module in telemetryModules)
            {
                if (module is QuickPulseTelemetryModule telemetryModule)
                {
                    quickPulseModule = telemetryModule;
                }

                module.Initialize(configuration);
            }

            QuickPulseTelemetryProcessor quickPulseProcessor = null;

            configuration.TelemetryProcessorChainBuilder
            .Use((next) =>
            {
                quickPulseProcessor = new QuickPulseTelemetryProcessor(next);
                return(quickPulseProcessor);
            })
            .Use((next) => new FilteringTelemetryProcessor(filterOptions, next));

            if (samplingSettings != null)
            {
                configuration.TelemetryProcessorChainBuilder.Use((next) =>
                                                                 new AdaptiveSamplingTelemetryProcessor(samplingSettings, null, next));
            }

            if (snapshotCollectorConfiguration != null)
            {
                configuration.TelemetryProcessorChainBuilder.UseSnapshotCollector(snapshotCollectorConfiguration);
            }

            configuration.TelemetryProcessorChainBuilder.Build();
            quickPulseModule?.RegisterTelemetryProcessor(quickPulseProcessor);

            foreach (ITelemetryProcessor processor in configuration.TelemetryProcessors)
            {
                if (processor is ITelemetryModule module)
                {
                    module.Initialize(configuration);
                }
            }

            configuration.ApplicationIdProvider = applicationIdProvider;
        }
        /// <summary>Updates requestTelemetry from request with properties, which could be deferred till after sampling.</summary>
        /// <param name="requestTelemetry">RequestTelemetry to be updated.</param>
        /// <param name="request">HttpRequest containing Url and headers.</param>
        /// <param name="applicationIdProvider">Provider for current applicationId.</param>
        internal static void UpdateRequestTelemetryFromRequest(RequestTelemetry requestTelemetry, HttpRequest request, IApplicationIdProvider applicationIdProvider)
        {
            if (requestTelemetry == null || request == null)
            {
                return;
            }

            if (requestTelemetry.Url == null)
            {
                requestTelemetry.Url = request.Unvalidated.Url;
            }

            if (string.IsNullOrEmpty(requestTelemetry.Source))
            {
                var    sourceAppId           = GetSourceAppId(request.Unvalidated.Headers);
                string currentComponentAppId = GetApplicationId(applicationIdProvider, requestTelemetry.Context?.InstrumentationKey);
                // If the source header is present on the incoming request,
                // and it is an external component (not the same ikey as the one used by the current component),
                // then populate the source field.
                if (!string.IsNullOrEmpty(currentComponentAppId) &&
                    !string.IsNullOrEmpty(sourceAppId) &&
                    sourceAppId != currentComponentAppId)
                {
                    requestTelemetry.Source = sourceAppId;
                }
            }
        }
        /// <summary>Updates requestTelemetry from request with properties, which could be deferred till after sampling.</summary>
        /// <param name="requestTelemetry">RequestTelemetry to be updated.</param>
        /// <param name="request">HttpRequest containing Url and headers.</param>
        /// <param name="applicationIdProvider">Provider for current applicationId.</param>
        internal static void UpdateRequestTelemetryFromRequest(RequestTelemetry requestTelemetry, HttpRequest request, IApplicationIdProvider applicationIdProvider)
        {
            if (requestTelemetry == null || request == null)
            {
                return;
            }

            if (requestTelemetry.Url == null)
            {
                try
                {
                    requestTelemetry.Url = request.Unvalidated.Url;
                }
                catch (Exception ex)
                {
                    // "AI (Internal): Unknown error, message System.UriFormatException: Invalid URI: The hostname could not be parsed."
                    // Do nothing here. We cannot force an invalid value into the Uri object.
                    WebEventSource.Log.FailedToSetRequestTelemetryUrl(request.RawUrl, ex.ToInvariantString());
                }
            }

            if (string.IsNullOrEmpty(requestTelemetry.Source))
            {
                var    sourceAppId           = GetSourceAppId(request.Unvalidated.Headers);
                string currentComponentAppId = GetApplicationId(applicationIdProvider, requestTelemetry.Context?.InstrumentationKey);
                // If the source header is present on the incoming request,
                // and it is an external component (not the same ikey as the one used by the current component),
                // then populate the source field.
                if (!string.IsNullOrEmpty(currentComponentAppId) &&
                    !string.IsNullOrEmpty(sourceAppId) &&
                    sourceAppId != currentComponentAppId)
                {
                    requestTelemetry.Source = sourceAppId;
                }
            }
        }
예제 #14
0
        public static IServiceCollection AddApplicationInsights(this IServiceCollection services)
        {
            services.TryAddSingleton <ISdkVersionProvider, WebJobsSdkVersionProvider>();

            // Bind to the configuration section registered with
            services.AddOptions <ApplicationInsightsLoggerOptions>()
            .Configure <ILoggerProviderConfiguration <ApplicationInsightsLoggerProvider> >((options, config) =>
            {
                config.Configuration?.Bind(options);
            });

            services.AddSingleton <ITelemetryInitializer, HttpDependenciesParsingTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsRoleEnvironmentTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsSanitizingInitializer>();
            services.AddSingleton <ITelemetryModule, QuickPulseTelemetryModule>();

            services.AddSingleton <IApplicationIdProvider, ApplicationInsightsApplicationIdProvider>();

            services.AddSingleton <ITelemetryModule, DependencyTrackingTelemetryModule>(provider =>
            {
                var dependencyCollector = new DependencyTrackingTelemetryModule();
                var excludedDomains     = dependencyCollector.ExcludeComponentCorrelationHttpHeadersOnDomains;
                excludedDomains.Add("core.windows.net");
                excludedDomains.Add("core.chinacloudapi.cn");
                excludedDomains.Add("core.cloudapi.de");
                excludedDomains.Add("core.usgovcloudapi.net");
                excludedDomains.Add("localhost");
                excludedDomains.Add("127.0.0.1");

                var includedActivities = dependencyCollector.IncludeDiagnosticSourceActivities;
                includedActivities.Add("Microsoft.Azure.ServiceBus");

                return(dependencyCollector);
            });
            services.AddSingleton <ITelemetryModule, AppServicesHeartbeatTelemetryModule>();

            services.AddSingleton <ITelemetryChannel, ServerTelemetryChannel>();
            services.AddSingleton <TelemetryConfiguration>(provider =>
            {
                ApplicationInsightsLoggerOptions options = provider.GetService <IOptions <ApplicationInsightsLoggerOptions> >().Value;
                LoggerFilterOptions filterOptions        = CreateFilterOptions(provider.GetService <IOptions <LoggerFilterOptions> >().Value);

                ITelemetryChannel channel     = provider.GetService <ITelemetryChannel>();
                TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();

                IApplicationIdProvider appIdProvider = provider.GetService <IApplicationIdProvider>();

                // Because of https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/943
                // we have to touch (and create) Active configuration before initializing telemetry modules
                // Active configuration is used to report AppInsights heartbeats
                // role environment telemetry initializer is needed to correlate heartbeats to particular host

                var activeConfig = TelemetryConfiguration.Active;
                if (!string.IsNullOrEmpty(options.InstrumentationKey) &&
                    string.IsNullOrEmpty(activeConfig.InstrumentationKey))
                {
                    activeConfig.InstrumentationKey = options.InstrumentationKey;
                }

                if (!activeConfig.TelemetryInitializers.OfType <WebJobsRoleEnvironmentTelemetryInitializer>().Any())
                {
                    activeConfig.TelemetryInitializers.Add(
                        new WebJobsRoleEnvironmentTelemetryInitializer());
                }

                SetupTelemetryConfiguration(
                    config,
                    options,
                    channel,
                    provider.GetServices <ITelemetryInitializer>(),
                    provider.GetServices <ITelemetryModule>(),
                    appIdProvider,
                    filterOptions);

                return(config);
            });

            services.AddSingleton <TelemetryClient>(provider =>
            {
                TelemetryConfiguration configuration = provider.GetService <TelemetryConfiguration>();
                TelemetryClient client = new TelemetryClient(configuration);

                ISdkVersionProvider versionProvider            = provider.GetService <ISdkVersionProvider>();
                client.Context.GetInternalContext().SdkVersion = versionProvider?.GetSdkVersion();

                return(client);
            });

            services.AddSingleton <ILoggerProvider, ApplicationInsightsLoggerProvider>();

            return(services);
        }
예제 #15
0
        private static void SetupTelemetryConfiguration(
            TelemetryConfiguration configuration,
            ApplicationInsightsLoggerOptions options,
            ITelemetryChannel channel,
            IEnumerable <ITelemetryInitializer> telemetryInitializers,
            IEnumerable <ITelemetryModule> telemetryModules,
            IApplicationIdProvider applicationIdProvider,
            LoggerFilterOptions filterOptions)
        {
            if (options.InstrumentationKey != null)
            {
                configuration.InstrumentationKey = options.InstrumentationKey;
            }

            configuration.TelemetryChannel = channel;

            foreach (ITelemetryInitializer initializer in telemetryInitializers)
            {
                configuration.TelemetryInitializers.Add(initializer);
            }

            (channel as ServerTelemetryChannel)?.Initialize(configuration);

            QuickPulseTelemetryModule quickPulseModule = null;

            foreach (ITelemetryModule module in telemetryModules)
            {
                if (module is QuickPulseTelemetryModule telemetryModule)
                {
                    quickPulseModule = telemetryModule;
                    if (options.QuickPulseAuthenticationApiKey != null)
                    {
                        quickPulseModule.AuthenticationApiKey = options.QuickPulseAuthenticationApiKey;
                    }
                }

                module.Initialize(configuration);
            }

            QuickPulseTelemetryProcessor quickPulseProcessor = null;

            configuration.TelemetryProcessorChainBuilder
            .Use((next) => new OperationFilteringTelemetryProcessor(next))
            .Use((next) =>
            {
                quickPulseProcessor = new QuickPulseTelemetryProcessor(next);
                return(quickPulseProcessor);
            })
            .Use((next) => new FilteringTelemetryProcessor(filterOptions, next));

            if (options.SamplingSettings != null)
            {
                configuration.TelemetryProcessorChainBuilder.Use((next) =>
                                                                 new AdaptiveSamplingTelemetryProcessor(options.SamplingSettings, null, next));
            }

            if (options.SnapshotConfiguration != null)
            {
                configuration.TelemetryProcessorChainBuilder.UseSnapshotCollector(options.SnapshotConfiguration);
            }

            configuration.TelemetryProcessorChainBuilder.Build();
            quickPulseModule?.RegisterTelemetryProcessor(quickPulseProcessor);

            foreach (ITelemetryProcessor processor in configuration.TelemetryProcessors)
            {
                if (processor is ITelemetryModule module)
                {
                    module.Initialize(configuration);
                }
            }

            configuration.ApplicationIdProvider = applicationIdProvider;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="RequestTrackingTelemetryModule"/> class.
 /// </summary>
 /// <param name="applicationIdProvider">Provider to resolve Application Id</param>
 public RequestTrackingTelemetryModule(IApplicationIdProvider applicationIdProvider)
 {
     this.applicationIdProvider = applicationIdProvider;
     this.subscriptions         = new ConcurrentBag <IDisposable>();
 }
예제 #17
0
 /// <summary>
 /// Creates RequestTrackingTelemetryModule.
 /// </summary>
 /// <param name="applicationIdProvider"></param>
 public RequestTrackingTelemetryModule(IApplicationIdProvider applicationIdProvider)
 {
     this.applicationIdProvider = applicationIdProvider;
     this.subscriptions         = new ConcurrentBag <IDisposable>();
     this.diagnosticListeners   = new List <IApplicationInsightDiagnosticListener>();
 }
예제 #18
0
 public static void SetCurrent(IApplicationIdProvider applicationIdProvider)
 {
     _current.Value = applicationIdProvider.GetApplicationId();
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="OperationCorrelationTelemetryInitializer"/> class.
 /// </summary>
 /// <param name="httpContextAccessor">Accessor for retrieving the current HTTP context.</param>
 /// <param name="applicationIdProvider">Nullable Provider for resolving application Id to be used by Correlation.</param>
 public OperationCorrelationTelemetryInitializer(IHttpContextAccessor httpContextAccessor, IApplicationIdProvider applicationIdProvider = null) : base(httpContextAccessor)
 {
     this.applicationIdProvider = applicationIdProvider;
 }
        public static IServiceCollection AddApplicationInsights(this IServiceCollection services)
        {
            services.TryAddSingleton <ISdkVersionProvider, WebJobsSdkVersionProvider>();

            // Bind to the configuration section registered with
            services.AddOptions <ApplicationInsightsLoggerOptions>()
            .Configure <ILoggerProviderConfiguration <ApplicationInsightsLoggerProvider> >((options, config) =>
            {
                config.Configuration?.Bind(options);
            });

            services.AddSingleton <ITelemetryInitializer, HttpDependenciesParsingTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsRoleEnvironmentTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsSanitizingInitializer>();
            services.AddSingleton <ITelemetryInitializer, WebJobsTelemetryInitializer>();

            services.AddSingleton <ITelemetryModule, QuickPulseTelemetryModule>();

            services.AddSingleton <ITelemetryModule>(provider =>
            {
                ApplicationInsightsLoggerOptions options = provider.GetService <IOptions <ApplicationInsightsLoggerOptions> >().Value;
                if (options.EnablePerformanceCountersCollection)
                {
                    return(new PerformanceCollectorModule());
                }

                return(NullTelemetryModule.Instance);
            });

            services.AddSingleton <IApplicationIdProvider, ApplicationInsightsApplicationIdProvider>();

            services.AddSingleton <ITelemetryModule, DependencyTrackingTelemetryModule>(provider =>
            {
                var options = provider.GetService <IOptions <ApplicationInsightsLoggerOptions> >().Value;

                var dependencyCollector = new DependencyTrackingTelemetryModule();
                var excludedDomains     = dependencyCollector.ExcludeComponentCorrelationHttpHeadersOnDomains;
                excludedDomains.Add("core.windows.net");
                excludedDomains.Add("core.chinacloudapi.cn");
                excludedDomains.Add("core.cloudapi.de");
                excludedDomains.Add("core.usgovcloudapi.net");
                excludedDomains.Add("localhost");
                excludedDomains.Add("127.0.0.1");

                var includedActivities = dependencyCollector.IncludeDiagnosticSourceActivities;
                includedActivities.Add("Microsoft.Azure.ServiceBus");

                dependencyCollector.EnableW3CHeadersInjection = options.HttpAutoCollectionOptions.EnableW3CDistributedTracing;
                return(dependencyCollector);
            });

            services.AddSingleton <ITelemetryModule>(provider =>
            {
                var options = provider.GetService <IOptions <ApplicationInsightsLoggerOptions> >().Value;
                if (options.HttpAutoCollectionOptions.EnableHttpTriggerExtendedInfoCollection)
                {
                    var appIdProvider = provider.GetService <IApplicationIdProvider>();

                    return(new RequestTrackingTelemetryModule(appIdProvider)
                    {
                        CollectionOptions = new RequestCollectionOptions
                        {
                            TrackExceptions = false, // webjobs/functions track exceptions themselves
                            EnableW3CDistributedTracing = options.HttpAutoCollectionOptions.EnableW3CDistributedTracing,
                            InjectResponseHeaders = options.HttpAutoCollectionOptions.EnableResponseHeaderInjection
                        }
                    });
                }

                return(NullTelemetryModule.Instance);
            });

            services.AddSingleton <ITelemetryModule, AppServicesHeartbeatTelemetryModule>();

            services.AddSingleton <ITelemetryChannel, ServerTelemetryChannel>();
            services.AddSingleton <TelemetryConfiguration>(provider =>
            {
                ApplicationInsightsLoggerOptions options = provider.GetService <IOptions <ApplicationInsightsLoggerOptions> >().Value;
                LoggerFilterOptions filterOptions        = CreateFilterOptions(provider.GetService <IOptions <LoggerFilterOptions> >().Value);

                ITelemetryChannel channel     = provider.GetService <ITelemetryChannel>();
                TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();

                IApplicationIdProvider appIdProvider   = provider.GetService <IApplicationIdProvider>();
                ISdkVersionProvider sdkVersionProvider = provider.GetService <ISdkVersionProvider>();
                // Because of https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/943
                // we have to touch (and create) Active configuration before initializing telemetry modules
                // Active configuration is used to report AppInsights heartbeats
                // role environment telemetry initializer is needed to correlate heartbeats to particular host

                var activeConfig = TelemetryConfiguration.Active;
                if (!string.IsNullOrEmpty(options.InstrumentationKey) &&
                    string.IsNullOrEmpty(activeConfig.InstrumentationKey))
                {
                    activeConfig.InstrumentationKey = options.InstrumentationKey;
                }

                if (!activeConfig.TelemetryInitializers.OfType <WebJobsRoleEnvironmentTelemetryInitializer>().Any())
                {
                    activeConfig.TelemetryInitializers.Add(new WebJobsRoleEnvironmentTelemetryInitializer());
                    activeConfig.TelemetryInitializers.Add(new WebJobsTelemetryInitializer(sdkVersionProvider));
                    if (options.HttpAutoCollectionOptions.EnableW3CDistributedTracing)
                    {
                        // W3C distributed tracing is enabled by the feature flag inside ApplicationInsights SDK
                        // W3COperationCorrelationTelemetryInitializer will go away once W3C is implemented
                        // in the DiagnosticSource (.NET)

                        TelemetryConfiguration.Active.TelemetryInitializers.Add(new W3COperationCorrelationTelemetryInitializer());
                    }
                }

                SetupTelemetryConfiguration(
                    config,
                    options,
                    channel,
                    provider.GetServices <ITelemetryInitializer>(),
                    provider.GetServices <ITelemetryModule>(),
                    appIdProvider,
                    filterOptions);

                return(config);
            });

            services.AddSingleton <TelemetryClient>(provider =>
            {
                TelemetryConfiguration configuration = provider.GetService <TelemetryConfiguration>();
                TelemetryClient client = new TelemetryClient(configuration);

                ISdkVersionProvider versionProvider            = provider.GetService <ISdkVersionProvider>();
                client.Context.GetInternalContext().SdkVersion = versionProvider?.GetSdkVersion();

                return(client);
            }
                                                    );

            services.AddSingleton <ILoggerProvider, ApplicationInsightsLoggerProvider>();

            return(services);
        }
        private static void SetupTelemetryConfiguration(
            TelemetryConfiguration configuration,
            ApplicationInsightsLoggerOptions options,
            ITelemetryChannel channel,
            IEnumerable <ITelemetryInitializer> telemetryInitializers,
            IEnumerable <ITelemetryModule> telemetryModules,
            IApplicationIdProvider applicationIdProvider,
            LoggerFilterOptions filterOptions)
        {
            if (options.InstrumentationKey != null)
            {
                configuration.InstrumentationKey = options.InstrumentationKey;
            }

            if (options.HttpAutoCollectionOptions.EnableW3CDistributedTracing)
            {
                // W3C distributed tracing is enabled by the feature flag inside ApplicationInsights SDK
                // W3COperationCorrelationTelemetryInitializer will go away once W3C is implemented
                // in the DiagnosticSource (.NET)
                configuration.TelemetryInitializers.Add(new W3COperationCorrelationTelemetryInitializer());
            }

            configuration.TelemetryChannel = channel;

            foreach (ITelemetryInitializer initializer in telemetryInitializers)
            {
                configuration.TelemetryInitializers.Add(initializer);
            }

            (channel as ServerTelemetryChannel)?.Initialize(configuration);

            QuickPulseTelemetryModule quickPulseModule = null;

            foreach (ITelemetryModule module in telemetryModules)
            {
                if (module is QuickPulseTelemetryModule telemetryModule)
                {
                    quickPulseModule = telemetryModule;
                    if (options.QuickPulseAuthenticationApiKey != null)
                    {
                        quickPulseModule.AuthenticationApiKey = options.QuickPulseAuthenticationApiKey;
                    }
                }

                module.Initialize(configuration);
            }

            QuickPulseTelemetryProcessor quickPulseProcessor = null;

            configuration.TelemetryProcessorChainBuilder
            .Use((next) => new OperationFilteringTelemetryProcessor(next))
            .Use((next) =>
            {
                quickPulseProcessor = new QuickPulseTelemetryProcessor(next);
                return(quickPulseProcessor);
            })
            .Use((next) => new FilteringTelemetryProcessor(filterOptions, next));

            if (options.SamplingSettings != null)
            {
                configuration.TelemetryProcessorChainBuilder.Use((next) =>
                                                                 new AdaptiveSamplingTelemetryProcessor(options.SamplingSettings, null, next));
            }

            if (options.SnapshotConfiguration != null)
            {
                configuration.TelemetryProcessorChainBuilder.UseSnapshotCollector(options.SnapshotConfiguration);
            }

            configuration.TelemetryProcessorChainBuilder.Build();
            quickPulseModule?.RegisterTelemetryProcessor(quickPulseProcessor);

            foreach (ITelemetryProcessor processor in configuration.TelemetryProcessors)
            {
                if (processor is ITelemetryModule module)
                {
                    module.Initialize(configuration);
                }
            }

            configuration.ApplicationIdProvider = applicationIdProvider;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:HostingDiagnosticListener"/> class.
 /// </summary>
 /// <param name="client"><see cref="TelemetryClient"/> to post traces to.</param>
 /// <param name="applicationIdProvider">Nullable Provider for resolving application Id to be used by Correlation.</param>
 public HostingDiagnosticListener(TelemetryClient client, IApplicationIdProvider applicationIdProvider = null)
 {
     this.client = client ?? throw new ArgumentNullException(nameof(client));
     this.applicationIdProvider = applicationIdProvider;
 }
예제 #23
0
 public static void SetCurrent(IApplicationIdProvider applicationIdProvider)
 {
     _current.Value = applicationIdProvider.GetApplicationId();
 }