Dela via


Aktivera webbläsartelemetri

Instrumentpanelen .NET.NET Aspire kan konfigureras för att ta emot telemetri som skickas från webbläsarappar. Den här funktionen är användbar för övervakning av prestanda på client-sidan och användarinteraktioner. Webbläsartelemetri kräver ytterligare instrumentpanelskonfiguration och att JavaScript OTEL SDK läggs till i webbläsarapparna.

I den här artikeln beskrivs hur du aktiverar webbläsartelemetri på instrumentpanelen .NET.NET Aspire.

Konfiguration av instrumentpanel

Webbläsartelemetri kräver instrumentpanelen för att aktivera dessa funktioner:

  • OTLP HTTP-slutpunkt. Den här slutpunkten används av instrumentpanelen för att ta emot telemetri från webbläsarappar.
  • Resursdelning mellan ursprung (CORS). CORS gör att webbläsarappar kan göra begäranden till instrumentpanelen.

OTLP-konfiguration

Instrumentpanelen .NET.NET Aspire tar emot telemetri via OTLP-slutpunkter. HTTP OTLP-slutpunkter och gRPC OTLP-slutpunkter stöds av instrumentpanelen. Webbläsarappar måste använda HTTP OLTP för att skicka telemetri till instrumentpanelen eftersom webbläsarappar inte stöder gRPC.

Om du vill konfigurera gPRC- eller HTTP-slutpunkterna anger du följande miljövariabler:

  • DOTNET_DASHBOARD_OTLP_ENDPOINT_URL: Den gRPC-slutpunkt som instrumentpanelen ansluter till för sina data.
  • DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL: HTTP-slutpunkten som instrumentpanelen ansluter till för sina data.

Konfigurationen av HTTP OTLP-slutpunkten beror på om instrumentpanelen startas av programvärden eller körs som en fristående applikation.

Konfigurera OTLP HTTP med appvärd

Om kontrollpanelen och appen startas av appvärden konfigureras OTLP-slutpunkterna i appvärdens "launchSettings"-konfigurationsfil.json fil.

Överväg följande exempel JSON fil:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:15887;http://localhost:15888",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "DOTNET_ENVIRONMENT": "Development",
        "DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL": "https://localhost:16175",
        "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037",
        "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
      }
    },
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "http://localhost:15888",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "DOTNET_ENVIRONMENT": "Development",
        "DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL": "http://localhost:16175",
        "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17037",
        "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true",
        "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"
      }
    },
    "generate-manifest": {
      "commandName": "Project",
      "launchBrowser": true,
      "dotnetRunMessages": true,
      "commandLineArgs": "--publisher manifest --output-path aspire-manifest.json",
      "applicationUrl": "http://localhost:15888",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "DOTNET_ENVIRONMENT": "Development"
      }
    }
  }
}

Föregående startinställningar JSON-filen konfigurerar alla profiler för att inkludera DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL miljövariabeln.

Konfigurera OTLP HTTP med fristående instrumentpanel

Om instrumentpanelen används fristående utan rest från .NET Aspireär OTLP HTTP-slutpunkten som standard aktiverad på port 18890. Porten måste dock mappas när instrumentpanelscontainern startas:

docker run --rm -it -d \
    -p 18888:18888 \
    -p 4317:18889 \
    -p 4318:18890 \
    --name aspire-dashboard \
    mcr.microsoft.com/dotnet/aspire-dashboard:9.0

Föregående kommando kör instrumentpanelens container och mappar gRPC OTLP till port 4317 och HTTP OTLP till port 4318.

CORS-konfiguration

Som standard är webbläsarappar begränsade från att göra API-anrop mellan domäner. Detta påverkar sändning av telemetri till instrumentpanelen eftersom instrumentpanelen och webbläsarappen alltid finns på olika domäner. Om du konfigurerar CORS i .NET.NET Aspire-instrumentpanelen tar du bort begränsningen.

Om kontrollpanelen och din app har startats av appvärden krävs ingen CORS-konfiguration. .NET .NET Aspire konfigurerar automatiskt instrumentpanelen för att tillåta alla resursens ursprung.

Om instrumentpanelen används standlone måste CORS konfigureras manuellt. Domänen som används för att visa webbläsarappen måste konfigureras som ett tillåtet ursprung genom att ange DASHBOARD__OTLP__CORS__ALLOWEDORIGINS miljövariabeln när instrumentpanelscontainern startas:

docker run --rm -it -d \
    -p 18888:18888 \
    -p 4317:18889 \
    -p 4318:18890 \
    -e DASHBOARD__OTLP__CORS__ALLOWEDORIGINS=https://localhost:8080 \
    --name aspire-dashboard \
    mcr.microsoft.com/dotnet/aspire-dashboard:9.0

Föregående kommando kör instrumentpanelscontainern och konfigurerar https://localhost:8080 som ett tillåtet ursprung. Det innebär att en webbläsarapp som används med https://localhost:8080 har behörighet att skicka telemetrin på instrumentpanelen.

Flera ursprung kan tillåtas med ett kommaavgränsat värde. Eller så kan alla ursprung tillåtas med * wildcard. Till exempel DASHBOARD__OTLP__CORS__ALLOWEDORIGINS=*.

Mer information finns i .NET.NET Aspire instrumentpanelskonfiguration: OTLP CORS.

OTLP-slutpunktssäkerhet

