Фильтрация и предварительная обработка данных телеметрии в пакете SDK для Application Insights

Чтобы настроить способ обогащения и обработки данных телеметрии перед их отправкой в службу Application Insights, можно написать и настроить подключаемые модули для пакета SDK Application Insights.

  • Выборка сокращает объем данных телеметрии, не искажая статистические данные. Благодаря выборке связанные точки данных хранятся вместе, что облегчает навигацию между ними во время диагностики проблемы. На портале общее количество умножается, чтобы компенсировать выборку.
  • Фильтрация с использованием обработчиков данных телеметрии позволяет фильтровать данные телеметрии в пакете SDK перед отправкой на сервер. Например, можно уменьшить объем данных телеметрии, исключив запросы от роботов. С помощью фильтрации сократить трафик проще, чем при помощи выборки. Она обеспечивает более полный контроль над передаваемыми данными, но влияет на статистику. Например, вы можете отфильтровать все успешные запросы.
  • Инициализаторы телеметрии добавляют или изменяют свойства для любых данных телеметрии, отправляемых из вашего приложения, включая данные телеметрии из стандартных модулей. Например, можно добавить вычисляемые значения или номера версий, по которым будут отфильтрованы данные на портале.
  • API пакета SDK используется для отправки пользовательских событий и показателей.

Перед началом работы

Фильтрация

Такой подход позволяет непосредственно контролировать включение элементов в поток данных телеметрии и исключение из него. Фильтрацию можно использовать для удаления элементов телеметрии перед отправкой в Application Insights. Фильтрацию можно использовать совместно с выборкой или по отдельности.

Для фильтрации данных телеметрии нужно создать обработчик данных телеметрии и зарегистрировать его с помощью TelemetryConfiguration. Все данные телеметрии проходят через обработчик. Вы можете удалить их из потока или передать следующему обработчику в цепочке. Сюда входят данные телеметрии из стандартных модулей, таких как сборщик HTTP-запросов и сборщик зависимостей, а также данные телеметрии, полученные вами самостоятельно. Например, можно отфильтровать данные телеметрии о запросах из программ-роботов или успешных вызовах зависимостей.

Предупреждение

Фильтрация данных телеметрии, отправленных из пакета SDK с помощью обработчиков, может исказить отображаемую на портале статистику и затруднить отслеживание связанных элементов.

Вместо этого попробуйте использовать выборку.

