Добавление процессора телеметрии Application Insights в функцию Azure - PullRequest
1 голос
/ 09 октября 2019

Я регистрирую пользовательский телеметрический процессор в функции Azure - однако во время запуска клиентский процессор никогда не запускается. Мой код выглядит так:

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);
    }
}

Этот подход прекрасно работает в веб-API. Есть ли обходной путь? Или я что-то упустил?

1 Ответ

1 голос
/ 10 октября 2019

При использовании ITelemetry Processor в azure function, попробуйте следующее руководство:

Сначала установите последнюю версию 3.0.13 пакета nuget в свой проект функции Azure: Microsoft.Azure. WebJobs.Logging.ApplicationInsights .

Затем напишите свою функцию лазури. В моем тесте я создаю лазурную функцию BLOB-триггера v2. А для целей тестирования я просто добавляю пользовательское свойство в телеметрию трассировки (вы можете изменить код в соответствии со своими потребностями). Код выглядит следующим образом:

    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;
                    });
                }
            }
        }
    }

Затем опубликуйте эту функцию Azure на портале Azure -> когда публикация завершится, на портале Azure -> ваша функция Azure -> вкладка «Монитор», добавьте сведения о своем приложении.

Наконец, загрузите BLOB-объект в хранилище BLOB-объектов, затем перейдите к пониманию приложения, и вы увидите, что свойство добавлено в ваши данные телеметрии. Снимок экрана, как показано ниже:

enter image description here

...