全部產品
Search
文件中心

Application Real-Time Monitoring Service:通過OpenTelemetry上報.NET應用資料

更新時間:Aug 08, 2024

通過OpenTelemetry為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用OpenTelemetry為.NET應用進行自動或手動埋點並上報資料。

前提條件

擷取存取點資訊

  1. 登入ARMS控制台,在左側導覽列單擊接入中心

  2. 服務端應用地區單擊OpenTelemetry卡片。

  3. 在彈出的OpenTelemetry面板中選擇資料需要上報的地區。

    說明

    初次接入的地區將會自動進行資源初始化。

  4. 選擇串連方式上報方式,然後複製存取點資訊。

    • 串連方式:若您的服務部署在阿里雲上,且所屬地區與選擇的接入地區一致,推薦使用阿里雲內網方式,否則選擇公網方式。

    • 上報方式:根據用戶端支援的協議類型選擇HTTP或gRPC協議上報資料。

    image.png

背景資訊

OpenTelemetry .NET支援自動埋點和手動埋點。

  • 自動埋點

    • 支援自動埋點的.NET / .NET Framework版本:

      • .NET SDK 6+

      • .NET Framework暫不支援自動埋點

    • 支援的架構請參見OpenTelemetry官方文檔

  • 手動埋點和半自動埋點

樣本Demo

範例程式碼倉庫地址:dotnet-demo

方法一:自動埋點

版本限制

  • .NET SDK 6+

  • .NET Framework暫不支援自動埋點

  1. 使用ASP.NET Core編寫Web應用。

    1. 建立Demo應用。

      mkdir dotnet-simple-demo
      cd dotnet-simple-demo
      dotnet new web
    2. Properties/launchSettings.json檔案中的內容替換成以下配置。

      {
        "$schema": "http://json.schemastore.org/launchsettings.json",
        "profiles": {
          "http": {
            "commandName": "Project",
            "dotnetRunMessages": true,
            "launchBrowser": true,
            "applicationUrl": "http://localhost:8080",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          }
        }
      }
    3. 構建應用。

      dotnet build
  2. 為應用配置自動埋點.

    1. 下載並執行OpenTelemetry .NET自動埋點安裝指令碼。

      curl -L -O https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh
      
      ./otel-dotnet-auto-install.sh
    2. 設定環境變數並運行OpenTelemetry .NET自動埋點指令碼。

      請將<serviceName>替換為您的服務名,請將<endpoint><token>替換為前提條件中擷取的存取點和鑒權Token。

      export OTEL_TRACES_EXPORTER=otlp \
        OTEL_METRICS_EXPORTER=none \
        OTEL_LOGS_EXPORTER=none \
        OTEL_SERVICE_NAME=<serviceName> \
        OTEL_EXPORTER_OTLP_PROTOCOL=grpc
        OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint> \
        OTEL_EXPORTER_OTLP_HEADERS="Authentication=<token>"
      . $HOME/.otel-dotnet-auto/instrument.sh
      說明

      更多OpenTelemetry .NET自動埋點的環境變數配置,請參見OpenTelemetry .NET自動埋點環境變數

  3. 運行並訪問應用。

    1. 運行應用。

      dotnet run
    2. 使用以下命令訪問應用,產生的調用鏈會自動上報至Managed Service for OpenTelemetry

      curl localhost:8080/