Создание обработчика данных телеметрии (C#)

  1. Чтобы создать фильтр, реализуйте ITelemetryProcessor.

    Обработчики данных телеметрии создают цепь обработки. При создании экземпляра обработчика данных телеметрии предоставляется ссылка на следующий обработчик в цепочке. Когда точка данных телеметрии передается в метод Process, он выполняет свою работу и затем вызывает (или не вызывает) следующий обработчик данных телеметрии в цепочке.

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    
    public class SuccessfulDependencyFilter : ITelemetryProcessor
    {
        private ITelemetryProcessor Next { get; set; }
    
        // next will point to the next TelemetryProcessor in the chain.
        public SuccessfulDependencyFilter(ITelemetryProcessor next)
        {
            this.Next = next;
        }
    
        public void Process(ITelemetry item)
        {
            // To filter out an item, return without calling the next processor.
            if (!OKtoSend(item)) { return; }
    
            this.Next.Process(item);
        }
    
        // Example: replace with your own criteria.
        private bool OKtoSend (ITelemetry item)
        {
            var dependency = item as DependencyTelemetry;
            if (dependency == null) return true;
    
            return dependency.Success != true;
        }
    }
    
  2. Добавьте обработчик.

Приложения ASP.NET

В файл ApplicationInsights.config вставьте следующий фрагмент кода:

<TelemetryProcessors>
  <Add Type="WebApplication9.SuccessfulDependencyFilter, WebApplication9">
     <!-- Set public property -->
     <MyParamFromConfigFile>2-beta</MyParamFromConfigFile>
  </Add>
</TelemetryProcessors>

Можно передавать строковые значения из файла конфигурации, указав открытые именованные свойства в классе.

Предупреждение

Будьте внимательны и задайте имя типа и имена свойств в файле конфигурации, совпадающие с именами классов и свойств в коде. Если файл конфигурации ссылается на несуществующий тип или свойство, пакет SDK может не отправить данные телеметрии без уведомления.

Другой способ — инициализировать фильтр в коде. Вставьте обработчик в цепочку в соответствующем классе инициализации, например AppStart в Global.asax.cs:

var builder = TelemetryConfiguration.Active.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
builder.Use((next) => new SuccessfulDependencyFilter(next));

// If you have more processors:
builder.Use((next) => new AnotherProcessor(next));

builder.Build();

Клиенты телеметрии, созданные после этой точки, будут использовать обработчики.

Приложения службы рабочей роли или приложения ASP.NET Core

Примечание

Добавление обработчика с помощью ApplicationInsights.config или TelemetryConfiguration.Active недопустимо для приложений ASP.NET Core или при использовании пакета SDK Microsoft.ApplicationInsights.WorkerService.

Для приложений, написанных с помощью ASP.NET Core или WorkerService, добавление нового обработчика данных телеметрии осуществляется с помощью метода расширения AddApplicationInsightsTelemetryProcessor в IServiceCollection, как показано ниже. Этот метод вызывается в методе ConfigureServices класса Startup.cs.

    public void ConfigureServices(IServiceCollection services)
    {
        // ...
        services.AddApplicationInsightsTelemetry();
        services.AddApplicationInsightsTelemetryProcessor<SuccessfulDependencyFilter>();

        // If you have more processors:
        services.AddApplicationInsightsTelemetryProcessor<AnotherProcessor>();
    }

Примеры фильтров

Искусственные запросы

Вы можете отфильтровывать программы-роботы и веб-тесты. Хотя обозреватель метрик позволяет отфильтровывать искусственные источники, этот вариант сокращает трафик и объем принимаемых данных, фильтруя источники в пакете SDK.

public void Process(ITelemetry item)
{
  if (!string.IsNullOrEmpty(item.Context.Operation.SyntheticSource)) {return;}

  // Send everything else:
  this.Next.Process(item);
}

Сбой проверки подлинности

Отфильтруйте запросы с ответом 401.

public void Process(ITelemetry item)
{
    var request = item as RequestTelemetry;

    if (request != null &&
    request.ResponseCode.Equals("401", StringComparison.OrdinalIgnoreCase))
    {
        // To filter out an item, return without calling the next processor.
        return;
    }

    // Send everything else
    this.Next.Process(item);
}

Фильтрация быстрых удаленных вызовов зависимостей

Если требуется диагностировать только вызовы, которые выполняются медленно, можно отфильтровать быстрые вызовы.

Примечание

Это приведет к искажению статистических данных, отображаемых на портале.

public void Process(ITelemetry item)
{
    var request = item as DependencyTelemetry;

    if (request != null && request.Duration.TotalMilliseconds < 100)
    {
        return;
    }
    this.Next.Process(item);
}

Неполадки диагностики зависимостей

этом блоге описан проект, в котором диагностика неполадок с зависимостями реализована в виде автоматического опрашивания зависимостей.

Веб-приложения JavaScript

Фильтрация с помощью ITelemetryInitializer

  1. Создайте функцию обратного вызова инициализатора телеметрии. Функция обратного вызова принимает ITelemetryItem в качестве параметра, что является обрабатываемым событием. Возврат false из этого обратного вызова приводит к исключению элемента телеметрии.

    var filteringFunction = (envelope) => {
      if (envelope.data.someField === 'tobefilteredout') {
          return false;
      }
    
      return true;
    };
    
  2. Добавьте обратный вызов инициализатора телеметрии:

    appInsights.addTelemetryInitializer(filteringFunction);
    

Добавление или изменение свойств: ITelemetryInitializer

Используйте инициализаторы телеметрии, чтобы обогатить данные телеметрии с помощью дополнительных сведений или чтобы переопределить свойства телеметрии, заданные стандартными модулями телеметрии.

Например, веб-пакет Application Insights собирает данные телеметрии о HTTP-запросах. По умолчанию любой запрос с кодом ответа больше 400 он помечает как неудавшийся. Если вам нужно, чтобы значение 400 считалось успешным, задайте инициализатор телеметрии, в котором можно настроить свойство Success.

Если задан инициализатор телеметрии, он вызывается всякий раз, когда вызывается любой метод Track*(). Это относится также к методам Track(), вызываемым стандартными модулями телеметрии. Обычно эти модули не задают свойство, которое уже задал инициализатор. Инициализаторы телеметрии вызываются перед вызовом обработчиков данных телеметрии. Поэтому все обогащения, выполненные инициализаторами, видны для обработчиков.

Определение инициализатора

C#

using System;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;

namespace MvcWebRole.Telemetry
{
  /*
   * Custom TelemetryInitializer that overrides the default SDK
   * behavior of treating response codes >= 400 as failed requests
   *
   */
  public class MyTelemetryInitializer : ITelemetryInitializer
  {
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        // Is this a TrackRequest() ?
        if (requestTelemetry == null) return;
        int code;
        bool parsed = Int32.TryParse(requestTelemetry.ResponseCode, out code);
        if (!parsed) return;
        if (code >= 400 && code < 500)
        {
            // If we set the Success property, the SDK won't change it:
            requestTelemetry.Success = true;

            // Allow us to filter these requests in the portal:
            requestTelemetry.Properties["Overridden400s"] = "true";
        }
        // else leave the SDK to set the Success property
    }
  }
}

