Compartir a través de


Habilitación de la telemetría del explorador

El panel de .NET.NET Aspire se puede configurar para recibir datos de telemetría enviados desde aplicaciones del explorador. Esta característica es útil para supervisar el rendimiento del lado clienty las interacciones del usuario. La telemetría del navegador requiere una configuración adicional del panel y que el SDK de OTEL de JavaScript se añade a las aplicaciones del navegador.

En este artículo se describe cómo habilitar la telemetría del explorador en el panel de .NET.NET Aspire.

Configuración del panel

La telemetría del explorador requiere que el panel habilite estas características:

  • Punto de conexión HTTP de OTLP. El tablero de control utiliza este punto de conexión para recibir telemetría de aplicaciones de navegador.
  • Uso compartido de recursos entre orígenes (CORS). CORS permite que las aplicaciones del explorador realicen solicitudes en el panel.

Configuración de OTLP

El panel de .NET.NET Aspire recibe telemetría a través de puntos de conexión de OTLP. los puntos de conexión de OTLP HTTP y los puntos de conexión de OTLP gRPC son compatibles con el panel. Las aplicaciones del explorador deben usar HTTP OLTP para enviar telemetría al panel porque las aplicaciones del explorador no admiten gRPC.

Para configurar los puntos de conexión gPRC o HTTP, especifique las siguientes variables de entorno:

  • DOTNET_DASHBOARD_OTLP_ENDPOINT_URL: El punto de conexión gRPC al que se conecta el tablero para obtener sus datos.
  • DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL: punto de conexión HTTP al que se conecta el panel para sus datos.

La configuración del punto de conexión OTLP HTTP depende de si el host de la aplicación inicia el panel o se ejecuta de forma independiente.

Configurar OTLP HTTP con el host de la aplicación

Si el host de la aplicación inicia el panel y la aplicación, los puntos de conexión de OTLP del panel se configuran en el launchSettings del host de la aplicación.json archivo.

Considere el siguiente ejemplo de archivo JSON:

{
  "$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"
      }
    }
  }
}

La configuración de inicio anterior JSON archivo configura todos los perfiles para incluir la variable de entorno DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL.

Configurar HTTP OTLP con un panel de control independiente

Si el panel se usa de forma independiente, sin el rest de .NET Aspire, el punto de conexión HTTP de OTLP está habilitado de forma predeterminada en el puerto 18890. Sin embargo, el puerto debe asignarse cuando se inicia el contenedor del panel:

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

El comando anterior ejecuta el contenedor del panel y asigna gRPC OTLP al puerto 4317 y HTTP OTLP al puerto 4318.

Configuración de CORS

De forma predeterminada, las aplicaciones del explorador están restringidas a realizar llamadas API entre dominios. Esto afecta al envío de telemetría al panel porque el panel y la aplicación del explorador siempre están en dominios diferentes. La configuración de CORS en el panel de .NET.NET Aspire quita la restricción.

Si el host de la aplicación inicia el panel y la aplicación, no se requiere ninguna configuración de CORS. .NET .NET Aspire configura automáticamente el panel para permitir todos los orígenes de recursos.

Si el panel se usa de forma independiente, CORS debe configurarse manualmente. El dominio que se usa para ver la aplicación del explorador debe configurarse como origen permitido especificando la variable de entorno DASHBOARD__OTLP__CORS__ALLOWEDORIGINS cuando se inicia el contenedor del panel:

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

El comando anterior ejecuta el contenedor del panel y configura https://localhost:8080 como origen permitido. Esto significa que una aplicación del explorador a la que se accede mediante https://localhost:8080 tiene permiso para enviar la telemetría del panel.

Se pueden permitir varios orígenes con un valor separado por comas. También se pueden permitir todos los orígenes con el carácter comodín *. Por ejemplo, DASHBOARD__OTLP__CORS__ALLOWEDORIGINS=*.

Para obtener más información, consulte .NET.NET Aspire configuración del panel: OTLP CORS.

Seguridad del punto de conexión de OTLP

Los puntos de conexión del panel OTLP se pueden proteger con la autenticación de clave API. Cuando están habilitadas, las solicitudes OTLP HTTP al panel deben incluir la clave de API en el encabezado x-otlp-api-key. De forma predeterminada, se genera una nueva clave de API cada vez que se ejecuta el panel.

La autenticación de clave de API se habilita automáticamente cuando el panel se ejecuta desde el host de la aplicación. La autenticación del panel se puede deshabilitar estableciendo DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS en true en el launchSettings del host de la aplicación.json archivo.

Los puntos de conexión de OTLP no están seguros de forma predeterminada en el panel independiente.

Configuración de la aplicación del explorador

Una aplicación de navegador usa la SDK de OTEL de JavaScript para enviar telemetría al panel. El envío correcto de telemetría al panel requiere que el SDK esté configurado correctamente.

Exportador de OTLP

Los exportadores de OTLP deben incluirse en la aplicación del explorador y configurarse con el SDK. Por ejemplo, exportar el seguimiento distribuido con OTLP usa el paquete @opentelemetry/exporter-trace-otlp-proto.

Cuando se agrega OTLP al SDK, se deben especificar las opciones de OTLP. Las opciones de OTLP incluyen:

  • url: la dirección a la que se realizan las solicitudes OTLP HTTP. La dirección debe ser el punto de conexión HTTP OTLP del panel y la ruta de acceso a la API HTTP de OTLP. Por ejemplo, https://localhost:4318/v1/traces para el exportador de rastreo OTLP. Si el host de la aplicación inicia la aplicación del explorador, el punto de conexión de OTLP HTTP está disponible en la variable de entorno OTEL_EXPORTER_OTLP_ENDPOINT.

  • headers: los encabezados enviados con solicitudes. Si está habilitada la autenticación de la clave de API del punto de conexión OTLP, se debe enviar el encabezado x-otlp-api-key en las solicitudes OTLP. Si el host de la aplicación inicia la aplicación del explorador, la clave de API está disponible en la variable de entorno OTEL_EXPORTER_OTLP_HEADERS.

Metadatos del explorador

Cuando se configura una aplicación de explorador para recopilar seguimientos distribuidos, la aplicación del explorador puede establecer los intervalos de seguimiento primarios de un explorador mediante el elemento meta en el CÓDIGO HTML. El valor del elemento meta name="traceparent" debe corresponder con la traza actual.

En una aplicación de .NET, por ejemplo, es probable que el valor primario de seguimiento se asigne desde el Activity.Current y pase su valor de Activity.Id como content. Por ejemplo, considere el siguiente código de Razor:

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

El código anterior establece el elemento meta traceparent en el ID de la actividad actual.

Código de telemetría del explorador de ejemplo

El código JavaScript siguiente muestra la inicialización del SDK de JavaScript OpenTelemetry y el envío de datos de telemetría al panel:

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

El código javaScript anterior define una función initializeTelemetry que espera la dirección URL del punto de conexión de OTLP, los encabezados y los atributos de recurso. Estos parámetros son proporcionados por la aplicación de navegador que los extrae de las variables de entorno establecidas por el anfitrión de la aplicación. Tenga en cuenta el siguiente código de Razor:

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

Propina

La agrupación y la minificación del código JavaScript están fuera del ámbito de este artículo.

Para obtener el ejemplo de trabajo completo de cómo configurar el SDK de OTEL de JavaScript para enviar telemetría al panel, consulte el ejemplo de telemetría del explorador .

Consulte también