Vad är distribuerad spårning och telemetrikorrelation?

Kommentar

Följande dokumentation förlitar sig på det klassiska API:et Application Insights. Den långsiktiga planen för Application Insights är att samla in data med OpenTelemetry. Mer information finns i Aktivera Azure Monitor OpenTelemetry för .NET-, Node.js-, Python- och Java-program.

Moderna moln- och mikrotjänstarkitekturer har aktiverat enkla, oberoende distributionsbara tjänster som minskar kostnaderna samtidigt som tillgängligheten och dataflödet ökar. Det har dock gjort det svårare att resonera kring och felsöka övergripande system. Distribuerad spårning löser det här problemet genom att tillhandahålla en prestandaprofilerare som fungerar som anropsstackar för moln- och mikrotjänstarkitekturer.

Azure Monitor tillhandahåller två funktioner för användning av distribuerade spårningsdata: transaktionsdiagnostikvyn för en enskild transaktion/begäran och programkartvyn för att visa hur system interagerar.

Application Insights kan övervaka varje komponent separat och identifiera vilken komponent som är ansvarig för fel eller prestandaförsämring med hjälp av distribuerad telemetrikorrelation. Den här artikeln förklarar datamodellen, tekniker för kontextspridning, protokoll och implementering av korrelationstaktik på olika språk och plattformar som används av Application Insights.

Aktivera distribuerad spårning

Om du vill aktivera distribuerad spårning för ett program lägger du till rätt agent, SDK eller bibliotek i varje tjänst baserat på dess programmeringsspråk.

Aktivera via Application Insights via autoinstrumentation eller SDK:er

Application Insights-agenter och SDK:er för .NET, .NET Core, Java, Node.js och JavaScript stöder alla distribuerad spårning internt. Instruktioner för att installera och konfigurera varje Application Insights SDK är tillgängliga för:

Med rätt Application Insights SDK installerat och konfigurerat samlas spårningsinformation automatiskt in för populära ramverk, bibliotek och tekniker av SDK-beroende autocollectors. Den fullständiga listan över tekniker som stöds finns i dokumentationen för autocollection för beroenden.

Alla tekniker kan också spåras manuellt med ett anrop till TrackDependencyTelemetryClient.

Aktivera via OpenTelemetry

Application Insights stöder nu distribuerad spårning via OpenTelemetry. OpenTelemetry tillhandahåller en leverantörsneutral instrumentation för att skicka spårningar, mått och loggar till Application Insights. Till en början tog OpenTelemetry-communityn på sig distribuerad spårning. Mått och loggar pågår fortfarande.

En komplett berättelse om observerbarhet innehåller alla tre pelarna. Kontrollera statusen för våra Azure Monitor OpenTelemetry-baserade erbjudanden för att se den senaste statusen för vad som ingår, vilka erbjudanden som är allmänt tillgängliga och supportalternativ.

Följande sidor består av vägledning för språk för att aktivera och konfigurera Microsofts OpenTelemetry-baserade erbjudanden. Viktigt är att vi delar de tillgängliga funktionerna och begränsningarna för varje erbjudande så att du kan avgöra om OpenTelemetry är rätt för ditt projekt.

Aktivera via OpenCensus

Utöver Application Insights SDK:er stöder Application Insights även distribuerad spårning via OpenCensus. OpenCensus är en distribution med öppen källkod, leverantörsoberoende, enskild distribution av bibliotek för att tillhandahålla insamling av mått och distribuerad spårning för tjänster. Det gör det också möjligt för communityn med öppen källkod att aktivera distribuerad spårning med populära tekniker som Redis, Memcached eller MongoDB. Microsoft samarbetar på OpenCensus med flera andra övervaknings- och molnpartners.

Mer information om OpenCensus för Python finns i Konfigurera Azure Monitor för ditt Python-program.

OpenCensus-webbplatsen har API-referensdokumentation för Python, Go och olika guider för att använda OpenCensus.

Datamodell för telemetrikorrelation

