Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to correctly add a custom AI telemetry processor #2584

Open
acblksun opened this issue Sep 21, 2020 · 7 comments
Open

How to correctly add a custom AI telemetry processor #2584

acblksun opened this issue Sep 21, 2020 · 7 comments
Assignees
Milestone

Comments

@acblksun
Copy link

Hi there,

We're looking to add a custom AI telemetry processor when using the azure webjobs SDK nuget package
Microsoft.Azure.WebJobs.Logging.ApplicationInsights. We require some filtering for some of the automatically collected telemetry. In this case the telemetry we wish to filter is from Azure table storage. Our App Insights is flooded (and alerts on) 401 failures to table storage items we know might not be there.

We use dotnet core 3.1 for our api as well as webjobs. In the api we have done this in the past using a dependency filter like so:

public void ConfigureServices(IServiceCollection services)
{
	// snip - other service configuration
	
	
	// Add App Insights telemetry
	services.AddApplicationInsightsTelemetry(options =>
	{
		// Instrumentation from "ApplicationInsights:InstrumentationKey"
		options.AddAutoCollectedMetricExtractor = true; // default is true
		options.InstrumentationKey = Configuration.GetValue<string>("ApplicationInsights:InstrumentationKey");
		options.DeveloperMode = Env.IsDevelopment();
	});

	// MyDependencyTelemetryFilter is of type ITelemetryProcessor
	services.AddApplicationInsightsTelemetryProcessor<MyDependencyTelemetryFilter>();
}

Repro steps

For our webjob, we have

var hostBuilder = new HostBuilder()
// other builders skipped
.ConfigureLogging((context, logging) =>
{
	logging
		.AddApplicationInsightsWebJobs(options =>
		{
			options.EnableDependencyTracking = true;
			options.InstrumentationKey = context.Configuration.GetValue<string>("ApplicationInsights:InstrumentationKey");

			// TODO - add ITelemetryProcessor telemetry filter >> here <<
			// logging.Services.AddApplicationInsightsTelemetryProcessor<MyDependencyTelemetryFilter>();

		});
		
	// TODO - add ITelemetryProcessor telemetry filter >> or here <<
	// logging.Services.AddApplicationInsightsTelemetryProcessor<MyDependencyTelemetryFilter>();
}

We have also tried

var hostBuilder = new HostBuilder()
// other builders skipped
.ConfigureServices((context, services) =>
{
	// TODO - add ITelemetryProcessor telemetry filter >> or here <<
	services.AddApplicationInsightsTelemetryProcessor<MyDependencyTelemetryFilter>();
}

Expected behavior

For apps written by using ASP.NET Core or WorkerService, adding a new telemetry processor is done by using the AddApplicationInsightsTelemetryProcessor extension method on IServiceCollection, as shown. This method is called in the ConfigureServices method of your Startup.cs class.

Documented https://docs.microsoft.com/en-us/azure/azure-monitor/app/api-filtering-sampling#create-a-telemetry-processor-c

var hostBuilder = new HostBuilder()
// other builders skipped
.ConfigureServices((context, services) =>
{
	services.AddApplicationInsightsTelemetryProcessor<MyDependencyTelemetryFilter>();
}

Actual behavior

Attempting to add to using services.AddApplicationInsightsTelemetryProcessor<MyDependencyTelemetryFilter>(); does not work and the telemetry filter is unused.

Known workarounds

There are two workarounds

Workaround 1 - using Microsoft.ApplicationInsights.WorkerService

https://docs.microsoft.com/en-us/azure/azure-monitor/app/worker-service

Application Insights is releasing a new SDK, called Microsoft.ApplicationInsights.WorkerService, which is best suited for non-HTTP workloads like messaging, background tasks, console applications etc.

The only time we could get it to work was removing Microsoft.Azure.WebJobs.Logging.ApplicationInsights and replacing it with Microsoft.ApplicationInsights.WorkerService. However it appears the webjobs sdk has a lot of custom filtering that we would prefer not to lose.

Workaround 2 - manual addition to TelemetryProcessorChainBuilder in ConfigureServices

The author of the open issue #2459 which talks about ordering or telemetry processors discusses the following code. I have verified this appears to work, but the author, @digitalfuller, indicates this is not best practice and there's no comments on the issue.

new HostBuilder()
    .ConfigureLogging((context, builder) =>
    {
         builder.AddApplicationInsightsWebJobs(o => 
        {
            o.InstrumentationKey = appInsightsKey;
        }
    }
    .ConfigureServices(services =>
    {
        var sp = services.BuildServiceProvider();
        var tc = sp.GetRequiredService<TelemetryConfiguration>();
        var tpcb = tc.TelemetryProcessorChainBuilder;

        tpcb.Use(next => new MyDependencyTelemetryFilter(next));

        tpcb.Build();
    })

Related information

Provide any related information

@tanujnarula
Copy link

Do we have any resolution for this? We have exact same issue.

@chinwobble
Copy link

We have the same issue too

@sergevm
Copy link

sergevm commented Jan 7, 2021

Bumping into issues too. We migrated a .net framework solution with web jobs to dotnet core with an update of the app insights SDK's. Because of a breaking behaviour in the way the SDK logs stuff since the update, I wanted to see if I can revert things by using a processor. But the processor doesn't trigger. Tried the second fix mentioned above, but it looks like the Request telemetry that I start for the operation does not invoke the processor, while MetricTelemetry etc do.

As for the breaking behaviour, I see in the Azure portal that the request telemetry adds a bunch of custom properties, amongst which the "OperationName" custom property, which is apparently always set to the name of the method.

The method where the request is handled, is actually triggered in the web job with messages on a service bus, and we want to reflect the name of the message in the logging, instead or the generic method name (the method is choosing the handler for the message). So we use a StartOperation call passing in the name of the message, but while the request name is set accordingly, in the custom properties the method name keeps showing as the operation name.

@v-anvari v-anvari self-assigned this Mar 24, 2021
@NickMSW
Copy link

NickMSW commented Apr 12, 2021

We are running into this issue as well. Are there any updates?

@v-anvari
Copy link

Tagging @brettsam for further insights

@wmcainsh
Copy link

Same as above, would be good to get a resolution to this as we are getting swamped with synthetic request log entries since moving to Azure Front Door.

@AkshitaKukreja30
Copy link

AkshitaKukreja30 commented Feb 22, 2024

This solution worked for me :

builder.AddApplicationInsightsWebJobs(
loggerOptionsConfiguration: loggerOptions =>
{
loggerOptions.ConnectionString = configuration["ApplicationInsightsConnectionStringBlackSecret"];
loggerOptions.EnableLiveMetrics = true;
},
additionalTelemetryConfiguration: telemetryConfiguration =>
{
telemetryConfiguration.TelemetryProcessorChainBuilder.Use(next => new SuppressDependencyFilter(next));
telemetryConfiguration.TelemetryProcessorChainBuilder.Build();
}
);

SuppressDependencyFilter is my custom Dependency Filter implementing the interface ITelemetryProcessor with the Business Logic to suppress the unwanted dependencies from Telemetry Processor chaining.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants