说明:
- OpenTelemetry 是工具、API 和 SDK 的集合,用于检测、生成、收集和导出遥测数据(指标、日志和跟踪),帮助用户分析软件的性能和行为。关于 OpenTelemetry 的更多信息请参考 OpenTelemetry 官方网站。
- OpenTelemetry 社区活跃,技术更迭迅速,广泛兼容主流编程语言、组件与框架,为云原生微服务以及容器架构的链路追踪能力广受欢迎。
OpenTelemetry-dotnet 方案对于 .NET 的常用依赖以及框架,包括 ASPNET、HTTPCLIENT、MYSQLCONNECTOR 等,提供了自动接入,在不需要修改代码的情况下就能实现链路信息的上报。其他支持自动接入的依赖库和框架请参考 OpenTelemetry 社区提供的 完整列表。本文将为您介绍如何使用 OpenTelemetry .NET SDK 接入 .NET 应用数据。
前提条件
OpenTelemetry .NET 支持自动接入和手动接入。
自动接入
- 支持自动接入的版本:
- .NET SDK ≥ 6
- .NET Framework 暂不支持自动接入
- 支持自动接入的框架请参见 OpenTelemetry官方文档 。
手动接入
- 支持手动接入的版本:
- .NET ≥ 5.0
- .NET Core ≥ 2.0
- .NET Framework ≥ 4.6.1
- 支持手动接入的框架请参见 OpenTelemetry官方文档 。
Demo 应用
示例代码 Program.cs 是一个 WebApplication 使用 MySQLConnector 连接 MySQL 数据库操作,对应的 MySQL 务请自行搭建,或直接创建云产品实例。
初始化应用。
dotnet new web引入 Demo 中用到的依赖包。
其中Microsoft.Extensions.Logging.Abstractions是MySqlConnector所必需的包。dotnet add package MySqlConnector; dotnet add package Microsoft.Extensions.Logging.Abstractions;修改
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" } } } }编写业务代码
Program.csProgram.cs中使用 WebApplication 接口模拟使用 MySQLConnector 连接 MySQL 数据库操作。using MySqlConnector; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.MapGet("/todo", () => { string connectionString = "server=localhost;port=3306;User Id=root;password=;Database=MyDB"; using (MySqlConnection myConnnect = new MySqlConnection(connectionString)) { try { myConnnect.Open(); using (MySqlCommand myCmd = new MySqlCommand("select * from MyTable", myConnnect)) { using (MySqlDataReader reader = myCmd.ExecuteReader()) { List<Int32> results = new List<Int32>(); while (reader.Read()) { // 假设我们只处理第一列的数据ID results.Add(reader.GetInt32(0)); } return "ids:" + string.Join(", ", results); } } } catch (Exception ex) { Console.WriteLine($"数据库操作出错: {ex.Message}"); return "数据库操作出错"; } } }); app.Run();
前置步骤:获取接入点和 Token
- 在左侧菜单栏中选择应用性能监控 > 应用列表,单击接入应用。
- 在右侧弹出的数据接入抽屉框中,单击 .NET 语言。
- 在接入 .NET 应用页面,选择您所要接入的地域以及业务系统。
- 选择接入协议类型为 OpenTelemetry。
- 上报方式选择您所想要的上报方式,获取您的接入点和 Token。
说明:
- 内网上报:使用此上报方式,您的服务需运行在云平台VPC。通过 VPC 直接联通,在避免外网通信的安全风险同时,可以节省上报流量开销。
- 外网上报:当您的服务部署在本地或非云平台VPC 内,可以通过此方式上报数据。请注意外网通信存在安全风险,同时也会造成一定上报流量。
自动接入方案(推荐)
步骤1:安装 opentelemetry-dotnet-instrumentation
下载并执行 OpenTelemetry .NET 自动埋点安装脚本。
curl -L -O https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh chmod -x otel-dotnet-auto-install.sh sh ./otel-dotnet-auto-install.sh设置环境变量并运行 OpenTelemetry .NET 自动埋点脚本。
chmod -x $HOME/.otel-dotnet-auto/instrument.sh export OTEL_TRACES_EXPORTER=otlp \ OTEL_METRICS_EXPORTER=none \ OTEL_LOGS_EXPORTER=none \ OTEL_SERVICE_NAME=<service-name> \ # 此处<service-name>改为自定义服务名 OTEL_EXPORTER_OTLP_PROTOCOL=grpc \ OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint> \ # 此处替换成步骤1中获得的接入点 OTEL_RESOURCE_ATTRIBUTES="token=<token>" # 此处替换成步骤1中获得的token . $HOME/.otel-dotnet-auto/instrument.sh说明:
如果在 macOS 上安装 opentelemetry-dotnet-instrumentation,需要额外安装 coreutils 工具。
brew install coreutils
步骤2:运行应用
构建并运行应用。
dotnet build dotnet run在浏览器中访问以下链接:
http://localhost:8080 http://localhost:8080/todo每次进入该页面,OpenTelemetry 都会自动创建 Trace,并将链路数据上报至 APM。
接入验证
启动 .NET 应用后,通过8080端口访问对应的接口,例如 https://localhost:8080/todo。在有正常流量的情况下,应用性能监控 > 应用监控 > 应用列表 中将展示接入的应用,应用性能监控 > 应用监控 > 应用详情 > 实例监控中将展示接入的应用实例。由于可观测数据的处理存在一定延时,如果接入后在控制台没有查询到应用或实例,请等待30秒左右。
自定义埋点(可选)
当自动埋点不满足您的场景或者需要增加业务层埋点时,您可参照下述内容,使用 opentelemetry-dotnet-instrumentation 添加自定义埋点。本文仅展示最基本的自定义埋点方式,OpenTelemetry 社区提供了更多灵活的自定义埋点方式,具体使用方法可参考 OpenTelemetry 社区提供的 .NET 自定义埋点文档。
引入 System.Diagnostics.DiagnosticSource 依赖包
dotnet add package System.Diagnostics.DiagnosticSource
创建 ActivitySource 实例
private static readonly ActivitySource RegisteredActivity = new ActivitySource("Examples.ManualInstrumentations.Registered");
创建 Activity
using (var activity = RegisteredActivity.StartActivity("Main"))
{
// 添加 Activity Tag
activity?.SetTag("key", "3.1415");
// 为 Activity 添加一个 Event
activity?.AddEvent(new("something happened"));
// 一些业务代码
Thread.Sleep(1000);
}
在 OpenTelemetry.AutoInstrumentation 中注册 ActivitySource
在环境变量中设置 OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES,没有通过该配置注册的 ActivitySource 将不会接入上报。
export OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES=Examples.ManualInstrumentations.Registered
手动接入方案
若 .NET SDK 版本不大于6或使用 .NET Framework ,但能满足手动接入条件,可以选择手动接入上报。本文仅展示最基本的手动埋点方式,OpenTelemetry 社区提供了更多灵活的手动埋点方式,具体使用方法可参考 OpenTelemetry 社区提供的 .NET 手动接入文档。
步骤一:安装手动接入所需的 OpenTelemetry 相关依赖
安装手动接入所需的 OpenTelemetry 相关依赖。
dotnet add package OpenTelemetry dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol dotnet add package OpenTelemetry.Extensions.Hosting如果是基于 ASP.NET Core 的应用,还需要引入 OpenTelemetry.Instrumentation.AspNetCore 依赖。
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
步骤二:初始化 OpenTelemtry SDK
创建一个
tracerProvider并确保添加以下代码在您的程序开始处。var serviceName = "<service-name>"; // <service-name>替换成自定义服务名 using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource(serviceName) .SetResourceBuilder( ResourceBuilder.CreateDefault().AddService(serviceName) .AddAttributes(new Dictionary<string, object> { ["token"] = "<token>", // <token>替换成前置步骤中获得的 Token ["host.name"] = "<host>" // <host>替换成自定义主机名 })) .AddOtlpExporter(opt => { opt.Endpoint = new Uri("<endpoint>"); // <endpoint>替换成前置步骤中获得的接入点信息 opt.Protocol = OtlpExportProtocol.Grpc; }) .Build();
步骤三:修改应用代码,使用 ActivitySource 创建 Activity
在应用任意需要手动接入的地方,创建一个
ActivitySource用于创建Activity。
其用途相当于可观测领域的 Tracer 。var MyActivitySource = new ActivitySource(serviceName);当
ActivitySource创建好后,创建一个Activity。
其用途相当于可观测领域的 Span 。using var activity = MyActivitySource.StartActivity("SayHello"); // 添加 Activity Tag activity?.SetTag("key", "3.1415"); // 为 Activity 添加一个 Event activity?.AddEvent(new("something happened"));
步骤四:运行程序
构建并运行应用。
dotnet build
dotnet run
接入验证
运行 .NET 应用,在有正常流量的情况下,应用性能监控 > 应用监控 > 应用列表 中将展示接入的应用,应用性能监控 > 应用监控 > 应用详情 > 实例监控中将展示接入的应用实例。由于可观测数据的处理存在一定延时,如果接入后在控制台没有查询到应用或实例,请等待30秒左右。