Application Insights definierar en datamodell för distribuerad telemetrikorrelation. Om du vill associera telemetri med en logisk åtgärd har varje telemetriobjekt ett kontextfält med namnet operation_Id. Varje telemetriobjekt i den distribuerade spårningen delar den här identifieraren. Så även om du förlorar telemetri från ett enda lager kan du fortfarande associera telemetri som rapporterats av andra komponenter.

En distribuerad logisk åtgärd består vanligtvis av en uppsättning mindre åtgärder som är begäranden som bearbetas av en av komponenterna. Telemetri för begäran definierar dessa åtgärder. Varje telemetriobjekt för begäran har ett eget id objekt som identifierar det unikt och globalt. Och alla telemetriobjekt (till exempel spårningar och undantag) som är associerade med begäran bör ange operation_parentId värdet för begäran id.

Beroendetelemetri representerar varje utgående åtgärd, till exempel ett HTTP-anrop till en annan komponent. Den definierar också sin egen id som är globalt unik. Telemetri för begäran, som initieras av det här beroendeanropet, använder detta id som dess operation_parentId.

Du kan skapa en vy över den distribuerade logiska åtgärden med hjälp operation_Idav , operation_parentIdoch request.id med dependency.id. Dessa fält definierar också kausalitetsordningen för telemetrianrop.

I en mikrotjänstmiljö kan spårningar från komponenter gå till olika lagringsobjekt. Varje komponent kan ha sina egna anslutningssträng i Application Insights. För att få telemetri för den logiska åtgärden frågar Application Insights data från varje lagringsobjekt.

När antalet lagringsobjekt är stort behöver du en ledtråd om var du ska titta härnäst. Application Insights-datamodellen definierar två fält för att lösa det här problemet: request.source och dependency.target. Det första fältet identifierar komponenten som initierade beroendebegäran. Det andra fältet identifierar vilken komponent som returnerade svaret från beroendeanropet.

Information om hur du frågar från flera olika instanser med hjälp app av frågeuttrycket finns i app()-uttryck i Azure Monitor-frågan.

Exempel

Låt oss ta en titt på ett exempel. Ett program med namnet Aktiekurser visar det aktuella marknadspriset för en aktie med hjälp av ett externt API som heter Stock. Programmet Aktiekurser har en sida med namnet Stock page (Lagersida) som klientens webbläsare öppnar med hjälp GET /Home/Stockav . Programmet frågar lager-API:et med hjälp av HTTP-anropet GET /api/stock/value.

Du kan analysera den resulterande telemetrin genom att köra en fråga:

(requests | union dependencies | union pageViews)
| where operation_Id == "STYz"
| project timestamp, itemType, name, id, operation_ParentId, operation_Id

I resultatet delar alla telemetriobjekt roten operation_Id. När ett Ajax-anrop görs från sidan tilldelas ett nytt unikt ID (qJSXU) till beroendetelemetrin och ID:t för pageView används som operation_ParentId. Serverbegäran använder sedan Ajax-ID:t som operation_ParentId.

itemType name ID operation_ParentId operation_Id
Sidvisning Lagersida STYz STYz
Beroende GET /Home/Stock qJSXU STYz STYz
begäran GET Home/Stock KqKwlrSt9PA= qJSXU STYz
Beroende GET /api/stock/value bBrf2L7mm2g= KqKwlrSt9PA= STYz

När anropet GET /api/stock/value görs till en extern tjänst måste du känna till serverns identitet så att du kan ange fältet dependency.target på rätt sätt. När den externa tjänsten inte stöder övervakning target ställs den in på tjänstens värdnamn. Ett exempel är stock-prices-api.com. Men om tjänsten identifierar sig genom att returnera ett fördefinierat HTTP-huvud innehåller target den tjänstidentitet som gör att Application Insights kan skapa en distribuerad spårning genom att fråga telemetri från den tjänsten.

Korrelationshuvuden med W3C TraceContext

Application Insights övergår till W3C Trace-Context, som definierar:

  • traceparent: Bär det globalt unika åtgärds-ID:t och den unika identifieraren för anropet.
  • tracestate: Bär systemspecifik spårningskontext.