Приложения ASP.NET: загрузка инициализатора

В ApplicationInsights.config.:

<ApplicationInsights>
  <TelemetryInitializers>
    <!-- Fully qualified type name, assembly name: -->
    <Add Type="MvcWebRole.Telemetry.MyTelemetryInitializer, MvcWebRole"/>
    ...
  </TelemetryInitializers>
</ApplicationInsights>

Другой способ — создать экземпляр инициализатора в коде, например в Global.aspx.cs.

protected void Application_Start()
{
    // ...
    TelemetryConfiguration.Active.TelemetryInitializers.Add(new MyTelemetryInitializer());
}

Дополнительную информацию см. здесь.

Приложения службы рабочей роли или приложения ASP.NET Core: загрузка инициализатора

Примечание

Добавление инициализатора с помощью ApplicationInsights.config или TelemetryConfiguration.Active недопустимо для приложений ASP.NET Core или при использовании пакета SDK Microsoft.ApplicationInsights.WorkerService.

Для приложений, написанных с помощью ASP.NET Core или WorkerService, добавление нового инициализатора осуществляется с помощью контейнера внедрения зависимостей, как показано ниже. Это делается с помощью метода Startup.ConfigureServices.

 using Microsoft.ApplicationInsights.Extensibility;
 using CustomInitializer.Telemetry;
 public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ITelemetryInitializer, MyTelemetryInitializer>();
}

Инициализаторы телеметрии JavaScript

JavaScript

Вставьте инициализатор телеметрии с помощью обратного вызова фрагмента onInit:

<script type="text/javascript">
!function(T,l,y){<!-- Removed the Snippet code for brevity -->}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js",
crossOrigin: "anonymous",
onInit: function (sdk) {
  sdk.addTelemetryInitializer(function (envelope) {
    envelope.data.someField = 'This item passed through my telemetry initializer';
  });
}, // Once the application insights instance has loaded and initialized this method will be called
cfg: { // Application Insights Configuration
    instrumentationKey: "YOUR_INSTRUMENTATION_KEY"
}});
</script>

Краткое описание ненастраиваемых свойств, доступных в коллекции telemetryItem, см. в разделе Экспорт модели данных Application Insights.

Вы можете добавить любое количество инициализаторов по своему усмотрению. Они применяются в порядке добавления.

Обработчики телеметрии OpenCensus Python

Обработчики данных телеметрии в OpenCensus Python — это просто функции обратного вызова, которые вызываются для обработки данных телеметрии перед их экспортом. Функция обратного вызова должна принимать тип данных конверт в качестве параметра. Чтобы исключить данные телеметрии из экспорта, убедитесь, что функция обратного вызова возвращает False. Схема типов данных Azure Monitor в конвертах представлена на сайте GitHub.

Примечание

Можно изменить cloud_RoleName, изменив атрибут ai.cloud.role в поле tags.

def callback_function(envelope):
    envelope.tags['ai.cloud.role'] = 'new_role_name'
# Example for log exporter
import logging

from opencensus.ext.azure.log_exporter import AzureLogHandler

logger = logging.getLogger(__name__)

# Callback function to append '_hello' to each log message telemetry
def callback_function(envelope):
    envelope.data.baseData.message += '_hello'
    return True

handler = AzureLogHandler(connection_string='InstrumentationKey=<your-instrumentation_key-here>')
handler.add_telemetry_processor(callback_function)
logger.addHandler(handler)
logger.warning('Hello, World!')
# Example for trace exporter
import requests

from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.trace import config_integration
from opencensus.trace.samplers import ProbabilitySampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(['requests'])

# Callback function to add os_type: linux to span properties
def callback_function(envelope):
    envelope.data.baseData.properties['os_type'] = 'linux'
    return True

exporter = AzureExporter(
    connection_string='InstrumentationKey=<your-instrumentation-key-here>'
)
exporter.add_telemetry_processor(callback_function)
tracer = Tracer(exporter=exporter, sampler=ProbabilitySampler(1.0))
with tracer.span(name='parent'):
response = requests.get(url='https://www.wikipedia.org/wiki/Rabbit')
# Example for metrics exporter
import time

from opencensus.ext.azure import metrics_exporter
from opencensus.stats import aggregation as aggregation_module
from opencensus.stats import measure as measure_module
from opencensus.stats import stats as stats_module
from opencensus.stats import view as view_module
from opencensus.tags import tag_map as tag_map_module

