MicrosoftDocs / azure-docs

Open source documentation of Microsoft Azure
https://docs.microsoft.com/azure
Creative Commons Attribution 4.0 International
10.21k stars 21.37k forks source link

Dependency Tracking Telemetry with App Insights #25015

Open batizar opened 5 years ago

batizar commented 5 years ago

Can't find any documentations on how to add dependency tracking and other telemetries by App Insights when I use webjob 3 .netcore.

Since applicationinsights.config cannot be used in .netcore and AddApplicationInsightsTelemetry doesn't exist like ASP.NET Core, and not really sure how to use what is explained here (https://docs.microsoft.com/en-us/azure/azure-monitor/app/console) in webjob hostbuilder code. Please help.

Cheers.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

batizar commented 5 years ago

Fixed my issue like this but I don't like how it looks. Using AutoFac and Serilog. Please advice if there is a cleaner or easier way to do this.

private static DependencyTrackingTelemetryModule InitializeDependencyTracking()
{
    var appInsightsKey = Configuration.GetValue<string>("APPINSIGHTS_INSTRUMENTATIONKEY");

    var configuration = TelemetryConfiguration.Active;

    configuration.InstrumentationKey = appInsightsKey;
    configuration.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
    configuration.TelemetryInitializers.Add(new HttpDependenciesParsingTelemetryInitializer());
    configuration.TelemetryInitializers.Add(new HttpDependenciesParsingTelemetryInitializer());

    var module = new DependencyTrackingTelemetryModule();

    // prevent Correlation Id to be sent to certain endpoints. You may add other domains as needed.
    module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("core.windows.net");
    module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("core.chinacloudapi.cn");
    module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("core.cloudapi.de");
    module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("core.usgovcloudapi.net");
    module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("localhost");
    module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("127.0.0.1");

    // enable known dependency tracking, note that in future versions, we will extend this list. 
    // please check default settings in https://github.com/Microsoft/ApplicationInsights-dotnet-server/blob/develop/Src/DependencyCollector/DependencyCollector/ApplicationInsights.config.install.xdt

    module.IncludeDiagnosticSourceActivities.Add("Microsoft.Azure.ServiceBus");
    module.IncludeDiagnosticSourceActivities.Add("Microsoft.Azure.EventHubs");

    // initialize the module
    module.Initialize(configuration);

    return module;
}
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
    builder.RegisterLogger();
    …
    builder.RegisterInstance(InitializeDependencyTracking()).As<DependencyTrackingTelemetryModule>().SingleInstance();
    …
    builder.Register(c => new CallLogger(Log.Logger));
})
.UseSerilog((hostContext, loggerConfig) =>
{
    var appInsightsKey = Configuration.GetValue<string>("APPINSIGHTS_INSTRUMENTATIONKEY");

    loggerConfig.ReadFrom.Configuration(Configuration)
        .Enrich.FromLogContext()
        .WriteTo.Console(theme: AnsiConsoleTheme.Code);

    if (appInsightsKey != null)
    {
        var telemetryClient = new TelemetryClient();
        telemetryClient.InstrumentationKey = appInsightsKey;
        loggerConfig.WriteTo.ApplicationInsightsTraces(telemetryClient);
    }
})
try
{
    var host = hostBuilder.Build();
    using (host)
    {
        Log.Information("Starting host");
        await host.RunAsync();
    }
}
catch (Exception ex)
{
    Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();

    await Task.Delay(5000);
}

Thanks.

Grace-MacJones-MSFT commented 5 years ago

Hi @batizar, thanks for bringing this to our attention. Your feedback has been shared with the content owner for further review.

ggailey777 commented 5 years ago

@batizar we have some additional DI information here. @brettsam, in case we have better guidance for this scenario.

brettsam commented 5 years ago

We should create more of a TelemetryClientFactory that makes it easier to tweak things like this. Will discuss with @lmolkova and see what we can do. It looks like in this case, @batizar wants to swap out the DependencyTrackingTelemetryModule we register here and instead use a customized one.

batizar commented 5 years ago

@ggailey777 not really sure how to convert InitializeDependencyTracking code to CustomTelemetryInitializer, any ideas around that? thanks.

batizar commented 5 years ago

@brettsam from what I see yours is missing module.IncludeDiagnosticSourceActivities.Add("Microsoft.Azure.EventHubs"); as well as configuration.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer()); and configuration.TelemetryInitializers.Add(new HttpDependenciesParsingTelemetryInitializer());. not really sure if they are of any importance.

CraigGraw commented 5 years ago

What is the recommended way to configure a WebJob v3 to log dependencies e.g. CosmosDB, Blob Storage, HttpClient etc...? The documentation appears to be missing a comprehensive way forward for this explicit requirement.

batizar commented 4 years ago

I ended up changing how I was doing this to use AddApplicationInsightsWebJobs like this with Autofac and Serilog. Please let me know if there is any better way to get TelemetryConfiguration because I don't really like building service provider just to get it.

.ConfigureLogging((hostContext, logBuilder) =>
{
    var appInsightsKey = hostContext.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
    if (!string.IsNullOrEmpty(appInsightsKey))
    {
        logBuilder.AddApplicationInsightsWebJobs(o => o.InstrumentationKey = appInsightsKey);
    }
})
.ConfigureServices((hostContext, services) =>
{
    services.AddOptions();
    services.Configure<AppConfig>(_configuration.GetSection("AppConfig"));

    services.AddSingleton(typeof(ITelemetryChannel), new ServerTelemetryChannel
    {
        StorageFolder = GetTelemetryDirectoryPath(hostContext.HostingEnvironment.ContentRootPath)
    });
    services.AddSingleton(typeof(ITelemetryInitializer), new CloudRoleNameTelemetryInitializer(GetCloudRoleName()));
    services.AddSingleton(typeof(ITelemetryInitializer), new VersionTelemetryInitializer());
    services.AddApplicationInsightsKubernetesEnricher();    

    var serviceProvider = services.BuildServiceProvider();
    _telemetryConfig = serviceProvider.GetService<TelemetryConfiguration>();

    var containerBuilder = new ContainerBuilder();
    containerBuilder.Populate(services);
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>((hostContext, containerBuilder) =>
{
    containerBuilder.RegisterLogger();  
    containerBuilder.RegisterType<Functions>();
})
.UseSerilog((hostContext, loggerConfig) =>
{
    loggerConfig.ReadFrom.Configuration(Configuration)
        .Enrich.FromLogContext()
        .WriteTo.Console(theme: AnsiConsoleTheme.Code);

        if (_telemetryConfig != null)
    {       
        loggerConfig.WriteTo.ApplicationInsights(_telemetryConfig, new CustomTelemetryConverter());
    }
})