OpenTelemetry.NET API

Status and Releases

Tracing Metrics Logging
1.0 Alpha Beta

安装

dotnet add package OpenTelemetry.Api

说明

应用程序的开发者和库的作者使用 OpenTelemetry API 来测量其应用程序。API 仅仅关注对于测量应用程序/库的必须的抽象。对于特殊的要求,例如 telemetry 如何导出到特定的 telemetry 后端,如何采样 telemetry 等等。API 由 Tracing API、Logging API、Metric API、Context 和 Propagation API ,以及一套语义约定所组成。

Tracing API

Tracing API 允许你生成 Span,它表示 Trace 的单个操作。Span 可以嵌套成为 Span 树。每个 Trace 包含一个根 Span,它专门描述整个的操作,一个或者多个的子 Span 对应子操作。

Logging API

OpenTelemetry.NET 并没有对日志引入自己的 API。相反,它提供了对众所周知的 Microsoft.Extensions.Logging API 的集成。

Metrics API

Metrics API 允许用户捕获计算机程序在运行时的测量。Metrics API 被设计为处理原始的测量,通常是这些测量的持续统计。

Baggage API

Baggage API 允许用户添加上下文信息到 metric、trace 以及 log 中。Baggage 可以使用 Propagator 来从进程暴露。OpenTelemetry SDK 提供了 BaggageProgagator ,并默认启用。

// Use GetBaggage to get all the key/value pairs present in Baggage
foreach (var item in Baggage.GetBaggage())
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
} // Use SetBaggage method to add a key/value pair in Baggage
Baggage.SetBaggage("AppName", "MyApp");
Baggage.SetBaggage("Region", "West US"); // Use RemoveBaggage method to remove a key/value pair in Baggage
Baggage.RemoveBaggage("AppName"); // Use ClearBaggage method to remove all the key/value pairs in Baggage
Baggage.ClearBaggage();

建议的添加 Baggate 方式是使用 Baggate.SetBaggate() API。OpenTelemetry 用户不应该使用 Activity.AddBaggate() 方法

OpenTelemetry.NET Tracing API 入门

很久以来,.NET 运行时提供了 Activity 类,它的用意是跟踪和表示与 OpenTelemetry Span 等价的意图。OpenTelemetry.NET 重用已有的 Activity 并用于表示 Telemetry 中的 Span。这意味着,用户可以仅仅使用 .NET 运行时,就可以测量其应用程序,并记录 OpenTelemetry 兼容的 Trace。

Activity 和相关类来自 System.Diagnostics.DiagnosticSource NuGet 包。该包的 5.0.0 版本包含了改进的 Activity 类,使得它更加接近 OpenTelemetry API 规范。

即使 Activity 使能了 OpenTelemetry 支持的所有场景,已经熟悉 OpenTelemetry 术语的用户可能发现它很容易使用该术语操作。例如,StartSpan 可能就是 StartActivity。为了帮助这种转换,OpenTelemetry.API 包提供了垫片类来封装 .NET 的 Activity 类。

垫片类仅仅存在于 API 中。.NET 的 OpenTelemetry SDK 将仅仅使用 Activity 。而不管在测量中使用的是垫片类,还是 Activity 类。最终的结果将是相同的。在 Processor 和 Exporter 中得到相同的数据。

建议的测量方式是使用 .NET Activity API。用户仅仅要求依赖于 DiagnosticSource。添加对于 OpenTelemetry.APi 仅仅对于如下场景是必须的:

  1. 你希望使用匹配 OpenTelemetry 规范的术语。垫片对于此类用户是有帮助的。如果你想比较其差异,请参考
  2. 你的库与其它库或者组件进行通讯,并期望访问 Propagator,以注入并抽取上下文数据。有些最通用的库要求这样,例如 HttpClient、ASP.NET、ASP.NET Core。该仓储已经提供了对于这些常用库的指导。如果你的库不是基于这些库构建,并期望借助于 propagator,请参考 Context propagation 一节。
  3. 你希望借助于 Baggage API

使用 .NET Activity API 测量库/应用程序

基本使用

