共用方式為


啟用瀏覽器遙測

.NET .NET Aspire 儀錶板可以設定為接收從瀏覽器應用程式傳送的遙測。 這項功能適用於監視 client端效能和用戶互動。 瀏覽器的遙測需要額外配置儀表板,並且在瀏覽器應用程式中新增 JavaScript OTEL SDK

本文討論如何在 .NET.NET Aspire 儀錶板中啟用瀏覽器遙測。

儀錶板設定

瀏覽器遙測需要儀錶板才能啟用這些功能:

  • OTLP HTTP 端點。 儀錶板會使用此端點從瀏覽器應用程式接收遙測。
  • 跨原始來源資源分享 (CORS)。 CORS 可讓瀏覽器應用程式向儀錶板提出要求。

OTLP 組態

.NET .NET Aspire 儀錶板會透過OTLP端點接收遙測。 儀錶板支援 HTTP OTLP 端點 和 gRPC OTLP 端點。 瀏覽器應用程式必須使用 HTTP OLTP 將遙測傳送至儀錶板,因為瀏覽器應用程式不支援 gRPC。

若要設定 gPRC 或 HTTP 端點,請指定下列環境變數:

  • DOTNET_DASHBOARD_OTLP_ENDPOINT_URL:儀錶板連線至其數據的 gRPC 端點。
  • DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL:儀表板連接以擷取數據的 HTTP 端點。

HTTP OTLP 端點的設定取決於儀錶板是由應用程式主機啟動還是獨立執行。

使用應用程式主機配置 OTLP HTTP

如果儀錶板和您的應用程式是由應用程式主機啟動,儀錶板 OTLP 端點會在應用程式主機的 launchSettings 中設定。json 檔案。

請參考以下範例 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"
      }
    }
  }
}

前述的啟動配置 JSON 檔案會將所有配置檔設為包含 DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL 環境變數。

使用獨立儀表板設定 OTLP HTTP

如果儀錶板是獨立使用,而沒有 .NET Aspire的 rest,則預設會在埠 18890上啟用 OTLP HTTP 端點。 不過,當儀錶板容器啟動時,必須映射埠。

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

上述命令會執行儀錶板容器,並將 gRPC OTLP 對應至埠 4317,並將 HTTP OTLP 對應至埠 4318

CORS 設定

根據預設,瀏覽器應用程式會限制進行跨網域 API 呼叫。 這會影響將遙測傳送至儀錶板,因為儀錶板和瀏覽器應用程式一律位於不同的網域上。 在 .NET.NET Aspire 儀錶板中設定CORS會移除限制。

如果儀錶板和您的應用程式是由應用程式主機啟動,則不需要 CORS 設定。 .NET .NET Aspire 會自動設定控制面板以允許所有資源來源。

如果儀錶板是獨立使用,則必須手動設定 CORS。 用來檢視瀏覽器應用程式的網域必須設定為允許的來源,方法是在儀錶板容器啟動時指定 DASHBOARD__OTLP__CORS__ALLOWEDORIGINS 環境變數:

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

上述命令會執行儀錶板容器,並將 https://localhost:8080 設定為允許的來源。 這表示透過 https://localhost:8080 存取的瀏覽器應用程式有權限發送儀表板遙測數據。

您可以使用逗號分隔值來允許多個原始來源。 或者,可以允許所有來源使用 * 通配符。 例如,DASHBOARD__OTLP__CORS__ALLOWEDORIGINS=*

如需詳細資訊,請參閱 .NET.NET Aspire 儀錶板設定:OTLP CORS

OTLP 端點安全性

儀錶板 OTLP 端點可以使用 API 金鑰驗證來保護。 啟用時,對儀錶板的 HTTP OTLP 要求必須包含 API 金鑰作為 x-otlp-api-key 標頭。 根據預設,每次執行儀錶板時,都會產生新的 API 金鑰。

從應用程式主機執行儀錶板時,會自動啟用 API 金鑰驗證。 您可以將應用程式主機 launchSettings 中的 DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS 設定為 true,以停用儀錶板驗證。此設定位於json 檔案中。

根據預設,獨立儀錶板中的 OTLP 端點不安全。

瀏覽器應用程式設定

瀏覽器應用程式會使用 JavaScript OTEL SDK,將遙測資料傳送至儀表板。 若要成功將遙測數據傳送至儀錶板,必須正確設定 SDK。

OTLP 匯出器

OTLP 匯出工具必須包含在瀏覽器應用程式中,並使用 SDK 進行設定。 例如,使用 OTLP 匯出分散式追蹤會使用 @opentelemetry/exporter-trace-otlp-proto 套件。

將 OTLP 新增至 SDK 時,必須指定 OTLP 選項。 OTLP 選項包括:

  • url:發送 HTTP OTLP 請求的位址。 地址應該是儀表板的 HTTP OTLP 端點和 OTLP HTTP API 的路徑。 例如,https://localhost:4318/v1/traces 代表追蹤系統中的 OTLP 匯出工具。 如果應用程式主機啟動瀏覽器應用程式,則可從 OTEL_EXPORTER_OTLP_ENDPOINT 環境變數取得 HTTP OTLP 端點。

  • headers:使用要求傳送的標頭。 如果啟用了 OTLP 端點 API 金鑰驗證,必須隨 OTLP 請求傳送 x-otlp-api-key 標頭。 如果瀏覽器應用程式是由應用程式主機啟動,則 API 金鑰可從 OTEL_EXPORTER_OTLP_HEADERS 環境變數取得。

瀏覽器元數據

當瀏覽器應用程式設定為收集分散式追蹤時,瀏覽器應用程式可以使用 HTML 中的 meta 元素來設定瀏覽器範圍的追蹤父代。 name="traceparent" 中繼資料元素的值應該對應至目前的追蹤。

例如,在 .NET 應用程式中,追蹤父值可能會從 Activity.Current 指派,並將其 Activity.Id 值傳遞為 content。 例如,請考慮下列 Razor 程式碼:

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

上述程式代碼會將 traceparent 中繼元素設定為目前的活動 ID。

瀏覽器遙測程式代碼範例

下列 JavaScript 程式代碼示範 OpenTelemetry JavaScript SDK 的初始化,以及將遙測數據傳送至儀錶板:

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

上述 JavaScript 程式碼定義了一個 initializeTelemetry 函式,該函式需要 OTLP 端點 URL、標頭和資源屬性。 這些參數是由取用的瀏覽器應用程式提供,可從應用程式主機所設定的環境變數提取這些參數。 請考慮下列 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>

提示

JavaScript 程式代碼的統合和縮製已超出本文的範圍。

如需設定 JavaScript OTEL SDK 將遙測資料傳送至儀錶板的完整範例,請參閱 瀏覽器遙測範例

另請參閱