Reputation: 303
I am registering a Custom telemetry processor in an azure function - during startup, however, the customer processor is never fired. My code looks like this:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
// ...
builder.Services.AddHttpContextAccessor();
builder.Services.AddApplicationInsightsTelemetryProcessor<CustomTelemetryProcessor>();
// ...
}
}
public class CustomTelemetryProcessor : ITelemetryProcessor
{
private ITelemetryProcessor _next;
private IHttpContextAccessor _httpContextAccessor;
public CustomTelemetryProcessor(ITelemetryProcessor next, IHttpContextAccessor httpContextAccessor)
{
// never gets to here
_next = next;
_httpContextAccessor = httpContextAccessor;
}
public void Process(ITelemetry item)
{
// never gets here
if (item is OperationTelemetry operationTelemetry)
{
// ...
operationTelemetry.Properties.Add("MyCustomProperty", "MyCustomValue");
// ...
}
// Send the item to the next TelemetryProcessor
_next.Process(item);
}
}
This approach works fine in a Web API. Is there a workaround? Or am I missing something?
Upvotes: 3
Views: 7986
Reputation: 29940
When using ITelemetry Processor
in azure function
, please try the guide below:
First, install the latest version 3.0.13
of nuget package in your azure function project: Microsoft.Azure.WebJobs.Logging.ApplicationInsights.
Then write your azure function. In my test, I create a blob trigger azure function v2. And for testing purpose, I just add a custom property to the trace telemetry(you can modify the code to meet your need). The code is as below:
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Linq;
[assembly: WebJobsStartup(typeof(FunctionApp16.MyStartup))]
namespace FunctionApp16
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run([BlobTrigger("samples-workitems/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
}
}
internal class CustomTelemetryProcessor : ITelemetryProcessor
{
private ITelemetryProcessor _next;
private IHttpContextAccessor _httpContextAccessor;
public CustomTelemetryProcessor(ITelemetryProcessor next, IHttpContextAccessor httpContextAccessor)
{
_next = next;
_httpContextAccessor = httpContextAccessor;
}
public void Process(ITelemetry item)
{
//for testing purpose, I just add custom property to trace telemetry, you can modify the code as per your need.
if (item is TraceTelemetry traceTelemetry)
{
// use _httpContextAccessor here...
traceTelemetry.Properties.Add("MyCustomProperty555", "MyCustomValue555");
}
// Send the item to the next TelemetryProcessor
_next.Process(item);
}
}
public class MyStartup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.Services.AddHttpContextAccessor();
var configDescriptor = builder.Services.SingleOrDefault(tc => tc.ServiceType == typeof(TelemetryConfiguration));
if (configDescriptor?.ImplementationFactory != null)
{
var implFactory = configDescriptor.ImplementationFactory;
builder.Services.Remove(configDescriptor);
builder.Services.AddSingleton(provider =>
{
if (implFactory.Invoke(provider) is TelemetryConfiguration config)
{
var newConfig = TelemetryConfiguration.Active;
newConfig.ApplicationIdProvider = config.ApplicationIdProvider;
newConfig.InstrumentationKey = config.InstrumentationKey;
newConfig.TelemetryProcessorChainBuilder.Use(next => new CustomTelemetryProcessor(next, provider.GetRequiredService<IHttpContextAccessor>()));
foreach (var processor in config.TelemetryProcessors)
{
newConfig.TelemetryProcessorChainBuilder.Use(next => processor);
}
var quickPulseProcessor = config.TelemetryProcessors.OfType<QuickPulseTelemetryProcessor>().FirstOrDefault();
if (quickPulseProcessor != null)
{
var quickPulseModule = new QuickPulseTelemetryModule();
quickPulseModule.RegisterTelemetryProcessor(quickPulseProcessor);
newConfig.TelemetryProcessorChainBuilder.Use(next => quickPulseProcessor);
}
newConfig.TelemetryProcessorChainBuilder.Build();
newConfig.TelemetryProcessors.OfType<ITelemetryModule>().ToList().ForEach(module => module.Initialize(newConfig));
return newConfig;
}
return null;
});
}
}
}
}
Then publish this azure function to azure portal -> when publish is completed, in azure portal -> your azure function -> Monitor tab, add your application insights.
At last, upload blob to the blob storage, then nav to application insights, you can see that the property is added in your telemetry data. Screenshot as below:
Upvotes: 4