在使用可观测链路 OpenTelemetry 版控制台追踪应用的链路数据之前,需要通过客户端将应用数据上报至可观测链路 OpenTelemetry 版。本文介绍如何通过OpenTelemetry客户端上报 .NET应用数据(此方法同样适用于使用C#语言开发的应用)。

前提条件

获取接入点信息
  1. 登录ARMS控制台,在左侧导航栏选择应用监控 > 应用列表
  2. 应用列表页面顶部选择目标地域,然后单击目标应用名称。
    说明 语言列显示Java图标图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。
  3. 在弹出的页面中,单击左侧导航栏上方的返回图标图标,返回上一层。
  4. 在左侧导航栏单击集群配置,然后在右侧页面单击接入点信息页签。
  5. 在页面顶部选择需要接入的地域,然后在集群信息区域打开显示Token开关。
  6. 客户端采集工具区域单击OpenTelemetry
    在下方表格的相关信息列中,获取接入点信息。OT接入点信息
    说明 如果应用部署于阿里云生产环境,则选择阿里云VPC网络接入点,否则选择公网接入点。

示例Demo

示例代码仓库地址:dotnet-demo

方法一:使用OpenTelemetry .NET SDK手动埋点

  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 --prerelease
  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,返回以下页面则说明数据已上报至可观测链路 OpenTelemetry 版控制台。
    返回页面

查看监控数据

登录ARMS控制台后,在应用监控 > 应用列表页面选择目标应用,查看链路数据。
说明 语言列显示Java图标图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。