Filtrowanie i wstępne przetwarzanie danych telemetrycznych w zestawie Application Insights SDK

Wtyczki zestawu SDK usługi Application Insights mogą dostosowywać sposób wzbogacania i przetwarzania telemetrii przed wysłaniem ich do usługi Application Insights.

  • Próbkowanie zmniejsza ilość danych telemetrycznych bez wpływu na statystyki. Utrzymuje on powiązane punkty danych, aby można było przechodzić między nimi podczas diagnozowania problemu. W portalu łączna liczba jest mnożona w celu zrekompensowania próbkowania.
  • Filtrowanie za pomocą procesorów telemetrycznych umożliwia filtrowanie danych telemetrycznych w zestawie SDK przed wysłaniem ich do serwera. Można na przykład zmniejszyć ilość danych telemetrycznych, wykluczając żądania z robotów. Filtrowanie to bardziej podstawowe podejście do zmniejszenia ruchu niż próbkowanie. Pozwala to na większą kontrolę nad tym, co jest przesyłane, ale wpływa na statystyki. Możesz na przykład odfiltrować wszystkie pomyślne żądania.
  • Inicjatory telemetrii dodają lub modyfikują właściwości do dowolnej telemetrii wysyłanej z aplikacji, która obejmuje dane telemetryczne z modułów standardowych. Można na przykład dodać wartości obliczeniowe lub numery wersji, za pomocą których można filtrować dane w portalu.
  • Interfejs API zestawu SDK służy do wysyłania niestandardowych zdarzeń i metryk.

Przed rozpoczęciem:

Filtrowanie

Ta technika zapewnia bezpośrednią kontrolę nad elementami dołączonymi lub wykluczonymi ze strumienia telemetrii. Filtrowanie może służyć do porzucania elementów telemetrii z wysyłania do usługi Application Insights. Filtrowanie można używać z próbkowaniem lub oddzielnie.

Aby filtrować dane telemetryczne, należy napisać procesor telemetrii i zarejestrować go w usłudze TelemetryConfiguration. Wszystkie dane telemetryczne przechodzą przez procesor. Możesz usunąć go ze strumienia lub przekazać go do następnego procesora w łańcuchu. Dane telemetryczne ze standardowych modułów, takich jak moduł zbierający żądania HTTP i moduł zbierający zależności, oraz śledzone dane telemetryczne są uwzględniane samodzielnie. Można na przykład odfiltrować dane telemetryczne dotyczące żądań z robotów lub pomyślnych wywołań zależności.

Ostrzeżenie

Filtrowanie danych telemetrycznych wysyłanych z zestawu SDK przy użyciu procesorów może wypaczyć statystyki widoczne w portalu i utrudniać obserwowanie powiązanych elementów.

Zamiast tego rozważ użycie próbkowania.

Tworzenie procesora telemetrii

C#

  1. Aby utworzyć filtr, zaimplementuj element ITelemetryProcessor.

    Procesory telemetryczne konstruuje łańcuch przetwarzania. Podczas tworzenia wystąpienia procesora telemetrii otrzymujesz odwołanie do następnego procesora w łańcuchu. Gdy punkt danych telemetrycznych jest przekazywany do metody procesu, wykonuje swoją pracę, a następnie wywołuje (lub nie wywołuje) następnego procesora telemetrii w łańcuchu.

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.ApplicationInsights.DataContracts;
    
    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. Dodaj procesor.

aplikacje ASP.NET

Wstaw ten fragment kodu w ApplicationInsights.config:

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

Wartości ciągów można przekazać z pliku .config, podając publiczne nazwane właściwości w klasie.

Ostrzeżenie

Należy zachować ostrożność, aby dopasować nazwę typu i wszystkie nazwy właściwości w pliku .config do nazw klas i właściwości w kodzie. Jeśli plik .config odwołuje się do nieistniejących typów lub właściwości, zestaw SDK może dyskretnie nie wysyłać żadnych danych telemetrycznych.

Alternatywnie można zainicjować filtr w kodzie. W odpowiedniej klasie inicjowania, na przykład AppStart w Global.asax.cspliku , wstaw procesor do łańcucha:

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

Klienci telemetrii utworzone po tym punkcie będą używać procesorów.

aplikacje usługi ASP.NET Core/Worker

Uwaga

Dodanie procesora przy użyciu metody ApplicationInsights.config lub TelemetryConfiguration.Active nie jest prawidłowe w przypadku aplikacji ASP.NET Core lub jeśli używasz Microsoft. Zestaw SDK ApplicationInsights.WorkerService.

