我们很高兴地宣布推出新的 Elastic® OpenTelemetry SDK for .NET 发行版的 alpha 版本。在这篇文章中,我们将介绍一些您可能对这个新发行版产生的合理问题。
如果您想试用这个早期访问版本,请立即下载 NuGet 包。我们欢迎所有反馈和建议,以帮助我们在稳定版本发布之前增强发行版。
查看我们的公告博客文章,了解有关 OpenTelemetry 以及我们决定推出 OpenTelemetry 发行版的更多信息。
Elastic .NET OpenTelemetry 发行版
随着 Elastic .NET OpenTelemetry SDK 发行版的 alpha 版本发布,我们正在将 OpenTelemetry 作为检测 .NET 应用程序的首选和推荐选择。
在 .NET 中,运行时基类库 (BCL) 包括专为原生 OpenTelemetry 检测而设计的类型,例如 Activity 和 Meter,这使得采用 OpenTelemetry 原生检测更加方便。
我们当前发行版的 alpha 版本有意限制了功能。我们的目标是评估 API 设计和易用性的适用性,为未来发展奠定坚实的基础。我们承认它可能不适用于所有应用程序场景,因此,虽然我们欢迎开发人员安装它进行试用,但我们目前不建议将其用于生产环境。
在后续版本中,我们计划在朝着与现有的 Elastic APM .NET 代理实现功能对等的目标前进时添加更多功能。根据用户反馈,我们将改进 API 并朝着稳定版本发展。在此之前,我们可能需要进行一些破坏性的 API 更改来支持其他用例。
当前的 alpha 版本支持在典型的现代工作负载(例如 ASP.NET Core 和 worker 服务)中进行安装。它最适合现代 .NET 运行时 .NET 6.0 及更高版本。我们很乐意听取您认为我们接下来应该关注的其他场景。
我们在发行版中引入的类型旨在支持从“vanilla” OpenTelemetry SDK 轻松切换,而无需(或只需极少)代码更改。我们预计在大多数情况下,只需添加 NuGet 包即可开始使用。
最初的 alpha 版本在 OpenTelemetry 的“vanilla” SDK 之上添加的内容非常少,但是通过尽早采用它,您可以塑造它的发展方向。我们将在后续版本中为开发人员提供有价值的增强功能。
如果您想关注发行版的开发,该代码是完全开源的,并且可在 GitHub 上获取。我们鼓励您针对遇到的错误或可用性痛点提出问题。
如何开始使用?
开始使用 Elastic OpenTelemetry 发行版非常容易。只需将 Elastic OpenTelemetry NuGet 包的引用添加到您的项目中即可。这可以通过将包引用添加到项目 (csproj) 文件来实现。
<PackageReference Include="Elastic.OpenTelemetry" Version="1.0.0-alpha.1" />
添加包引用后,您可以在应用程序中使用 Elastic OpenTelemetry 发行版。该发行版包含 OpenTelemetry SDK 的传递依赖项,因此您无需将 OpenTelemetry SDK 包添加到您的项目中。这样做不会造成任何危害,并且可以用于在 Elastic 发行版引用它们之前选择加入较新的 SDK 版本。
Elastic OpenTelemetry 发行版旨在易于使用并集成到您的应用程序中,包括那些以前直接使用 OpenTelemetry SDK 的应用程序。当已经使用 OpenTelemetry SDK 时,唯一需要的更改是将 Elastic.OpenTelemetry NuGet 包添加到项目中。这样做将自动切换到 Elastic 发行版提供的固化配置。
ASP.NET Core 示例
一个常见的需求是基于 Microsoft.Extensions.Hosting 库检测 ASP.NET Core 应用程序,该库通过 IServiceProvider 提供依赖项注入。
OpenTelemetry SDK 和 Elastic 发行版都包含扩展方法,可以通过添加几行代码来启用应用程序中的可观测性功能。
此示例重点介绍如何使用 Elastic OpenTelemetry 发行版将检测添加到 ASP.NET Core 最小 API 应用程序。类似的步骤也适用于检测其他 ASP.NET Core 工作负载和基于主机(如 Worker 服务)的应用程序。
注意:此示例假设我们从使用 .NET 8 SDK 提供的项目模板创建的新 最小 API 项目开始。它还使用单个 Program.cs 文件中的顶级语句。
将 Elastic.OpenTelemetry 包引用添加到项目 (csproj) 文件中。
<PackageReference Include="Elastic.OpenTelemetry" Version="1.0.0-alpha.1" />
要利用 ASP.NET Core 的 OpenTelemetry SDK 检测,还请添加 OpenTelemetry.Instrumentation.AspNetCore NuGet 包。
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.7.1" />
此包包括支持为 ASP.NET Core 端点处理的请求收集检测(跟踪和指标)。
在 ASP.NET Core 应用程序的 Program.cs 文件中,添加以下两个 using 指令
using OpenTelemetry;
using OpenTelemetry.Trace;
OpenTelemetry SDK 在 IServiceCollection 上包含扩展方法,以启用和配置跟踪、指标和日志提供程序。Elastic 发行版会覆盖默认的 SDK 注册,添加几个固化默认值。
在最小 API 模板中,WebApplicationBuilder 公开了一个 Services 属性,该属性可用于向依赖项注入容器注册服务。确保注册 OpenTelemetry SDK 以启用跟踪和指标收集。
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddHttpClient() // <1>
.AddOpenTelemetry() // <2>
.WithTracing(t => t.AddAspNetCoreInstrumentation()); // <3>
<1> AddHttpClient 向依赖注入容器注册 IHttpClientFactory 服务。 这不是启用 OpenTelemetry 所必需的,但示例终结点将使用它来发送 HTTP 请求。
<2> AddOpenTelemetry 向依赖注入容器注册 OpenTelemetry SDK。如果可用,Elastic 发行版将覆盖此设置,以添加固定的默认值。
<3> 配置 OpenTelemetry 跟踪,以收集 ASP.NET Core 生成的跟踪和指标数据。
通过对 Program.cs 文件进行这些有限的更改,应用程序现在已配置为使用 OpenTelemetry SDK 和 Elastic 发行版来收集跟踪和指标,这些跟踪和指标通过 OTLP 导出。
为了演示跟踪功能,我们将通过 WebApplication 为 API 定义一个终结点。
var app = builder.Build();
app.UseHttpsRedirection();
app.MapGet("/", (IHttpClientFactory httpClientFactory) =>
Api.HandleRoot(httpClientFactory)); // <1>
app.Run();
<1> 映射一个处理对应用程序根 URL 路径的请求的终结点。处理程序将由我们还需要添加到应用程序的静态类提供。它接受一个 IHttpClientFactory 作为参数,该参数将在运行时从依赖注入容器中注入,并作为参数传递给 HandleRoot 方法。
namespace Example.Api
{
internal static class Api
{
public static async Task<IResult> HandleRoot(IHttpClientFactory httpClientFactory)
{
using var client = httpClientFactory.CreateClient();
await Task.Delay(100); // simulate work
var response = await client.GetAsync("https://elastic.ac.cn"); // <1>
await Task.Delay(50); // simulate work
return response.StatusCode == System.Net.HttpStatusCode.OK ? Results.Ok() : Results.StatusCode(500);
}
}
}
<1> 此 URL 将需要两次重定向,以便我们可以在跟踪中看到多个 span。
此静态类包含一个 HandleRoot 方法,该方法与终结点处理程序委托的签名匹配。
从工厂创建一个 HttpClient 后,它会向 elastic.co 网站发送 GET 请求。请求的任一侧都有一个延迟,此处用于模拟正在执行的某些业务逻辑。该方法根据外部 HTTP 请求的结果返回一个适当的状态代码。
如果您正在按照操作进行,还需要在 Program.cs 文件中包含 Example.Api 命名空间的 using 指令。
using Example.Api;
这就是我们现在需要的所有代码。Elastic 发行版将自动启用通过 OTLP 导出器导出遥测信号。OTLP 导出器要求配置终结点。配置终结点的常见机制是通过环境变量。
此演示使用 Elastic Cloud 部署作为我们可观测数据的目标。要从 Elastic Cloud 中运行的 Kibana® 检索终结点信息,请导航到可观测性设置指南。选择 OpenTelemetry 选项以查看应提供给应用程序的配置详细信息。
在 launchSettings.json 中或在应用程序运行的环境中为应用程序配置环境变量。授权标头持有者令牌应安全地存储在用户机密或合适的密钥保管库系统中。
至少,我们必须配置两个环境变量
-
OTEL_EXPORTER_OTLP_ENDPOINT
-
OTLP_EXPORTER_OTLP_HEADERS
还强烈建议使用 OTEL_RESOURCE_ATTRIBUTES 环境变量为应用程序配置至少一个描述性服务名称,否则将应用通用默认值。例如
"OTEL_RESOURCE_ATTRIBUTES": "service.name=minimal-api-example"
可以并且应该根据需要添加其他资源标记,例如版本。您可以在OpenTelemetry .NET SDK 文档中阅读有关配置资源属性的选项的更多信息。
配置完成后,运行应用程序并向其根终结点发送 HTTP 请求。将生成一个跟踪并将其导出到配置的 OTLP 终结点。
要查看跟踪,可以使用 Elastic APM Kibana UI。从 Kibana 主页,访问可观测性区域,并从 APM > 跟踪页面下的跟踪中访问。选择适当的时间范围并选择名为“GET /”的跟踪后,您将能够浏览一个或多个跟踪样本。
以上跟踪演示了 OpenTelemetry SDK 提供的内置检测集合和我们添加的可选 OpenTelemetry.Instrumentation.AspNetCore 包。
需要强调的是,如果我们使用没有 Elastic 发行版的“vanilla” SDK,我们将看到不同的跟踪。屏幕截图中蓝色显示的 HTTP span 将不会显示。默认情况下,OpenTelemetry SDK 不启用 HTTP 检测,并且需要额外的代码来配置出站 HTTP 请求的检测。Elastic 发行版认为应捕获 HTTP span 并默认启用此功能。
也可以向此应用程序添加特定于应用程序的检测。通常,这将需要调用特定于供应商的 API,例如 Elastic APM Agent 中的tracer API。选择 OpenTelemetry 的一个重要好处是能够使用与供应商无关的 API 来检测代码,而无需锁定供应商。我们可以通过更新示例中的 API 类来看到实际效果。
internal static class Api
{
public static string ActivitySourceName = "CustomActivitySource";
private static readonly ActivitySource ActivitySource = new(ActivitySourceName);
public static async Task<IResult> HandleRoot(IHttpClientFactory httpClientFactory)
{
using var activity = ActivitySource.StartActivity("DoingStuff", ActivityKind.Internal);
activity?.SetTag("custom-tag", "TagValue");
using var client = httpClientFactory.CreateClient();
await Task.Delay(100);
var response = await client.GetAsync("https://elastic.ac.cn"); // using this URL will require 2 redirects
await Task.Delay(50);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
activity?.SetStatus(ActivityStatusCode.Ok);
return Results.Ok();
}
activity?.SetStatus(ActivityStatusCode.Error);
return Results.StatusCode(500);
}
}
前面的代码段在 Api 类内部定义了一个私有静态 ActivitySource 字段。在 HandleRoot 方法内部,使用 ActivitySource 启动一个 Activity,并设置几个标记。ActivitySource 和 Activity 类型在 .NET BCL(基类库)中定义,并在 System.Diagnostics 命名空间中定义。需要 using 指令才能使用它们。
using System.Diagnostics;
通过使用 Activity API 来检测上述代码,我们不受任何特定供应商 APM 解决方案的约束。要了解有关使用 .NET API 以 OpenTelemetry 原生方式检测代码的更多信息,请访问Microsoft Learn 页面,其中涵盖了分布式跟踪检测。
我们必须应用的最后一个修改将指示 OpenTelemetry 观察来自我们特定于应用程序的 ActivitySource 的 span。这是通过使用依赖注入框架更新 OpenTelemetry 组件的注册来实现的。
builder.Services
.AddHttpClient()
.AddOpenTelemetry()
.WithTracing(t => t
.AddAspNetCoreInstrumentation()
.AddSource(Api.ActivitySourceName)); // <1>
<1> AddSource 将 OpenTelemetry SDK 订阅到我们应用程序代码生成的 span(activity)。
进行这些更改、重新运行应用程序并请求根终结点后,将收集并导出一个新的跟踪。最新的跟踪可以在 Kibana 可观测性 UI 中查看。
跟踪瀑布现在包括我们添加到应用程序代码的检测生成的内部“DoingStuff”span。HTTP span 仍然显示,现在是“DoingStuff”span 的子 span。
我们正在努力编写更全面的文档,以便在 elastic.co 上发布。在此之前,您可以在我们的存储库 readme 和 docs 文件夹中找到更多信息。
由于发行版旨在扩展 OpenTelemetry SDK 的功能,而对用于注册 SDK 的代码的影响有限,我们建议访问OpenTelemetry .NET 文档,以了解有关检测代码的信息,并提供 SDK 的更高级配置。
后续步骤是什么?
我们很高兴扩大对 OpenTelemetry 社区的支持,并为其在 .NET 生态系统中的未来做出贡献。这是在所有可观测性供应商之间加强协作、提供丰富的生态系统以支持开发人员改进应用程序可观测性且零供应商锁定的重要一步。
在此阶段,我们非常感谢 .NET 社区和我们的客户提供的任何反馈,以指导我们的 OpenTelemetry 发行版的方向。请试用我们的发行版,并通过我们的 GitHub 存储库与我们互动。
在接下来的几周和几个月中,我们将专注于稳定发行版的 API,并将 Elastic APM Agent 功能移植到发行版中。与此同时,我们希望开始通过OpenTelemetry GitHub 存储库向更广泛的 OpenTelemetry 社区捐赠和贡献功能。
本文章中描述的任何功能或特性的发布和时间安排仍由 Elastic 自行决定。当前不可用的任何功能或特性可能不会按时或根本无法交付。