方法二:手動埋點

  1. 進入範例程式碼倉庫的dotnet-demo/opentelemetry-demo/manual-demo路徑,然後安裝手動埋點所需的OpenTelemetry相關依賴。

    dotnet add package OpenTelemetry
    dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
    dotnet add package OpenTelemetry.Exporter.Console # 可選,在控制台匯出資料
    dotnet add package OpenTelemetry.Extensions.Hosting
  2. OpentelemetryExporterDemo.cs檔案中建立OpenTelemetry TracerProvider,並添加基於HTTP協議的OtlpExporter,修改上報應用程式名稱和上報資料的Endpoint。

    using System.Diagnostics;
    using OpenTelemetry;
    using OpenTelemetry.Trace;
    using OpenTelemetry.Resources;
    using OpenTelemetry.Exporter;
    
    namespace Demo
    {
        internal static class OpentelemetryExporterDemo
        {
            internal static void Run()
            {
                Console.WriteLine("otlp running");
                // OpenTelemetry上報應用程式名稱
                var serviceName = "otlp-test";
                using var tracerProvider = Sdk.CreateTracerProviderBuilder()
                    .AddSource(serviceName)
                    .SetResourceBuilder(
                    ResourceBuilder.CreateDefault().AddService(serviceName))
                    .AddOtlpExporter(opt =>
                                     {
                                         // 根據前提條件中擷取的存取點資訊進行修改
                                         opt.Endpoint = new Uri("<endpoint>");
                                         // 使用HTTP協議上報資料
                                         opt.Protocol = OtlpExportProtocol.HttpProtobuf;
                                     })
                    .AddConsoleExporter() // 可選,在控制台匯出資料
                    .Build();
                for(int i = 0; i<10; i++)
                {
                    var MyActivitySource = new ActivitySource(serviceName);
                    using var activity = MyActivitySource.StartActivity("SayHello");
                    activity?.SetTag("bar", "Hello World");
                }
            }
        }
    }
  3. 修改Program.cs檔案內容,在Main方法中調用OpentelemetryExporterDemo。

    using System.Diagnostics;
    using System.Net.Http;
    using OpenTelemetry;
    using OpenTelemetry.Resources;
    using OpenTelemetry.Trace;
    
    
    namespace Demo
    {
        public class Otlp
        {
            public static void Main(string[] args)
            {
                OpentelemetryExporterDemo.Run();
            }
        }
    }
  4. 在當前路徑下運行以下命令。

    dotnet run

方法三:半自動埋點

