可观测性OpenTelemetry-Metrics(指标)
1. 什么是OpenTelemetry
在介绍指标(Metrics)之前,我们先了解一下: 什么是OpenTelemetry?
微服务架构使开发人员能够更快地构建和发布软件,同时具有更大的独立性,因为他们不再受制于与单体架构相关的繁琐发布流程。随着这些现在分布式的系统的规模扩大,开发人员越来越难以看到他们自己的服务如何依赖或影响其他服务,特别是在部署期间或停机期间,速度和准确性至关重要。观测性使开发人员和操作员都能够获得对其系统的可见性。
那么呢?为了使系统具有可观测性,必须进行仪表化。也就是说,代码必须发出跟踪、度量和日志。然后,仪表化数据必须发送到观测性后端。市场上有许多观测性后端,从自托管的开源工具(例如Jaeger和Zipkin)到商业SaaS产品不一而足。
过去,代码的仪表化方式会有所不同,因为每个观测性后端都有自己的仪表化库和代理程序,用于向工具发出数据。这意味着没有标准化的数据格式用于将数据发送到观测性后端。此外,如果公司选择切换观测性后端,这意味着他们必须重新仪表化他们的代码并配置新代理程序,以便能够向新的工具发出遥测数据。
缺乏标准化的结果是数据可移植性的缺乏和用户维护仪表化库的负担。认识到标准化的必要性,云社区走到了一起,诞生了两个开源项目:OpenTracing(一个Cloud Native Computing Foundation(CNCF)项目)和OpenCensus(一个Google开源社区项目)。
OpenTracing 提供了一个供应商中立的API,用于将遥测数据发送到观测性后端;但是,它依赖于开发人员实现自己的库以符合规范。
OpenCensus 提供了一组特定语言的库,开发人员可以使用这些库来仪表化他们的代码,并将其发送到他们支持的任何一个后端。
由于上面说的种种原因就催生了OpenTelemetry,
为了拥有一个单一的标准,OpenCensus和OpenTracing于2019年5月合并,形成了OpenTelemetry(简称OTel)。作为CNCF孵化项目,OpenTelemetry结合了两者的优点,并有所创新。OTel的目标是提供一组标准化的供应商中立的SDK、API和工具,用于将数据摄入、转换和发送到观测性后端(即开源或商业供应商)。
简单的说什么是OpenTelemetry
- OpenTelemetry是一个开源的观测性工具和API集合,用于生成、收集和处理分布式系统的遥测数据。它提供了一种标准化的方式来跟踪分布式应用程序的性能和行为,并将这些数据发送到不同的观察平台进行存储、分析和可视化。也就是
OpenTelemetry
是一套观察性的标准。 - OpenTelemetry具有语言无关性,支持各种编程语言和框架,并可与多种观察平台集成。通过使用OpenTelemetry,开发人员和运维人员可以更轻松地理解和优化分布式应用程序的性能和可靠性。
2. OpenTelemetry Metrics类型
指标API定义了各种仪器。仪器记录测量值,这些值由指标SDK聚合并最终在进程外导出。仪器有同步和异步两种形式。同步仪器在发生时记录测量值。异步仪器注册回调,每次集合时调用一次,并在该时间点记录测量值。可用以下仪器:
- LongCounter/DoubleCounter:仅记录正值,具有同步和异步选项。对于计数诸如通过网络发送的字节数之类的内容非常有用。计数器测量默认按始终增加的单调总和聚合。这里只能往上增长不能往下减少。例如流量的统计就可以使用这里一类Metric,在Java语言的实现有同步也有异步两种形式。
- LongUpDownCounter/DoubleUpDownCounter:记录正负值,具有同步和异步选项。对于计算上升和下降的内容非常有用,例如队列的大小。上下计数器测量默认按非单调总和聚合。在Java语言的实现有同步也有异步两种形式。
- LongGauge/DoubleGauge:使用异步回调测量瞬时值。对于记录不能跨属性合并的值非常有用,例如CPU利用率百分比。计量测量默认按计量表聚合。例如某个应用的TCP的连接数量或者内存使用情况等等。在Java的实现中只有异步
- LongHistogram/DoubleHistogram:记录最有用于分析的测量值,例如作为直方图分布。没有异步选项可用。对于记录HTTP服务器处理请求所需的时间持续时间之类的内容非常有用。直方图测量默认按显式桶直方图聚合。直方图在Java实现中只有同步
同步instrument:
Instrument | Properties | Aggregation | 例子 |
---|---|---|---|
Counter | monotonic | sum -> delta | 请求数,请求大小 |
UpDownCounter | additive | last value -> sum | 连接的数量 |
Histogram | grouping | histogram | 请求持续时间,请求大小 |
异步instrument:
Instrument Name | Properties | Aggregation | Example |
---|---|---|---|
CounterObserver | monotonic | sum -> delta | CPU 使用时间 |
UpDownCounterObserver | additive | last value -> sum | Memory 使用大小 |
GaugeObserver | grouping | last value -> none/avg | 内存使用 (%) |
2.1 Instrument使用说明
-
Gauge(量规)是一个单独的值,可以随时变化,代表瞬时状态或者瞬时计数,例如 CPU 使用率或者当前在线用户数等。在OpenTelemetry中,Gauge通常通过提供一系列的值来表示单个指标的不同状态,例如当前使用内存的百分比。
-
Counter(计数器)是一个不断累加的值,代表在一段时间内的总量,例如请求数量或者错误数量等。在OpenTelemetry中,Counter会自动累加每个时间窗口内的指标值,并且通常会被重置为0,以便开始下一个时间窗口的计数。
-
Histogram: Histogram是一种表示分布的指标,它能够提供值的数量、最大值、最小值、平均值等信息。Histogram通常用于表示例如响应时间、数据大小等指标的分布情况。Histogram会记录一个时间段内值的分布情况,然后将其拆分为不同的桶(bucket),每个桶表示一个区间范围,可以在桶中记录数据数量、最大值、最小值等信息。
具体而言,在OpenTelemetry中,Gauge表示测量瞬时值的指标,例如某一时刻的 CPU 利用率。Counter用于记录某个累计量的值,例如请求数量。Histogram可以将测量数据分成多个桶,以便查看它们的分布情
3. 手动仪表化步骤
引入Jar包到项目(以Gradle为例)
dependencies {
implementation 'io.opentelemetry:opentelemetry-api:1.24.0'
implementation 'io.opentelemetry:opentelemetry-sdk:1.24.0'
implementation 'io.opentelemetry:opentelemetry-exporter-otlp:1.24.0'
implementation 'io.opentelemetry:opentelemetry-semconv:1.24.0-alpha'
}
创建例子:
//创建资源
Resource resource = Resource.getDefault()
.merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "logical-service-name")));
//创建TracerProvider
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder().build()).build())
.setResource(resource)
.build();
//创建MeterProvider
SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
.registerMetricReader(PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()).build())
.setResource(resource)
.build();
//创建OpenTelemetry实例
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setMeterProvider(sdkMeterProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
4. OpenTelemetry Metrics导入Prometheus
下面写一个例子将OpenTelemetry Metrics导入Prometheus。我们这里需要增加一个导入
implementation("io.opentelemetry:opentelemetry-exporter-prometheus:1.23.1-alpha")
代码如下:
public class OpenTelemetryTest {
public static void main(String[] args) throws InterruptedException {
Resource resource = Resource.getDefault().merge(Resource.create(Attributes.empty()));
SdkMeterProvider build = SdkMeterProvider.builder().setResource(resource)
.registerMetricReader(PrometheusHttpServer.builder().setPort(7070).build()).build();
OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder().setMeterProvider(build).buildAndRegisterGlobal();
Meter mxsm = openTelemetrySdk.getMeter("mxsm");
MemoryMXBean mxb = ManagementFactory.getMemoryMXBean();
AtomicLong cc= new AtomicLong();
mxsm.upDownCounterBuilder("process.runtime.jvm.memory.usage").setUnit("Bytes")
.buildWithCallback(record -> record.record(Runtime.getRuntime().totalMemory(),Attributes.of(AttributeKey.stringKey("type"),"heap")));
mxsm.upDownCounterBuilder("process.runtime.jvm.memory.usage_after_last_gc").setUnit("bytes").buildWithCallback(record->record.record(cc.longValue(), Attributes.of(AttributeKey.stringKey("type"),"heap")));
LongCounter build1 = mxsm.counterBuilder("mxsm.qqq").setUnit("1").build();
long i =1;
for(; ;){
cc.set(mxb.getHeapMemoryUsage().getUsed());
build1.add(i);
TimeUnit.SECONDS.sleep(1);
}
}
}
首先本地运行Prometheus。配置好相关配置。运行上面的程序然后打开Prometheus的控制台网页
更多的使用可以参照作者在 Apache EventMesh 的项目 ISSUE#3430的升级改造PR
5. 总结
使用OpenTelemetry Metrics可以带来以下优点:
- 标准化的度量指标:OpenTelemetry Metrics定义了一组标准的指标格式和命名规则,这使得应用程序和观察平台可以更容易地共享和理解度量数据。这也可以避免不同应用程序使用不同指标格式和命名规则所导致的混乱。
- 支持多种语言和框架:OpenTelemetry Metrics提供了各种编程语言和框架的API,使得应用程序可以轻松地生成和公开度量指标。这也使得跨语言和跨框架的应用程序可以使用相同的指标集合。
- 可扩展性:OpenTelemetry Metrics支持自定义指标和自定义指标聚合器,这使得应用程序可以更容易地收集和聚合特定于业务或应用程序的指标。
- 可插拔性:OpenTelemetry Metrics支持多种观察平台和后端存储,如Prometheus、Grafana、InfluxDB等。这使得应用程序可以轻松地将度量数据发送到不同的平台进行存储、分析和可视化。
- 实时数据分析:OpenTelemetry Metrics可以帮助应用程序实时地分析和可视化度量数据,这可以帮助开发人员和运维人员更快地检测和解决性能问题,提高应用程序的可靠性和稳定性。
转载自:https://juejin.cn/post/7229186336154419259