W przypadku aplikacji napisanych przy użyciu ASP.NET Core lub WorkerService dodanie nowego procesora telemetrii odbywa się przy użyciu AddApplicationInsightsTelemetryProcessor metody rozszerzenia w metodzie IServiceCollection, jak pokazano poniżej. Ta metoda jest wywoływana w metodzie ConfigureServicesStartup.cs klasy .

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

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

Aby zarejestrować procesory telemetryczne, które wymagają parametrów w ASP.NET Core, utwórz niestandardową klasę implementujący interfejs ITelemetryProcessorFactory. Wywołaj konstruktor z żądanymi parametrami w metodzie Create , a następnie użyj polecenia AddSingleton<ITelemetryProcessorFactory, MyTelemetryProcessorFactory>().

Przykładowe filtry

Żądania syntetyczne

Odfiltruj boty i testy internetowe. Chociaż Eksplorator metryk udostępnia opcję filtrowania źródeł syntetycznych, ta opcja zmniejsza ruch i rozmiar pozyskiwania przez filtrowanie ich w samym zestawie SDK.

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

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

Uwierzytelnianie nie powiodło się

Odfiltruj żądania przy użyciu odpowiedzi "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);
}

Filtrowanie szybkich wywołań zależności zdalnych

Jeśli chcesz zdiagnozować tylko powolne wywołania, odfiltruj te szybkie.

Uwaga

To filtrowanie spowoduje niesymetryczność statystyk widocznych w portalu.

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

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

Diagnozowanie problemów z zależnościami

W tym blogu opisano projekt do diagnozowania problemów z zależnościami przez automatyczne wysyłanie regularnych poleceń ping do zależności.

Java

Aby dowiedzieć się więcej na temat procesorów telemetrii i ich implementacji w języku Java, zapoznaj się z dokumentacją procesorów telemetrii Java.

Aplikacje internetowe JavaScript

Filtrowanie przy użyciu interfejsu ITelemetryInitializer

  1. Utwórz funkcję wywołania zwrotnego inicjatora telemetrii. Funkcja wywołania zwrotnego przyjmuje ITelemetryItem jako parametr, czyli zdarzenie, które jest przetwarzane. false Powrót z tego wywołania zwrotnego powoduje odfiltrowanie elementu telemetrii.

    var filteringFunction = (envelope) => {
      if (envelope.data.someField === 'tobefilteredout') {
          return false;
      }
    
      return true;
    };
    
  2. Dodaj wywołanie zwrotne inicjatora telemetrii:

    appInsights.addTelemetryInitializer(filteringFunction);
    

Dodawanie/modyfikowanie właściwości: ITelemetryInitializer

Inicjatory telemetrii umożliwiają wzbogacanie telemetrii dodatkowymi informacjami lub zastępowanie właściwości telemetrii ustawionych przez standardowe moduły telemetrii.

Na przykład usługa Application Insights dla pakietu internetowego zbiera dane telemetryczne dotyczące żądań HTTP. Domyślnie flaguje ono jako nieudane każde żądanie z kodem >odpowiedzi =400. Jeśli jednak chcesz traktować 400 jako powodzenie, możesz podać inicjator telemetrii, który ustawia właściwość success.

Jeśli podasz inicjator telemetrii, jest wywoływany za każdym razem, gdy zostanie wywołana dowolna z metod Track*(). Ten inicjator zawiera Track() metody wywoływane przez standardowe moduły telemetrii. Zgodnie z konwencją te moduły nie ustawiają żadnej właściwości, która została już ustawiona przez inicjator. Inicjatory telemetrii są wywoływane przed wywołaniem procesorów telemetrii. Dlatego wszelkie wzbogacania wykonywane przez inicjatory są widoczne dla procesorów.

Definiowanie inicjatora

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

aplikacje ASP.NET: załaduj inicjator

W ApplicationInsights.config:

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

Alternatywnie można utworzyć wystąpienie inicjatora w kodzie, na przykład w pliku Global.aspx.cs:

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

Zobacz więcej z tego przykładu.

aplikacje usługi ASP.NET Core/Worker: załaduj inicjator

Uwaga

Dodawanie inicjatora przy użyciu polecenia ApplicationInsights.config lub TelemetryConfiguration.Active nie jest prawidłowe dla aplikacji ASP.NET Core lub jeśli używasz Microsoft. Zestaw SDK ApplicationInsights.WorkerService.