Den senaste versionen av Application Insights SDK stöder protokollet Trace-Context, men du kan behöva välja det. (Bakåtkompatibilitet med det tidigare korrelationsprotokollet som stöds av Application Insights SDK upprätthålls.)

HTTP-korrelationsprotokollet , även kallat Request-Id, är inaktuellt. Det här protokollet definierar två huvuden:

  • Request-Id: Bär det globalt unika ID:t för anropet.
  • Correlation-Context: Bär samlingen name-value pairs för de distribuerade spårningsegenskaperna.

Application Insights definierar också tillägget för HTTP-korrelationsprotokollet. Den använder Request-Context namn/värde-par för att sprida den samling egenskaper som används av den omedelbara anroparen eller anroparen. Application Insights SDK använder det här huvudet för att ange fälten dependency.target och request.source .

Datamodellerna W3C Trace-Context och Application Insights mappar på följande sätt:

Programinsikter W3C TraceContext
Id av Request och Dependency parent-id
Operation_Id trace-id
Operation_ParentId överordnat ID för det här spannets överordnade spann. Det här fältet måste vara tomt om det är ett rotintervall.

Mer information finns i Application Insights telemetridatamodell.

Aktivera stöd för distribuerad spårning i W3C för .NET-appar

W3C TraceContext-baserad distribuerad spårning är aktiverad som standard i alla senaste .NET Framework/.NET Core SDK:er, tillsammans med bakåtkompatibilitet med äldre Request-Id-protokoll.

Aktivera stöd för distribuerad spårning i W3C för Java-appar

Java 3.0-agent

Java 3.0-agenten har stöd för W3C direkt och ingen mer konfiguration krävs.

Java SDK

  • Inkommande konfiguration

    För Java EE-appar lägger du till följande kod i taggen <TelemetryModules> i ApplicationInsights.xml:

    <Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule>
       <Param name = "W3CEnabled" value ="true"/>
       <Param name ="enableW3CBackCompat" value = "true" />
    </Add>
    

    Lägg till följande egenskaper för Spring Boot-appar:

    • azure.application-insights.web.enable-W3C=true
    • azure.application-insights.web.enable-W3C-backcompat-mode=true
  • Utgående konfiguration

    Lägg till följande kod i AI-Agent.xml:

    <Instrumentation>
      <BuiltIn enabled="true">
        <HTTP enabled="true" W3C="true" enableW3CBackCompat="true"/>
      </BuiltIn>
    </Instrumentation>
    

    Kommentar

    Bakåtkompatibilitetsläget är aktiverat som standard och parametern enableW3CBackCompat är valfri. Använd den bara när du vill inaktivera bakåtkompatibilitet.

    Vi rekommenderar att du inaktiverar det här läget när alla dina tjänster uppdateras till nyare versioner av SDK:er som stöder W3C-protokollet. Vi rekommenderar starkt att du flyttar till dessa nyare SDK:er så snart som möjligt.

Det är viktigt att se till att de inkommande och utgående konfigurationerna är exakt desamma.

Aktivera stöd för distribuerad spårning i W3C för webbappar

Den här funktionen är aktiverad som standard för JavaScript och rubrikerna inkluderas automatiskt när värdsidedomänen är samma som domänen som begäranden skickas till (till exempel är example.com värdsidan och Ajax-begäranden skickas till example.com). Om du vill ändra det distribuerade spårningsläget använder du konfigurationsfältetdistributedTracingMode. AI_AND_W3C tillhandahålls som standard för bakåtkompatibilitet med alla äldre tjänster som instrumenterats av Application Insights.