如在入门部分所述,在 OpenTelemetry.NET 中的测量 API 使用 .NET 中的 Activity API。

  1. 为你的应用程序安装 System.Diagnostics.DiagnosticSouce 5.0.1 及以上 Package

    <ItemGroup>
    <PackageReference
    Include="System.Diagnostics.DiagnosticSource"
    Version="5.0.1"
    />
    </ItemGroup>
  2. 创建一个 ``ActivitySource。提供处理测量相关的名称和版本。ActivitySource` 实例通常仅仅创建一个,并在整个应用程序/库中重用。

    static ActivitySource activitySource = new ActivitySource(
    "companyname.product.instrumentationlibrary",
    "semver1.0.0");

    上面的代码要求导入 System.Diagnostics 命名空间。

  3. 使用 ActivitySource 实例来创建 Activity 实例,用来表示单个的 Trace 。提供的参数是活动的 DisplayName

    var activity = activitySource.StartActivity("ActivityName");

    如果对于该 Activity 没有监听器,上面的活动将为 null。当最终的应用程序没有启用 OpenTelemetry 的时候就会发生。或者 OpenTelemetry 的采样器不采样此 Actitity 的时候。确保后继的使用该 activity 的操作进行 null 检查

  4. 使用 OpenTelemetry 语义约定填充 activity。非常建议检查 activity.IsAllDataRequested,在填充任何没有快速可用的数据之前。IsAllDataRequested 类似于 Span.IsRecording ,当采样器决定不采样该 activity 的时候,将返回 false。这可以用来忽略任何昂贵的提取标志的操作

    activity?.SetTag("http.method", "GET");
    if (activity != null && activity.IsAllDataRequested == true)
    {
    activity.SetTag("http.url", "http://www.mywebsite.com");
    }

    建议的方式是使用 Activity 类的 SetTag 来设置 span 属性。OpenTelemetry 用户不应该使用其它方法,比如 AddTag(),SetCustomProperty 等等

  5. 执行应用逻辑

  6. 在业务逻辑完成之后,停止 activity。

    activity?.Stop();

    另外,由于 Activity 已经实现了 IDisposable 接口,可以使用 using 块来确保 activity 在回收之前停止,如下所示

    using (var activity = activitySource.StartActivity("ActivityName")
    {
    activity?.SetTag("http.method", "GET");
    } // Activity gets stopped automatically at end of this block during dispose.

以上展示了使用 Activity 进行测量的基本用法。

Activity 创建的选项

以上的基本使用介绍了使用 StartActivity 来开始一个 Activity。启动的 Activity 自动变成 Current 活动。重要的是要注意,如果没有监听器作用于该 Activity 的话, StartActivity 返回 null。当应用程序没有启用 OpenTelemetry,或者当 OpenTelemetry 的采样器不采样此 Activity 的话。

StartActivity 有多个重载来控制 activity 的创建

  1. ActivityKind

    Activity 有一个称为 ActivityKind 的属性,表示 OpenTelemetry 的 SpanKind。默认值为 Internal。StartActivity 允许传递 ActivityKind

    var activity = activitySource.StartActivity("ActivityName", ActivityKind.Server);
  2. Parent,使用 ActivityContext

    ActivityContext 表示 OpenTelemetry 的 SpanContext。当启动一个新的 Activity 的时候,当前活动的 Activity 自动获取它,作为新创建的 Activity 的父节点。StartActivity 支持传递显式的 ActivityContext 来覆盖此行为。

    var parentContext = new ActivityContext(
    ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c"),
    ActivitySpanId.CreateFromString("b7ad6b7169203331"),
    ActivityTraceFlags.None); var activity = activitySource.StartActivity(
    "ActivityName",
    ActivityKind.Server,
    parentContext);

    ActivityContext 支持 W3C Trace-Context 规范,还可以使用符合 W3C Trace-Context 规范的单个字符串来提供父 Span 的上下文。如下所示

    var activity = activitySource.StartActivity(
    "ActivityName",
    ActivityKind.Server,
    "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01");
  3. 初始标志

    Activity 中的 Tag 表示 OpenTelemetry 中的 Span 属性。前面的示例展示了使用 Activity 的 SetTag() 来添加标志。还可以在创建 Activity 的时候提供初始化标志。如下所示。提供的标志可以被采样器所访问,而使用 SetTag() 方法添加的对于采样器不可用。

    var initialTags = new ActivityTagsCollection();
    
    initialTags["com.mycompany.product.mytag1"] = "tagValue1";
    initialTags["com.mycompany.product.mytag2"] = "tagValue2"; var activity = activitySource.StartActivity(
    "ActivityName",
    ActivityKind.Server,
    "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
    initialTags);

    上面的代码需要引入命名空间 System.Collections.Generic。

  4. Activity Links

    除了父子关联,activity 之间还可以使用 ActivityLink 来连接,它表示 OpenTelemetry 的 Link。连接的 Activity 必须在创建时提供,如下所示

    var activityLinks = new List<ActivityLink>();
    
    var linkedContext1 = new ActivityContext(
    ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c"),
    ActivitySpanId.CreateFromString("b7ad6b7169203331"),
    ActivityTraceFlags.None); var linkedContext2 = new ActivityContext(
    ActivityTraceId.CreateFromString("4bf92f3577b34da6a3ce929d0e0e4736"),
    ActivitySpanId.CreateFromString("00f067aa0ba902b7"),
    ActivityTraceFlags.Recorded); activityLinks.Add(new ActivityLink(linkedContext1));
    activityLinks.Add(new ActivityLink(linkedContext2)); var activity = activitySource.StartActivity(
    "ActivityWithLinks",
    ActivityKind.Server,
    default(ActivityContext),
    initialTags,
    activityLinks);

    注意,上面创建的 Activity 使用了 default(ActivityContext) 父节点,这使得它隐式成为 Activity.Current 的子节点。如果没有 Current 的话,就是一个孤儿节点。

添加 event

可以使用 AddEvent() 方法来为 Activity 添加事件

activity?.AddEvent(new ActivityEvent("sample activity event."));

除了提供 name,timestamp 之外,可以使用 ActivityEvent 来添加属性。

设置状态

OpenTelemetry 定义了称为 Status 关联到 Activity。在 .NET 中,没有 Status 类,请注意 Status 是使用如下的 tag 来设置到 Activity 的。

otel.status_code 是用来存储状态码 StatusCodeTagotel.status_description 是用来存储可选的描述信息 DescriptionTag

例如

activity?.SetTag("otel.status_code", "ERROR");
activity?.SetTag("otel.status_description", "error status description");

StatusCode 的值必须为字符串 UNSETOK 或者 ERROR 之一,它相关与 StatusCode 枚举的值

  • Unset
  • Ok
  • Error

如果使用 OpenTelemetry API 的垫片,那么你可以借助于 Activity 方法的扩展 SetStatus()。

使用 OpenTelemetry.API 垫片

如入门部分所述,除非你希望使用 OpenTelemetry 术语,例如 Tracer,才建议使用垫片。

请参考如下代码使用 垫片。

参考

Instrumenting a .NET web API using OpenTelemetry, Tempo, and Grafana Cloud | Grafana Labs

https://opentelemetry.lightstep.com/csharp/

OpenTelemetry.NET API的更多相关文章

  1. 20 个 .NET 6 新增的 API

    DateOnly & TimeOnly .NET 6 引入了两种期待已久的类型 - DateOnly 和 TimeOnly, 它们分别代表DateTime的日期和时间部分. DateOnly ...

  2. Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用

    一.分布式链路追踪发展简介 1.1 分布式链路追踪介绍 关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(https://www. ...

  3. Opentelemetry SDK的简单用法

    Opentelemetry SDK的简单用法 概述 Opentelemetry trace的简单架构图如下,客户端和服务端都需要启动一个traceProvider,主要用于将trace数据传输到reg ...

  4. .NET 6 预览版 5 发布

    很高兴.NET 6 预览版5终于跟大家见面了.我们现在正处于.NET 6 的后半部分,开始整合一些重要的功能. 例如.NET SDK 工作负载,它是我们.NET 统一愿景的基础,可以支持更多类型的应用 ...

  5. .NET 6 史上最全攻略

    欢迎使用.NET 6.今天的版本是.NET 团队和社区一年多努力的结果.C# 10 和F# 6 提供了语言改进,使您的代码更简单.更好.性能大幅提升,我们已经看到微软降低了托管云服务的成本..NET ...

  6. 一文详解|Go 分布式链路追踪实现原理

    在分布式.微服务架构下,应用一个请求往往贯穿多个分布式服务,这给应用的故障排查.性能优化带来新的挑战.分布式链路追踪作为解决分布式应用可观测问题的重要技术,愈发成为分布式应用不可缺少的基础设施.本文将 ...

  7. 解读Go分布式链路追踪实现原理

    摘要:本文将详细介绍分布式链路的核心概念.架构原理和相关开源标准协议,并分享我们在实现无侵入 Go 采集 Sdk 方面的一些实践. 本文分享自华为云社区<一文详解|Go 分布式链路追踪实现原理& ...

  8. OpenTelemetry架构介绍

    OpenTelemetry: 经得起考验的工具 摘自:https://blog.newrelic.com/product-news/what-is-opentelemetry/ 目录 OpenTele ...

  9. OpenTelemetry - 云原生下可观测性的新标准

    CNCF 简介 CNCF(Cloud Native Computing Foundation),中文为"云原生计算基金会",CNCF是Linux基金会旗下的基金会,可以理解为一个非 ...

  10. 当 .NET 5 遇上OpenTelemetry,会碰撞出怎样的火花?

    OpenTelemetry 介绍 我在之前的几篇文章都介绍了 OpenTelemetry, 你可以在这里找到 OpenTelemetry - 云原生下可观测性的新标准 深入研究 .NET 5 的开放式 ...

随机推荐

  1. USB和CAN都是用差分信号来传输数据,为什么CAN的传输距离能比USB远那么多?

    USB和CAN的区别 今天在看USB项目设计实例的时候,突然想到一个问题,从而引发了一些思考.经过思考加上查阅资料,写出了这一篇文章作为记录. 问题 ​ USB和CAN都是用两条线作为差分线以差分信号 ...

  2. USB type-c CC管脚如何做到正反接检测功能

    USB Type-C 连接器的 CC (Configuration Channel) 管脚用于实现插头方向检测和电源管理.具体来说,USB Type-C 连接器具有两个 CC 管脚:CC1 和 CC2 ...

  3. 数据库周刊57丨Oracle 2021年度安全警报;MySQL 8.0.23发布;MySQL索引优化导致的死锁案例;巨杉数据库跨引擎事务实践;MongoDB企业级能力解析;OceanBase OBCP 实验指导手册……

    摘要:墨天轮数据库周刊第57期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.Oracle 2021年度安全警报: Critical Patch Update 发布8个 ...

  4. 04-react的基本:条件渲染

    import reactDom from "react-dom" // 条件渲染 if else let loading = false // 写一个函数用于加载 const lo ...

  5. 什么是 RBAC 权限控制

    RBAC是Role Based Access Control的英文缩写,意思是 基于角色的访问控制. RBAC实际上就是针对产品去挖掘需求时所用到的Who(角色).What(拥有什么资源).How(有 ...

  6. 37 .vue2数组和对象的区别 ?

    vue2中的数组不能使用索引实现响应式 ,因为vue没有给数组元素添加get和set函数  : 追加对象的属性的时候不是响应式,要使用 $set 追加响应式  :

  7. 生成文本聚类java实现3

    由于carrot2对中文的理解很不靠谱,所以参考了网络上的一些资料,现在贡献出来所有代码. 代码的思路就是找字或者词出现的频度,并进行打分,最后按照出现次数和重要性,找出重要的语汇.现在贴出来一些可用 ...

  8. Golang 开源库分享:anko - 给 Go 加点“脚本魔法”

    GitHub 仓库链接:https://github.com/mattn/anko 1. anko 是干嘛用的? anko 是一个可以让 Go 项目支持脚本语言的小工具.换句话说,就是我们可以给 Go ...

  9. CMU15445学习记录

    写在开头 我已经深刻意识到找工作的不易,因此想要开始恶补计算机基础知识,以此作为起点 由于考研的时候学过408综合,因此试图逃课CSAPP并直接开始CMU,发表此篇用作记录. 关于底层原理 原理 数据 ...

  10. Robot_Parkour_Learning分享报告关键词记录

    fraction noise minecraft perlin noise 作为一种fraction noise 跑酷 深度相机,不然被挡住不知道是要下蹲还是要跳过去 issacGym的激光雷达的模拟 ...