W przypadku aplikacji napisanych przy użyciu ASP.NET Core lub WorkerService dodanie nowego inicjatora telemetrii odbywa się przez dodanie go do kontenera wstrzykiwania zależności, jak pokazano poniżej. Ten krok należy wykonać w metodzie Startup.ConfigureServices .

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

Inicjatory telemetrii języka JavaScript

JavaScript

Wstaw inicjator telemetrii przy użyciu fragmentu kodu onInit callback:

<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>

Aby uzyskać podsumowanie właściwości niedokumentowych dostępnych w elemencie telemetrii, zobacz Application Insights Export Data Model (Eksportowanie modelu danych w usłudze Application Insights).

Możesz dodać dowolną liczbę inicjatorów. Są one wywoływane w kolejności, w której są dodawane.

Procesory telemetryczne OpenCensus języka Python

Procesory telemetryczne w języku OpenCensus w języku Python są po prostu funkcjami wywołania zwrotnego wywoływanymi w celu przetwarzania danych telemetrycznych przed ich wyeksportowaniem. Funkcja wywołania zwrotnego musi akceptować typ danych koperty jako parametr. Aby odfiltrować dane telemetryczne z eksportowanych, upewnij się, że funkcja wywołania zwrotnego zwraca wartość False. Schemat typów danych usługi Azure Monitor można wyświetlić w kopertach w usłudze GitHub.

Uwaga

Można zmodyfikować cloud_RoleName , zmieniając ai.cloud.role atrybut w tags polu.

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()

Możesz dodać dowolną liczbę procesorów. Są one wywoływane w kolejności, w której są dodawane. Jeśli jeden procesor zgłasza wyjątek, nie ma to wpływu na następujące procesory.

Przykładowe dane telemetryczneInitializers

Dodawanie właściwości niestandardowej

Poniższy przykładowy inicjator dodaje właściwość niestandardową do każdej śledzonej telemetrii.

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

Dodawanie nazwy roli w chmurze

Poniższy przykładowy inicjator ustawia nazwę roli chmury na wszystkie śledzone dane telemetryczne.

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

Kontrolowanie adresu IP klienta używanego do mapowania geolokalizacji

Poniższy przykładowy inicjator ustawia adres IP klienta, który będzie używany do mapowania geolokalizacji zamiast adresu IP gniazda klienta podczas pozyskiwania danych telemetrycznych.

public void Initialize(ITelemetry telemetry)
{
    var request = telemetry as RequestTelemetry;
    if (request == null) return true;
    request.Context.Location.Ip = "{client ip address}"; // Could utilize System.Web.HttpContext.Current.Request.UserHostAddress;   
    return true;
}

ITelemetryProcessor i ITelemetryInitializer

Jaka jest różnica między procesorami telemetrii i inicjatorami telemetrii?

  • Istnieją pewne nakładające się na siebie czynności, które można z nimi zrobić. Oba te elementy mogą służyć do dodawania lub modyfikowania właściwości telemetrii, chociaż zalecamy używanie inicjatorów do tego celu.
  • Inicjatory telemetrii zawsze są uruchamiane przed procesorami telemetrii.
  • Inicjatory telemetrii mogą być wywoływane więcej niż raz. Zgodnie z konwencją nie ustawiają żadnej właściwości, która została już ustawiona.
  • Procesory telemetryczne umożliwiają całkowite zastąpienie lub odrzucenie elementu telemetrii.
  • Wszystkie zarejestrowane inicjatory telemetrii są wywoływane dla każdego elementu telemetrii. W przypadku procesorów telemetrycznych zestaw SDK gwarantuje wywołanie pierwszego procesora telemetrii. Niezależnie od tego, czy pozostałe procesory są wywoływane, czy nie, zależy od powyższych procesorów telemetrycznych.
  • Użyj inicjatorów telemetrii, aby wzbogacić dane telemetryczne o więcej właściwości lub zastąpić istniejącą. Użyj procesora telemetrii, aby odfiltrować dane telemetryczne.

Uwaga

Język JavaScript ma tylko inicjatory telemetrii, które mogą filtrować zdarzenia przy użyciu interfejsu ITelemetryInitializer

Rozwiązywanie problemów z ApplicationInsights.config

  • Upewnij się, że w pełni kwalifikowana nazwa typu i nazwa zestawu są poprawne.
  • Upewnij się, że plik applicationinsights.config znajduje się w katalogu wyjściowym i zawiera wszelkie ostatnie zmiany.

Dokumenty referencyjne

Kod zestawu SDK

Następne kroki