Opentelemetry Metrics SDK
Metrics SDK
目标
本文档包含两个部分,在第一部分中列出了实现OpenTelemetry Metric SDK的默认需求。实现者需要根据这些规则来实现OpenTelemetry API。
在第二部分中,以OpenTelemetry-Go Metric SDK为例描述了SDK模型的架构细节,给出所需要实现的内容,以此作为对实现者的指导,而不需要强制跨语言精确地去复制这种模型体系结构。
期望
SDK实现者在实现OpenTelemetry API时应该遵守该语言的最佳实践和运行时环境。实现者应该遵循 OpenTelemetry library guidelines给出的有关安全和性能的规定。
SDK 术语
Metrics SDK提供了一种Metrics API的实现,包含如下术语(本文后续将直接采用如下术语,不作翻译):
- Meter:支持OpenTelemetry Metric API的接口,与Resources 和Instrumentation Library绑定在一起
- MeterProvider:通过给定的Instrumentation Library获取Meter实例的接口
这些术语用于描述API和SDK的边界,但它们都是API级别的结构。我们可以使用API级别的术语来描述SDK和API之间的边界,但从API的角度看,SDK是不透明的,且没有结构。
本文给出了默认OpenTelemetry SDK的主要组件的内部结构,通过术语来解释每个组件在将metric数据从输入(API级别的事件)导出到输出(metric呈现格式)中所扮演的角色。我们使用Export Pipeline来描述SDK级别的功能。
export pipeline中有三个数据流会经过的主要组件,按顺序为:
- Accumulator:接收API通过Instrument获取的metric事件,并根据活动的Instrument和Label Set对计算出一个Accumulation
- Processor:从Accumulator接收Accumulations ,并转换为ExportRecordSet
- Exporter:接收ExportRecordSet,并转换为某种协议(如grpc),将其发送出去
Controller 组件在export pipeline中协调Accumulator、Processor和Exporter。
Metrics API规范定义了如下术语:
- Metric Instrument:开发者用于操作工具的API对象
- Synchronous Instrument:用户通过应用程序上下文调用的metric Instrument
- Asynchronous Instrument:通过从SDK的回调调用的metric Instrument
- Metric Descriptor:描述一个metric Instrument
- Metric Event:单个记录到或观察到的(Instrument, Label Set, Measurement)
- Collection Interval: Accumulator.Collect()调用的周期
- Label: 描述metric Event属性的key-value
- Label Set: 包含唯一的keys的key-values集
- Measurement: 来自synchronous instrument的证书或浮点数
- Observation: 来自asynchronous instrument的证书或浮点数
Resource SDK 定义了如下术语:
- Resource: 描述进程的一组具有唯一keys的key-value集
- Instrumentation Library:与一个工具包关联的名称和版本
下面为架构中重要的数据类型:
- Aggregator: 以一种有用的方式汇总一个或多个measurements
- Aggregator Snapshot: 在采集期间拷贝synchronous instrument aggregator的副本
- AggregatorSelector: 选择分配给metric instrument 的Aggregator
- Accumulation: 包含Instrument, Label Set, Resource, 和Aggregator snapshot, 由Accumulator生成
- Aggregation: 由特定的aggregator聚合一个或多个事件产生的结果, 由Processor生成
- AggregationKind: 描述了Aggregation支持的API类型 (e.g., Sum)
- ExportKind: Delta, Cumulative, 或Pass-Through的一种
- ExportKindSelector: 为一个metric Instrument选择ExportKind
- ExportRecord: 包含Instrument, Label Set, Resource, Timestamp(s), 和Aggregation
- ExportRecordSet: 一些列的export records.
术语SDK instrument 指Instrument的底层实现。
数据流图表
从外部看, Metrics SDK 实现了Meter
和MeterProvider
接口,从内部看, Metrics SDK为每个metric数据封装了一个export pipeline,包含四个重要组件。
Accumulator组件是将metric event并发地传递给Aggregator的地方,这是负责SDK性能的组件。Accumulator 负责bound 和unbound Instrument,更新和同步拷贝Aggregator 状态,调用Observer Instrument以及唤醒采集周期。
Processor 组件是exporter pipeline中可定制的组件。Processor 负责通过一个独立的AggregationSelector
接口为特定的Instrument选择Aggregators ,用于减少维数,以及用于在DELTA和CUMULATIVE数据表示之间进行转换。Processor 接口支持任意协议独立的数据转换,且可以将Processor连接在一起,形成更复杂的export pipelines。
Exporter 组件将处理的数据转换为特定的协议,并将其转发到某处。根据 library guidelines,exporter应该包含最小的功能,定制时最好通过Processors来表示。
Controller 组件协调在一个采集间隔内的采集动作,处理和导出采集间隔内的metric数据,确保对export pipeline的访问是同步的。
要求
下面列出了针对OpenTelemetry SDK主要组件的要求。
上面展示了一个抽象的数据流图,将本文档使用的标准组件名与数据路径做了映射。上图并非要说明SDK的整体架构,仅命名了一个export pipeline的过程,并将组件放到了上下文中。
SDK要求这些组件使用标准名称,这样做有助于在OpenTelemetry中构建一致性。每个SDK都应该包含这些组件,以及下面列出的接口,尽管每个SDK的实际组织可能会因可用的库和源语言的性能特征而有所不同。例如,一个SDK可能为每个instrument实现了一个Accumulator,或者可以为每个采集周期使用一个Accumulator(假设支持多采集周期)。
SDK
SDK封装了OpenTelemetry Metric export pipeline,实现了Meter接口,并管理SDK instrument,Resource和Instrumentation Library 元数据。
MeterProvider
Shutdown
该方法为provider提供了一种清理环境的方法。
每个MeterProvider实例只能调用一次Shutdown
,在调用Shutdown
之后,将不允许获得Meter
。对于这些调用,SDK应该返回一个有效的无操作Meter。
Shutdown
应该提供一种方式来让调用者知道是否成功,失败或超时。
当出现超时时,Shutdown
应该结束或中止。Shutdown
可以被实现为一个阻塞API,或异步API,通过回调或事件通知调用者。语言库作者可以决定是否配置shutdown的超时时间。
SDK:Instrument注册
OpenTelemetry SDK负责确保单个Meter的实现不会报告具有相同名称但不同定义的多个Instrument。为了实现该要求,如果一个Meter已经注册了一个相同名称的metric,则SDK必须拒绝在该Meter重复注册该Instrument。该要求甚至适用于尝试注册一个具有相同定义的Instrument。我们假设单个instrumentation library可以使用单个Instrument定义,而不是依赖SDK的重复注册。
不同的Meter具有不同的instrumentation library名称,允许在不同的instrumentation library中注册相同名称的Instrument,这种情况下,SDK必须将它们认为是不同的Instruments。
SDK负责实现API规范中包含的metric名称的语法要求。
SDK: RecordBatch() 函数
TODO: Add functional requirements for RecordBatch().
SDK: Collect() 函数
SDK负责实现Collect()
函数,该函数会调用一个或多个Accumulators。本规范刻意避免在SDK和Accumulator之间建立特定关系;还有一个实现细节,即一个SDK是否会维护一个Accumulator,或每个Instrument对应一个Accumulator,或介于两者之间的某些配置。
SDK Collect()
函数必须通过活动的synchronous instruments以及所有注册的asynchronous instruments的Accumulations来调用Processor。
SDK必须允许在评估asynchronous instrument回调期间使用synchronous metric instruments。但通过asynchronous instrument回调来使用synchronous instruments是有副作用的,这种情况下,SDK应该在处理asynchronous instrument之后再处理synchronous instruments,这样synchronous measurements会作为asynchronous observations采集间隔的一部分进行处理。
Accumulator
下图展示了API和Accumulator之间的关系,以及synchronous instruments的细节。
对于一个synchronous instrument,Accumulator会:
- 将每个活动的Label Set 映射到一条记录中,该记录由两个相同类型的Aggregator实例组成
- 在映射中输入新记录,如果需要,调用AggregationSelector
- 更新当前的Aggregator 实例,用以响应并发API事件
- 在当前Aggregator 实例上调用Aggregator.SynchronizedMove:a)拷贝其值到Aggregator快照实例中;b)将当前的Aggregator重置为0状态
- 调用Processor.Process。处理每一个生成的Accumulation (即Instrument, Label Set, Resource, 和Aggregator snapshot)
Accumulator必须提供选项来将一个Resource与它生成的Accumulations进行关联。
Synchronous metric instruments可以同步使用,除非源语言不支持该特性。SDK Accumulator 组件应该注意同步产生的性能压力。
Accumulator可能会使用排他锁定来维护synchronous instruments的更新。在调用Aggregator 时,Accumulator不应该持有排他锁,因为Aggregators可能具有更高的同步期望。
Accumulator: Collect()函数
Accumulator必须实现Collect方法来为活动的instruments构建和处理当前的Accumulation值,即在上一次采集之后会更新这些值。Collect方法必须调用Processor来处理对应调用之前的所有metric events的Accumulations。
必须在Collect期间使用Aggregator上的同步移动操作来计算Accumulations。该操作会同步拷贝当前的Aggregator,并将其重置为0状态,这样Aggregator会在当前采集周期处理结束之后,下次采集周期开始时立即开始累加事件。一个Accumulation 定义为同步拷贝的Aggregator与Label Set, Resource, 和metric Descriptor的组合。
TODO: Are there more Accumulator functional requirements?
Processor
TODO Processor functional requirements
Controller
TODO Controller functional requirements
Aggregator
TODO Aggregator functional requirements
如果可能的话,Sum Aggregator应该使用原子操作。
模型实现
本模型实现基于OpenTelemetry-Go SDK,本节为实现者提供指南。
Accumulator: Meter实现
为了构造一个Accumulator,需要提供Processor和options
// NewAccumulator constructs a new Accumulator for the given
// Processor and options.
func NewAccumulator(processor export.Processor, opts ...Option) *Accumulator
// WithResource sets the Resource configuration option of a Config.
func WithResource(res *resource.Resource) Option
Controller会使用Collect()
方法来调用Accumulator,对采集进行协调。
// Collect traverses the list of active instruments and exports
// data. Collect() may not be called concurrently.
//
// During the collection pass, the Processor will receive
// one Process(Accumulation) call per current aggregation.
//
// Returns the number of accumulations that were exported.
func (m *Accumulator) Collect(ctx context.Context) int
实现与用户级别的Metric API匹配的SDK级别的API
该接口位于SDK和API的边界处,包含3个方法:
// MeterImpl is the interface an SDK must implement to supply a Meter
// implementation.
type MeterImpl interface {
// RecordBatch atomically records a batch of measurements.
RecordBatch(context.Context, []label.KeyValue, ...Measurement)
// NewSyncInstrument returns a newly constructed
// synchronous instrument implementation or an error, should
// one occur.
NewSyncInstrument(descriptor Descriptor) (SyncImpl, error)
// NewAsyncInstrument returns a newly constructed
// asynchronous instrument implementation or an error, should
// one occur.
NewAsyncInstrument(
descriptor Descriptor,
runner AsyncRunner,
) (AsyncImpl, error)
}
这些方法覆盖了实现OpenTelemetry Metric API所需的所有入口。
RecordBatch
是一个直接由Accumulator实现的用户级别的API。另外两个instrument构造器用于创建同步和异步SDK instruments。
用户通常对Metric API Meter
接口感兴趣,该接口通过Metric API MeterProvider
接口获得。可以通过封装SDK Meter
实现来构建Meter
接口。
// WrapMeterImpl constructs a named `Meter` implementation from a
// `MeterImpl` implementation. The `instrumentationName` is the
// name of the instrumentation library.
func WrapMeterImpl(impl MeterImpl, instrumentationName string, opts ...MeterOption) Meter
该方法的选项:
- 可以为命名的Meter添加instrumentation library版本
instrument注册:
// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl with
// the addition of uniqueness checking.
func NewUniqueInstrumentMeterImpl(impl metric.MeterImpl) metric.MeterImpl {
访问instrument descriptor
API Descriptor
方法根据API级别的构造定义了instrument ,包括名称,instrument类型,描述和度量单位。在实现SDK时必须提供方式来访问传递给constructor的Descriptor。
// InstrumentImpl is a common interface for synchronous and
// asynchronous instruments.
type InstrumentImpl interface {
// Descriptor returns a copy of the instrument's Descriptor.
Descriptor() Descriptor
}
Synchronous SDK instrument
Synchronous SDK instrument 支持直接和绑定调用规范。
// SyncImpl is the implementation-level interface to a generic
// synchronous instrument (e.g., ValueRecorder and Counter instruments).
type SyncImpl interface {
// InstrumentImpl provides Descriptor().
InstrumentImpl
// Bind creates an implementation-level bound instrument,
// binding a label set with this instrument implementation.
Bind(labels []label.KeyValue) BoundSyncImpl
// RecordOne captures a single synchronous metric event.
RecordOne(ctx context.Context, number Number, labels []label.KeyValue)
}
// BoundSyncImpl is the implementation-level interface to a
// generic bound synchronous instrument
type BoundSyncImpl interface {
// RecordOne captures a single synchronous metric event.
RecordOne(ctx context.Context, number Number)
// Unbind frees the resources associated with this bound instrument.
Unbind()
}
Asynchronous SDK instrument
Asynchronous SDK instrument 支持单观察者和匹配观测者调用规范。用于执行Observer回调的接口会传递给constructor,这样asynchronous instruments就不需要其他API级别的访问方法。
// AsyncImpl is an implementation-level interface to an
// asynchronous instrument (e.g., Observer instruments).
type AsyncImpl interface {
// InstrumentImpl provides Descriptor().
InstrumentImpl
}
传递给asynchronous SDK instrument constructor 的异步"runner"接口(AsyncRunner)同时支持单个和批量调用规范。
Export pipeline细节
TODO: define AggregatorSelector, Aggregator, Accumulation, ExportKind, ExportKindSelector, Aggregation, AggregationKind ExportRecord, ExportRecordSet
Processor细节
TODO: define the Processor interface
Basic Processor
TODO: define how ExportKind conversion works (delta->cumulative required, cumulative->delta optional), Memory option (to not forget prior collection state).
Reducing Processor
TODO: Label filter, LabelFilterSelector
Controller 细节
TODO: Push, Pull
Aggregator Implementations
TODO: Sum, LastValue, Histogram, MinMaxSumCount, Exact, and Sketch.
Pending issues
ValueRecorder instrument default aggregation
TODO: The default SDK behavior for ValueRecorder
instruments is still in question. Options are: LastValue, Histogram, MinMaxSumCount, and Sketch.
Spec issue 636 OTEP 117 OTEP 118
Standard sketch histogram aggregation
TODO: T.B.D.: DDSketch considered a good choice for ValueRecorder instrument default aggregation.
Opentelemetry Metrics SDK的更多相关文章
- .NET 6 预览版 5 发布
很高兴.NET 6 预览版5终于跟大家见面了.我们现在正处于.NET 6 的后半部分,开始整合一些重要的功能. 例如.NET SDK 工作负载,它是我们.NET 统一愿景的基础,可以支持更多类型的应用 ...
- .NET 6 史上最全攻略
欢迎使用.NET 6.今天的版本是.NET 团队和社区一年多努力的结果.C# 10 和F# 6 提供了语言改进,使您的代码更简单.更好.性能大幅提升,我们已经看到微软降低了托管云服务的成本..NET ...
- 20 个 .NET 6 新增的 API
DateOnly & TimeOnly .NET 6 引入了两种期待已久的类型 - DateOnly 和 TimeOnly, 它们分别代表DateTime的日期和时间部分. DateOnly ...
- .NET静态代码织入——肉夹馍(Rougamo)
肉夹馍是什么 肉夹馍通过静态代码织入方式实现AOP的组件..NET常用的AOP有Castle DynamicProxy.AspectCore等,以上两种AOP组件都是通过运行时生成一个代理类执行AOP ...
- Opentelemetry SDK的简单用法
Opentelemetry SDK的简单用法 概述 Opentelemetry trace的简单架构图如下,客户端和服务端都需要启动一个traceProvider,主要用于将trace数据传输到reg ...
- OpenTelemetry架构介绍
OpenTelemetry: 经得起考验的工具 摘自:https://blog.newrelic.com/product-news/what-is-opentelemetry/ 目录 OpenTele ...
- OpenTelemetry - 云原生下可观测性的新标准
CNCF 简介 CNCF(Cloud Native Computing Foundation),中文为"云原生计算基金会",CNCF是Linux基金会旗下的基金会,可以理解为一个非 ...
- Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用
一.分布式链路追踪发展简介 1.1 分布式链路追踪介绍 关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(https://www. ...
- Metrics.net + influxdb + grafana 构建WebAPI的自动化监控和预警
前言 这次主要分享通过Metrics.net + influxdb + grafana 构建WebAPI的自动化监控和预警方案.通过执行耗时,定位哪些接口拖累了服务的性能:通过请求频次,设置适当的限流 ...
- BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.7.3)
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo将百度语音SDK(其中一部分功能)和自定义的UI对话框封装到一个module中,便于后续的SDK版本更新以及调用. 本De ...
随机推荐
- 性能提升1400+倍,快来看MySQL Volcano模型迭代器的谓词位置优化详解
摘要:性能提升1400+倍,快来看MySQL Volcano模型迭代器的谓词位置优化详解. 本文分享自华为云社区<华为云数据库内核专家为您揭秘MySQL Volcano模型迭代器性能提升千倍的秘 ...
- 云小课 | DSC之数据水印,防止数据被盗用
阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要: 华为云数据安全中 ...
- Appuploader工具让ipa上传到App Store 的最新流程和步骤
苹果官方提供的工具xcode上架ipa非常复杂麻烦.用appuploader 可以在 mac 和windows 上制作管理 证书 ,无需钥匙串工具 条件:1.以Windows为例,创建app打包i ...
- Intelij IDEA 隐藏 .idea
如图 这两文件夹是 IDEA 自动生成的,在开发过程中用不到它.可以把它隐藏(不在 IDEA中显示),操作如下: OK后,立即生效
- SpringBoot yml 小格子 变 小叶子
SpringBoot yml 小格子 变 小叶子 一般添加十多个模块后会出现这样的情况,正常情况下,看POM 文件里的 spring 引用是否异常 一般把 idea 关了再打开试试,有几次我是关了再开 ...
- 使用port-forward本地访问k8s集群内redis
前言 通过kubectl port-forward端口转发,在本地机器上访问k8s集群内的服务/数据库,对开发.调试.定位bug都很有用. 每次都要查,这里记录一下. 步骤 当然首先要确保本地机器上安 ...
- Python pickle 二进制序列化和反序列化 - 数据持久化
模块 pickle 实现了对一个 Python 对象结构的二进制序列化和反序列化. "pickling" 是将 Python 对象及其所拥有的层次结构转化为一个字节流的过程,而 & ...
- three.js项目引入vue,因代码编写不当导致的严重影响性能的问题,卡顿掉帧严重
three.js项目引入vue,因代码编写不当导致的严重影响性能的问题,卡顿掉帧严重 问题排查 使用谷歌浏览器的Performance分析页面性能 可以看到vue.js的reactiveGetter方 ...
- 0x68 - C题:車的放置
链接:https://ac.nowcoder.com/acm/contest/1062/C 题目描述 给定一个N行M列的棋盘,已知某些格子禁止放置. 问棋盘上最多能放多少个不能互相攻击的車. 車放在格 ...
- 【每日一题】25.「火」皇家烈焰 (字符串DP)
补题链接:Here 转移方程的具体含义我在代码注释里写出来了, 很好理解 这道题的难点在于如何表示状态, 一旦找到状态表示方法 只要根据题意做转移就行了 最后的答案就是 \(dp[n][0][0] + ...