Om XMLHttpRequest- eller Fetch Ajax-begäranden skickas till en annan domänvärd, inklusive underdomäner, inkluderas inte korrelationsrubrikerna som standard. Om du vill aktivera den här funktionen anger du konfigurationsfältet enableCorsCorrelation till .true Om du anger enableCorsCorrelation till trueinnehåller alla XMLHttpRequest- och Fetch Ajax-begäranden korrelationsrubrikerna. Om programmet på servern som anropas inte stöder traceparent huvudet kan begäran misslyckas, beroende på om webbläsaren/versionen kan verifiera begäran baserat på vilka huvuden servern accepterar. Du kan använda konfigurationsfältet correlationHeaderExcludedDomains för att undanta serverns domän från korskomponentens korrelationshuvudinmatning. Du kan till exempel använda correlationHeaderExcludedDomains: ['*.auth0.com'] för att undanta korrelationshuvuden från begäranden som skickas till identitetsprovidern Auth0.

Viktigt!

Information om hur du ser alla konfigurationer som krävs för att aktivera korrelation finns i JavaScript-korrelationsdokumentationen.

Telemetrikorrelation i OpenCensus Python

OpenCensus Python stöder W3C Trace-Context utan extra konfiguration.

Som referens hittar du OpenCensus-datamodellen på den här GitHub-sidan.

Korrelation för inkommande begäran

OpenCensus Python korrelerar W3C Trace-Context-huvuden från inkommande begäranden till de intervall som genereras från själva begärandena. OpenCensus korrelerar automatiskt med integreringar för dessa populära webbprogramramverk: Flask, Django och Pyramid. Du behöver bara fylla i W3C Trace-Context-huvudena med rätt format och skicka dem med begäran.

Utforska det här Flask-exempelprogrammet. Installera Flask, OpenCensus och tilläggen för Flask och Azure.


pip install flask opencensus opencensus-ext-flask opencensus-ext-azure

Du måste lägga till din Application Insights-anslutningssträng till miljövariabeln.

APPLICATIONINSIGHTS_CONNECTION_STRING=<appinsights-connection-string>

Exempel på Flask-program

from flask import Flask
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
from opencensus.trace.samplers import ProbabilitySampler

app = Flask(__name__)
middleware = FlaskMiddleware(
    app,
    exporter=AzureExporter(
        connection_string='<appinsights-connection-string>', # or set environment variable APPLICATION_INSIGHTS_CONNECTION_STRING
    ), 
    sampler=ProbabilitySampler(rate=1.0),
)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='localhost', port=8080, threaded=True)

Den här koden kör ett Flask-exempelprogram på den lokala datorn och lyssnar på port 8080. För att korrelera spårningskontexten skickar du en begäran till slutpunkten. I det här exemplet kan du använda ett curl kommando:

curl --header "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" localhost:8080

Genom att titta på rubrikformatet Trace-Context kan du härleda följande information:

version: 00

trace-id: 4bf92f3577b34da6a3ce929d0e0e4736

parent-id/span-id: 00f067aa0ba902b7

trace-flags: 01

Om du tittar på begärandeposten som skickades till Azure Monitor kan du se fält ifyllda med spårningshuvudinformationen. Du hittar data under Loggar (Analys) i Azure Monitor Application Insights-resursen.

Screenshot that shows Request telemetry in Logs (Analytics).

Fältet id är i formatet <trace-id>.<span-id>, där trace-id hämtas från spårningshuvudet som skickades i begäran och span-id är en genererad 8-bytesmatris för det här intervallet.

Fältet operation_ParentId är i formatet <trace-id>.<parent-id>, där båda trace-id och parent-id hämtas från spårningshuvudet som skickades i begäran.

Loggkorrelation

Med OpenCensus Python kan du korrelera loggar genom att lägga till ett spårnings-ID, ett span-ID och en samplingsflagga i loggposter. Du lägger till dessa attribut genom att installera OpenCensus-loggningsintegrering. Följande attribut läggs till i Python-objekt LogRecord : traceId, spanIdoch traceSampled (gäller endast för loggare som skapas efter integreringen).

Installera OpenCensus-loggningsintegrering:

python -m pip install opencensus-ext-logging

Exempelprogram

import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(['logging'])
logging.basicConfig(format='%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s')
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning('Before the span')
with tracer.span(name='hello'):
    logger.warning('In the span')
logger.warning('After the span')