OTLP-slutpunkter på instrumentpanelen kan skyddas med API-nyckelautentisering. När det är aktiverat måste HTTP OTLP-begäranden till instrumentpanelen innehålla API-nyckeln i x-otlp-api-key-huvudet. Som standard genereras en ny API-nyckel varje gång instrumentpanelen körs.

API-nyckelautentisering aktiveras automatiskt när kontrollpanelen körs från applikationsvärden. Instrumentpanelsautentisering kan inaktiveras genom att ställa in DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS till true i appvärdens launchSettings- ellerjson-filen.

OTLP-slutpunkter är oskyddade som standard på den fristående instrumentpanelen.

Konfiguration av webbläsarapp

En webbläsarapp använder JavaScript OTEL SDK för att skicka telemetri till instrumentpanelen. Om telemetri ska skickas till instrumentpanelen måste SDK:t vara korrekt konfigurerat.

OTLP-exportör

OTLP-exportörer måste ingå i webbläsarappen och konfigureras med SDK: et. Om du till exempel exporterar distribuerad spårning med OTLP används paketet @opentelemetry/exporter-trace-otlp-proto.

När OTLP läggs till i SDK måste OTLP-alternativ anges. OTLP-alternativ omfattar:

  • url: Adressen som HTTP OTLP-begäranden görs till. Adressen ska vara instrumentpanelens HTTP OTLP-slutpunkt och sökvägen till OTLP HTTP-API:et. Till exempel https://localhost:4318/v1/traces för OTLP-spårexportör. När webbläsarappen startas av appens värd är HTTP OTLP-slutpunkten tillgänglig från miljövariabeln OTEL_EXPORTER_OTLP_ENDPOINT.

  • headers: Rubrikerna som skickas med begäranden. Om API-nyckelautentisering för OTLP-slutpunkt är aktiverat måste x-otlp-api-key-huvudet skickas med OTLP-begäranden. När värdappen startar webbläsarappen är API-nyckeln tillgänglig från miljövariabeln OTEL_EXPORTER_OTLP_HEADERS.

Webbläsarmetadata

När en webbläsarapp har konfigurerats för att samla in distribuerade spårningar kan webbläsarappen ange den överordnade spårningen för en webbläsare med hjälp av meta-elementet i HTML-koden. Värdet för det name="traceparent" metaelementet ska motsvara den aktuella spårningen.

I en .NET-app skulle det överordnade värdet för spårningen förmodas bli tilldelat från Activity.Current och dess Activity.Id-värde skickas som content. Tänk till exempel på följande Razor-kod:

<head>
    @if (Activity.Current is { } currentActivity)
    {
        <meta name="traceparent" content="@currentActivity.Id" />
    }
    <!-- Other elements omitted for brevity... -->
</head>

Föregående kod anger metaelementet traceparent med det aktuella aktivitets-ID:t.

Exempel på telemetrikod för webbläsare

Följande JavaScript-kod visar initieringen av OpenTelemetry JavaScript SDK och sändning av telemetridata till instrumentpanelen:

import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { ZoneContextManager } from '@opentelemetry/context-zone';

export function initializeTelemetry(otlpUrl, headers, resourceAttributes) {
    const otlpOptions = {
        url: `${otlpUrl}/v1/traces`,
        headers: parseDelimitedValues(headers)
    };

    const attributes = parseDelimitedValues(resourceAttributes);
    attributes[SemanticResourceAttributes.SERVICE_NAME] = 'browser';

    const provider = new WebTracerProvider({
        resource: new Resource(attributes),
    });
    provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
    provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter(otlpOptions)));

    provider.register({
        // Prefer ZoneContextManager: supports asynchronous operations
        contextManager: new ZoneContextManager(),
    });

    // Registering instrumentations
    registerInstrumentations({
        instrumentations: [new DocumentLoadInstrumentation()],
    });
}

function parseDelimitedValues(s) {
    const headers = s.split(','); // Split by comma
    const result = {};

    headers.forEach(header => {
        const [key, value] = header.split('='); // Split by equal sign
        result[key.trim()] = value.trim(); // Add to the object, trimming spaces
    });

    return result;
}

Föregående JavaScript-kod definierar en initializeTelemetry funktion som förväntar sig OTLP-slutpunktens URL, rubrikerna och resursattributen. Dessa parametrar tillhandahålls av den förbrukande webbläsarappen som hämtar dem från de miljövariabler som anges av appvärden. Överväg följande Razor-kod:

@using System.Diagnostics
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - BrowserTelemetry</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />

    @if (Activity.Current is { } currentActivity)
    {
        <meta name="traceparent" content="@currentActivity.Id" />
    }
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">BrowserTelemetry</a>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>
    @await RenderSectionAsync("Scripts", required: false)
    <script src="scripts/bundle.js"></script>
    @if (Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") is { Length: > 0 } endpointUrl)
    {
        var headers = Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS");
        var attributes = Environment.GetEnvironmentVariable("OTEL_RESOURCE_ATTRIBUTES");
        <script>
            BrowserTelemetry.initializeTelemetry('@endpointUrl', '@headers', '@attributes');
        </script>
    }
</body>
</html>

Tips

Paketering och minifiering av JavaScript-koden ligger utanför omfånget för den här artikeln.

Det fullständiga arbetsexemplet för hur du konfigurerar JavaScript OTEL SDK för att skicka telemetri till instrumentpanelen finns i webbläsartelemetriexempel.

Se även