OpenTelemetry支援自動上傳數十種.NET架構Trace的資料,詳細的.NET架構列表請參見Supported Libraries

  1. 進入範例程式碼倉庫的dotnet-demo/opentelemetry-demo/auto-demo路徑,建立ASP.NET Core應用(Web應用)。

    請將代碼中的<your-project-name>替換為實際的應用程式名稱。

    mkdir <your-project-name>
    cd <your-project-name>
    dotnet new mvc
  2. 下載觀測.NET應用必備的OpenTelemetry依賴。

    dotnet add package OpenTelemetry.Exporter.Console # 在控制台匯出採集的資料
    dotnet add package OpenTelemetry.Extensions.Hosting
    dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol # 以OTLP協議匯出
  3. 下載自動埋點依賴。

    下載為ASP.NET Core架構自動埋點的依賴,當應用收到HTTP請求時,會自動產生Span並上報。如需為其他架構自動埋點,請參考Supported Libraries下載對應依賴。

    dotnet add package OpenTelemetry.Instrumentation.AspNetCore
  4. 修改<your-project-name>/Program.cs檔案中的代碼。

    1. 在源檔案開頭匯入所需包。

      using System.Diagnostics;
      using OpenTelemetry.Exporter;
      using OpenTelemetry.Resources;
      using OpenTelemetry.Trace;
    2. 在源檔案末尾添加DiagnosticsConfig類。

      請將代碼中的<your-service-name><your-host-name>替換為實際的服務名和主機名稱。

      public static class DiagnosticsConfig
      {
          public const string ServiceName = "<your-service-name>";
          public const string HostName = "<your-host-name>";
          public static ActivitySource ActivitySource = new ActivitySource(ServiceName);
      }
    3. 添加OpenTelemetry初始化代碼。

      • HTTP協議上報

        請將以下代碼中的<http_endpoint>替換成前提條件中擷取的存取點資訊。

        // ...
        builder.Services.AddOpenTelemetry()
            .WithTracing(tracerProviderBuilder =>
                tracerProviderBuilder
                    .AddSource(DiagnosticsConfig.ActivitySource.Name)
                    .SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder.CreateDefault()
                        .AddAttributes(new Dictionary<string, object> {
                            {"service.name", DiagnosticsConfig.ServiceName},
                            {"host.name",DiagnosticsConfig.HostName}
                        }))
                    .AddAspNetCoreInstrumentation()
                    .AddConsoleExporter() // 在控制台匯出Trace資料,可選
                    .AddOtlpExporter(opt =>
                    {
                        // 使用HTTP協議上報
                        opt.Endpoint = new Uri("<http_endpoint>");
                        opt.Protocol = OtlpExportProtocol.HttpProtobuf;
                    })
             );
        // ...
      • 使用gRPC協議上報

        請將以下代碼中的<grpc_endpoint><token>替換成前提條件中擷取的存取點資訊和Token。

        // ...
        builder.Services.AddOpenTelemetry()
            .WithTracing(tracerProviderBuilder =>
                tracerProviderBuilder
                    .AddSource(DiagnosticsConfig.ActivitySource.Name)
                    .SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder.CreateDefault()
                        .AddAttributes(new Dictionary<string, object> {
                            {"service.name", DiagnosticsConfig.ServiceName},
                            {"host.name",DiagnosticsConfig.HostName}
                        }))
                    .AddAspNetCoreInstrumentation()
                    .AddConsoleExporter() // 在控制台匯出Trace資料,可選
                    .AddOtlpExporter(opt =>
                    {
                        // 使用gRPC協議上報
                        opt.Endpoint = new Uri("<grpc_endpoint>");
                        opt.Headers = "Authentication=<token>";
                        opt.Protocol = OtlpExportProtocol.Grpc;
                    })
             );
        // ...

    展開查看Program.cs完整範例程式碼

    // 引入所需包
    using System.Diagnostics;
    using OpenTelemetry.Exporter;
    using OpenTelemetry.Resources;
    using OpenTelemetry.Trace;
    
    var builder = WebApplication.CreateBuilder(args);
    
    
    builder.Services.AddControllersWithViews();
    
    // OpenTelemetry 初始化
    builder.Services.AddOpenTelemetry()
        .WithTracing(tracerProviderBuilder =>
            tracerProviderBuilder
                .AddSource(DiagnosticsConfig.ActivitySource.Name)
                .SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder.CreateDefault()
                    .AddAttributes(new Dictionary<string, object> {
                        {"service.name", DiagnosticsConfig.ServiceName},
                        {"host.name",DiagnosticsConfig.HostName}
                    }))
                .AddAspNetCoreInstrumentation()
                .AddConsoleExporter() // 在控制台輸出Trace資料,可選
                .AddOtlpExporter(opt =>
                {
                    // 使用HTTP協議上報
                    opt.Endpoint = new Uri("<http_endpoint>");
                    opt.Protocol = OtlpExportProtocol.HttpProtobuf;
    
                    // 使用gRPC協議上報
                    // opt.Endpoint = new Uri("<grpc_endpoint>");
                    // opt.Headers = "Authentication=<token>";
                    // opt.Protocol = OtlpExportProtocol.Grpc;
                })
         );
    
    
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    
    app.Run();
    
    // 建立DiagnosticsConfig類
    public static class DiagnosticsConfig
    {
        public const string ServiceName = "<your-service-name>"; // 服務名
        public const string HostName = "<your-host-name>"; // 主機名稱
        public static ActivitySource ActivitySource = new ActivitySource(ServiceName);
    }
                                
  5. 在終端執行以下命令運行專案。

    dotnet run

    返回樣本:

    在返回資訊中擷取URL,例如http://localhost:5107

    Building...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5107
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Development
    info: Microsoft.Hosting.Lifetime[0]
          Content root path: /path/to/<your-project-name>
  6. 在瀏覽器中訪問http://localhost:5107,返回以下頁面則說明資料已上報至Managed Service for OpenTelemetry控制台。

    返回頁面

查看監控資料

登入ARMS控制台後,在應用監控 > 應用列表頁面選擇目標應用,查看鏈路資料。

說明

語言列顯示image表徵圖的應用為接入應用監控的應用,顯示-表徵圖的應用為接入可觀測鏈路 OpenTelemetry 版的應用。