Aktivieren von Browsertelemetrie
Das .NET.NET Aspire-Dashboard kann so konfiguriert werden, dass Telemetrie empfangen wird, die von Browser-Apps gesendet wird. Dieses Feature ist nützlich, um clientseitige Leistung und Benutzerinteraktionen zu überwachen. Browsertelemetrie erfordert zusätzliche Dashboardkonfiguration und dass das JavaScript OTEL SDK den Browser-Apps hinzugefügt wird.
In diesem Artikel wird erläutert, wie Sie Browsertelemetrie im .NET.NET Aspire-Dashboard aktivieren.
Dashboard-Konfiguration
Für die Browsertelemetrie ist das Dashboard erforderlich, um diese Features zu aktivieren:
- OTLP-HTTP-Endpunkt. Dieser Endpunkt wird vom Dashboard verwendet, um Telemetrie von Browser-Apps zu empfangen.
- Ursprungsübergreifende Ressourcenfreigabe (CORS). CORS ermöglicht Browser-Apps das Senden von Anforderungen an das Dashboard.
OTLP-Konfiguration
Das .NET-.NET Aspire-Dashboard empfängt Telemetrie über OTLP-Endpunkte. HTTP-OTLP-Endpunkte und gRPC-OTLP-Endpunkte werden vom Dashboard unterstützt. Browser-Apps müssen HTTP OLTP verwenden, um Telemetrie an das Dashboard zu senden, da Browser-Apps gRPC nicht unterstützen.
Um die gPRC- oder HTTP-Endpunkte zu konfigurieren, geben Sie die folgenden Umgebungsvariablen an:
-
DOTNET_DASHBOARD_OTLP_ENDPOINT_URL
: Der gRPC-Endpunkt, mit dem das Dashboard eine Verbindung für seine Daten herstellt. -
DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL
: Der HTTP-Endpunkt, mit dem das Dashboard eine Verbindung für seine Daten herstellt.
Die Konfiguration des HTTP OTLP-Endpunkts hängt davon ab, ob das Dashboard vom App-Host gestartet oder eigenständig ausgeführt wird.
OTLP-HTTP mit dem App-Host konfigurieren
Wenn das Dashboard und Ihre App vom App-Host gestartet werden, werden die OTLP-Dashboard-Endpunkte in der launchSettings.json-Datei des App-Hosts konfiguriert.
Betrachten Sie die folgende Beispieldatei 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"
}
}
}
}
Die vorherigen Starteinstellungen JSON Datei konfiguriert alle Profile so, dass sie die DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL
Umgebungsvariable enthalten.
OTLP HTTP mit einem eigenständigen Dashboard konfigurieren
Wenn das Dashboard eigenständig verwendet wird, ohne den Rest von .NET.NET Aspire, ist der OTLP-HTTP-Endpunkt standardmäßig für den Port 18890
aktiviert. Der Port muss jedoch zugeordnet werden, wenn der Dashboardcontainer gestartet wird:
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
Der vorangegangene Befehl führt den Dashboard-Container aus und ordnet gRPC OTLP auf Port 4317
und HTTP OTLP auf Port 4318
zu.
CORS-Konfiguration
Browser-Apps sind standardmäßig daran eingeschränkt, domänenübergreifende API-Aufrufe durchzuführen. Dies wirkt sich auf das Senden von Telemetrie an das Dashboard aus, da sich das Dashboard und die Browser-App immer auf unterschiedlichen Domänen befinden. Durch das Konfigurieren von CORS im .NET.NET Aspire-Dashboard wird die Einschränkung entfernt.
Wenn das Dashboard und Ihre App vom App-Host gestartet werden, ist keine CORS-Konfiguration erforderlich. .NET .NET Aspire konfiguriert das Dashboard automatisch so, dass alle Quellen zulässig sind.
Wenn das Dashboard eigenständig verwendet wird, muss CORS manuell konfiguriert werden. Die Domäne, die zum Anzeigen der Browser-App verwendet wird, muss als zulässiger Ursprung konfiguriert werden, indem die Umgebungsvariable DASHBOARD__OTLP__CORS__ALLOWEDORIGINS
angegeben wird, wenn der Dashboardcontainer gestartet wird:
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
Der obige Befehl führt den Dashboardcontainer aus und konfiguriert https://localhost:8080
als zulässigen Ursprung. Dies bedeutet, dass eine Browser-App, auf die mithilfe von https://localhost:8080
zugegriffen wird, über die Berechtigung zum Senden der Dashboard-Telemetrie verfügt.
Mehrere Ursprünge können mit einem durch Kommas getrennten Wert zulässig sein. Oder alle Ursprünge können mit dem *
-Wildcard zulässig sein. Beispiel: DASHBOARD__OTLP__CORS__ALLOWEDORIGINS=*
.
Weitere Informationen finden Sie unter .NET.NET Aspire Dashboard-Konfiguration: OTLP CORS.
OTLP-Endpunktsicherheit
Dashboard-OTLP-Endpunkte können mit API-Schlüsselauthentifizierung gesichert werden. Wenn aktiviert, müssen HTTP-OTLP-Anforderungen an das Dashboard den API-Schlüssel als Header x-otlp-api-key
enthalten. Standardmäßig wird bei jeder Ausführung des Dashboards ein neuer API-Schlüssel generiert.
Die API-Schlüsselauthentifizierung wird automatisch aktiviert, wenn das Dashboard vom App-Host ausgeführt wird. Die Dashboardauthentifizierung kann durch Festlegen von DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS
auf true
in der launchSettings.json-Datei des App-Hosts deaktiviert werden.
OTLP-Endpunkte sind standardmäßig im eigenständigen Dashboard ungesichert.
Browser-App-Konfiguration
Eine Browser-App verwendet das JavaScript OTEL SDK, um Telemetrie an das Dashboard zu senden. Das erfolgreiche Senden von Telemetrie an das Dashboard erfordert, dass das SDK ordnungsgemäß konfiguriert ist.
OTLP-Exporter
OTLP-Exporteure müssen in der Browser-App enthalten sein und mit dem SDK konfiguriert werden. Der Export von verteiltem Tracing mit OTLP erfolgt über das @opentelemetry/exporter-trace-otlp-proto-Paket.
Wenn OTLP dem SDK hinzugefügt wird, müssen OTLP-Optionen angegeben werden. OTLP-Optionen umfassen:
url
: Die Adresse, an die HTTP OTLP-Anforderungen gesendet werden. Die Adresse sollte der HTTP-OTLP-Endpunkt des Dashboards und der Pfad zur OTLP-HTTP-API sein. Beispiel:https://localhost:4318/v1/traces
für den OTLP-Ablaufverfolgungsexporteur. Wenn die Browser-App vom App-Host gestartet wird, ist der HTTP-OTLP-Endpunkt über die umgebungsvariableOTEL_EXPORTER_OTLP_ENDPOINT
verfügbar.headers
: Die kopfzeilen, die mit Anforderungen gesendet wurden. Wenn die OTLP-Endpunkt-API-Schlüsselauthentifizierung aktiviert ist, muss derx-otlp-api-key
-Header mit OTLP-Anforderungen gesendet werden. Wenn die Browser-App vom App-Host gestartet wird, ist der API-Schlüssel über die umgebungsvariableOTEL_EXPORTER_OTLP_HEADERS
verfügbar.
Browsermetadaten
Wenn eine Browser-App so konfiguriert ist, dass verteilte Traces gesammelt werden, kann die Browser-App den Trace Parent eines Browsers mithilfe des meta
-Elements im HTML-Code setzen. Der Wert des name="traceparent"
Meta-Elements sollte der aktuellen Ablaufverfolgung entsprechen.
In einer .NET-App wird der übergeordnete Wert der Ablaufverfolgung wahrscheinlich vom Activity.Current zugewiesen und deren Activity.Id Wert als content
übergeben. Betrachten Sie beispielsweise den folgenden Razor-Code:
<head>
@if (Activity.Current is { } currentActivity)
{
<meta name="traceparent" content="@currentActivity.Id" />
}
<!-- Other elements omitted for brevity... -->
</head>
Der vorherige Code legt das Metadaten-Element traceparent
auf die ID der aktuellen Aktivität fest.
Beispielcode für Browsertelemetrie
Der folgende JavaScript-Code veranschaulicht die Initialisierung des OpenTelemetry JavaScript SDK und das Senden von Telemetriedaten an das Dashboard:
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;
}
Der vorangehende JavaScript-Code definiert eine initializeTelemetry
-Funktion, die die OTLP-Endpunkt-URL, die Header und die Ressourcenattribute erwartet. Diese Parameter werden von der verbrauchenden Browser-App bereitgestellt, die sie aus den vom App-Host festgelegten Umgebungsvariablen abruft. Beachten Sie den folgenden Razor-Code:
@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>
Trinkgeld
Die Bündelung und Minimierung des JavaScript-Codes geht über den Rahmen dieses Artikels hinaus.
Das vollständige Beispiel, um das JavaScript OTEL-SDK so zu konfigurieren, dass Telemetrie an das Dashboard gesendet wird, finden Sie im Browser-Telemetrie-Beispiel.