När den här koden körs skrivs följande ut i konsolen:

2019-10-17 11:25:59,382 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 Before the span
2019-10-17 11:25:59,384 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=70da28f5a4831014 In the span
2019-10-17 11:25:59,385 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 After the span

Observera att det finns en spanId present för loggmeddelandet som är inom intervallet. spanId är samma som det som tillhör spannet med namnet hello.

Du kan exportera loggdata med hjälp AzureLogHandlerav . Mer information finns i Konfigurera Azure Monitor för ditt Python-program.

Vi kan också skicka spårningsinformation från en komponent till en annan för korrekt korrelation. Tänk dig till exempel ett scenario där det finns två komponenter och module1module2. Modul 1 anropar funktioner i modul 2. För att hämta loggar från både module1 och module2 i en enda spårning kan vi använda följande metod:

# module1.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer
from module_2 import function_1

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning("Before the span")

with tracer.span(name="hello"):
    logger.warning("In the span")
    function_1(logger, tracer)
logger.warning("After the span")
# module_2.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
logger = logging.getLogger(__name__)
tracer = Tracer(sampler=AlwaysOnSampler())


def function_1(logger=logger, parent_tracer=None):
    if parent_tracer is not None:
        tracer = Tracer(
            span_context=parent_tracer.span_context,
            sampler=AlwaysOnSampler(),
        )
    else:
        tracer = Tracer(sampler=AlwaysOnSampler())

    with tracer.span("function_1"):
        logger.info("In function_1")

Telemetrikorrelation i .NET

Korrelation hanteras som standard när en app registreras. Inga särskilda åtgärder krävs.

.NET-körning stöder distribuerad med hjälp av Activity och DiagnosticSource

Application Insights .NET SDK använder DiagnosticSource och Activity för att samla in och korrelera telemetri.

Telemetrikorrelation i Java

Java-agenten stöder automatisk korrelation av telemetri. Den fylls operation_id automatiskt i för alla telemetrier (till exempel spårningar, undantag och anpassade händelser) som utfärdas inom ramen för en begäran. Den sprider även korrelationsrubrikerna som beskrevs tidigare för tjänst-till-tjänst-anrop via HTTP, om Java SDK-agenten har konfigurerats.

Kommentar

Application Insights Java-agenten samlar automatiskt in begäranden och beroenden för JMS, Kafka, Netty/Webflux med mera. För Java SDK stöds endast anrop som görs via Apache HttpClient för korrelationsfunktionen. Automatisk kontextspridning mellan meddelandetekniker som Kafka, RabbitMQ och Azure Service Bus stöds inte i SDK:t.

För att samla in anpassad telemetri måste du instrumentera programmet med Java 2.6 SDK.

Rollnamn

Du kanske vill anpassa hur komponentnamn visas i Programkarta. För att göra det kan du ställa in cloud_RoleName manuellt genom att vidta någon av följande åtgärder:

  • För Application Insights Java anger du namnet på molnrollen på följande sätt:

    {
      "role": {
        "name": "my cloud role name"
      }
    }
    

    Du kan också ange namnet på molnrollen med hjälp av miljövariabeln APPLICATIONINSIGHTS_ROLE_NAME.

  • Med Application Insights Java SDK 2.5.0 och senare kan du ange cloud_RoleName genom att lägga <RoleName> till i din ApplicationInsights.xml-fil :

    Screenshot that shows Application Insights overview and connection string.

    <?xml version="1.0" encoding="utf-8"?>
    <ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
       <ConnectionString>InstrumentationKey=00000000-0000-0000-0000-000000000000</ConnectionString>
       <RoleName>** Your role name **</RoleName>
       ...
    </ApplicationInsights>
    
  • Om du använder Spring Boot med Application Insights Spring Boot Starter anger du ditt anpassade namn för programmet i filen application.properties :

    spring.application.name=<name-of-app>

Du kan också ange namnet på molnrollen via miljövariabeln eller systemegenskapen. Mer information finns i Konfigurera namnet på molnrollen .

Nästa steg