stats = stats_module.stats
view_manager = stats.view_manager
stats_recorder = stats.stats_recorder

CARROTS_MEASURE = measure_module.MeasureInt("carrots",
                                            "number of carrots",
                                            "carrots")
CARROTS_VIEW = view_module.View("carrots_view",
                                "number of carrots",
                                [],
                                CARROTS_MEASURE,
                                aggregation_module.CountAggregation())

# Callback function to only export the metric if value is greater than 0
def callback_function(envelope):
    return envelope.data.baseData.metrics[0].value > 0

def main():
    # Enable metrics
    # Set the interval in seconds in which you want to send metrics
    exporter = metrics_exporter.new_metrics_exporter(connection_string='InstrumentationKey=<your-instrumentation-key-here>')
    exporter.add_telemetry_processor(callback_function)
    view_manager.register_exporter(exporter)

    view_manager.register_view(CARROTS_VIEW)
    mmap = stats_recorder.new_measurement_map()
    tmap = tag_map_module.TagMap()

    mmap.measure_int_put(CARROTS_MEASURE, 1000)
    mmap.record(tmap)
    # Default export interval is every 15.0s
    # Your application should run for at least this amount
    # of time so the exporter will meet this interval
    # Sleep can fulfill this
    time.sleep(60)

    print("Done recording metrics")

if __name__ == "__main__":
    main()

Вы можете добавить любое количество обработчиков по своему усмотрению. Они применяются в порядке добавления. Если один из обработчиков порождает исключение, оно не влияет на следующие обработчики.

Примеры инициализаторов TelemetryInitializer

Добавление пользовательского свойства

Следующий пример инициализатора добавляет пользовательское свойство в каждый отслеживаемый элемент телеметрии.

public void Initialize(ITelemetry item)
{
  var itemProperties = item as ISupportProperties;
  if(itemProperties != null && !itemProperties.Properties.ContainsKey("customProp"))
    {
        itemProperties.Properties["customProp"] = "customValue";
    }
}

Добавление имени облачной роли

Следующий пример инициализатора добавляет имя облачной роли в каждый отслеживаемый элемент телеметрии.

public void Initialize(ITelemetry telemetry)
{
    if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
    {
        telemetry.Context.Cloud.RoleName = "MyCloudRoleName";
    }
}

Добавление сведений из HttpContext

Следующий пример инициализатора считывает данные из HttpContext и добавляет их в экземпляр RequestTelemetry. Объект IHttpContextAccessor автоматически предоставляется посредством внедрения зависимостей конструктора.

public class HttpContextRequestTelemetryInitializer : ITelemetryInitializer
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public HttpContextRequestTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor =
            httpContextAccessor ??
            throw new ArgumentNullException(nameof(httpContextAccessor));
    }

    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        if (requestTelemetry == null) return;

        var claims = this.httpContextAccessor.HttpContext.User.Claims;
        Claim oidClaim = claims.FirstOrDefault(claim => claim.Type == "oid");
        requestTelemetry.Properties.Add("UserOid", oidClaim?.Value);
    }
}

ITelemetryProcessor и ITelemetryInitializer

Различия между обработчиком и инициализатором данных телеметрии

  • Существует несколько общих задач, которые можно выполнять с их помощью. Их обоих можно использовать для добавления или изменения свойств телеметрии, однако для этой цели рекомендуется использовать инициализаторы.
  • Инициализаторы телеметрии всегда выполняются до обработчиков телеметрии.
  • Инициализаторы телеметрии могут вызываться несколько раз. По соглашению они не задают уже установленное свойство.
  • Обработчики данных телеметрии могут полностью заменить или удалить элемент телеметрии.
  • Все зарегистрированные инициализаторы телеметрии гарантированно вызываются для каждого элемента телеметрии. Для обработчиков данных телеметрии пакет SDK гарантирует вызов первого обработчика данных телеметрии. Вызов последующих обработчиков определяется предыдущими обработчиками данных телеметрии.
  • Используйте инициализаторы телеметрии для обогащения данных телеметрии дополнительными свойствами или для переопределения существующих свойств. Используйте обработчик данных телеметрии, чтобы фильтровать данные телеметрии.

Примечание

JavaScript содержит только инициализаторы телеметрии, которые могут отфильтровывать события с помощью ITelemetryInitializer

Устранение неполадок с файлом ApplicationInsights.config

  • Убедитесь, что полное имя типа и имя сборки указаны правильно.
  • Убедитесь, что файл applicationinsights.config находится в выходном каталоге и содержит все последние изменения.

Справочная документация

Код пакета SDK

Следующие шаги