【文章目标】
- OpenTelemetry介绍
- OpenTelemetry架构
- 在java项目中生成
Distributed trace id - helm chart有两个版本,在第5章有介绍,推荐使用
opentelemetry-operator进行安装
1. OpenTelemetry介绍
OpenTelemetry官方文档:opentelemetry.io/docs/
1.1 OpenTelemetry的定义
OpenTelemetry, also known as OTel for short, is a vendor-neutral open-source Observability framework for instrumenting, generating, collecting, and exporting telemetry data such as traces, metrics, logs.
OpenTelemetry,简称OTel,是专注Observability相关的开源框架,包含的功能有traces, metris, logs的自动收集、管理、导出等。
Observability:[计算机]可观察性
1.2 OpenTelemetry的一些重要概念
可以查看官网:opentelemetry.io/docs/concep…
-
Observability:可以让我们从外部了解一个系统,即可能在不了解一个系统的情况下,帮助我们了解这个系统的问题。因此,这个系统也必须暴露出一些signals,如:traces, metrics, logs。当一个程序已经有了这些指标后,那么开发人员并不需要额外的再增加更多的指标来做debug,因为所有的指标都已经有了。-->OpenTelemetry可以帮助我们的应用程序建立这些指标,这个过程也可以叫应用程序的instrumentation。 指标有很多种类:- (1)
Traces相关:用户的一个request,即使经历了很多个微服务app,这个traceId始终不变。每个微服务中的log,可以有额外的一个id叫spanId。(这里跟spring cloud slueth有点类似)。 - (2)
Metrics相关:系统错误率、CPU 利用率、给定服务的请求率等。 - (3)
SLI(Service Level Indicator) - (4)
SLO(Service Level Objective)
- (1)
-
OpenTelemetry能做什么:- 支持跨语种的
应用程序的instrumentation(即帮助应用程序收集上述指标),分自化收集和手动收集。 - 提供与vendor无关的实现collector,用于接收、处理和导出telemetry数据。
- 通过配置可将数据并行发送到多个目的地。
- ...
- 支持跨语种的
-
OpenTelemetry不能做什么:并不能提供观测功能,如Jaeger or Prometheus那样的。它只能支持导出到某些目的地。 -
组件- Cross-language specification
- Collector,用于接收、处理和导出telemetry数据。
- Language SDKsPer-language SDKs
- Automatic Instrumentation
2. 架构
对于Opentelemetry的架构还是比较模糊,Github的这个项目给了我一些启发:github.com/mnadeem/boo…
另外一篇文章的图也很有帮助:t.zoukankan.com/rongfenglia…
可以看到:
- (1) 生成telemetry指标:app中配了agent,这部分即上述说的
应用程序的instrumentation,支持很多语种如java, c++, go等等,方式分为自动的instrumentation和手动的instrumentation。这部分主要的作用是使应用程序产生telemetry指标如:trace, log, metrics。 - (2) trace归集:可以通过OpenTelemetry的组件
collector,与Tempo集成(Tempo作为存储的数据源),并最终在Grafana中展示。 - (3) Log归集:可以使用
Loki,通过Loki的组件promtail进行日志收集,并最终在Grafana中展示。这部分我已经写过文章:【k8s学习】Grafana Loki在Kubernetes中的安装(超详细),这篇文章详细的介绍了Grafana loki的安装,以与Grafana本身的安装,通过一个示例的Spring Boot项目最终将日志归集到Loki中,并在Grafana的Explore中通过LogQL进行查询、展示。 - (4) metrics归集:可以使用
victoria metrics进行存储,并最终在Grafana中展示。 - (5) 另外,Monitoring或是Alerting:可以使用
Prometheus。
3. 实现Distributed trace id的生成、存入、展示
依照#2的思路,本文主要是实现Distributed trace id相关的功能:
【所以需要做的有】:
- 通过Java Instrumentation生成trace id。
-->第4章 - 安装OpenTelemetry collector收集trace id。
- 在collector中配置exporter,将trace id推至Tempo存储起来。
- 在Grafana中配置Tempo数据源,以便可以通过UI查看。
【由于collector的安装相关,篇幅比较大,单独放另一篇文章。本文主要是在本地的java项目中,集成Opentelemetry的Instrumentation。】
4. 应用程序的instrumentation
关于这块,可以查看官网:opentelemetry.io/docs/instru…
可以看到OpenTelemetry支持不同语言的instrumentation:
4.1 Java的Instrumentation
点击Java相关的页面,可以看到Instrumentation分为:
Automatic Instrumentation(自动的Instrumentation):支持Java+的应用,它会自动的生成一些bytecode注入到我们的项目中,以便收集telemetry相关的数据,如进来的request,出去的http call,数据库call等等。Manual Instrumentation(手动的Instrumentation)
4.2 示例 - 基于自动的Instrumentation
如何自动化生成traceId,举个例子:
- 先从官网页面上下载 opentelemetry-javaagent.jar
- 再在启动的时候加上:
java -javaagent:path/to/opentelemetry-javaagent.jar -jar myapp.jar - ps. 如果使用IDEA启动Spring Boot,可以在VM Options加,jar的路径可以是全路径。如:
- 在log的pattern中加上
%X,如: - 打印出来的日志sample:
2022-08-01 17:39:11.735 trace_id=de6441b0701b34536d51b6333e95b0af, trace_flags=01, span_id=180fff77be7955ad [http-nio-8080-exec-1] INFO com.controller.VersionController [] - i am log. - 可以看到trace相关的,自动加上了。
最后,可能会在日志中看到一些错误的日志,如:[otel.javaagent 2022-08-01 17:39:12:862 +0800] [OkHttp http://localhost:4317/...] ERROR io.opentelemetry.exporter.internal.grpc.OkHttpGrpcExporter - Failed to export spans. The request could not be executed. Full error message: Failed to connect to localhost/[0:0:0:0:0:0:0:1]:4317
那是因为我们还没有配置Collector。
4.3 关于trace的规范
Opentelemetry关于trace的规范,遵循的是w3(万维网联盟)的trace-context标准,主要包括trace_id, span_id(parent_id), trace_flags等等,具体查看:www.w3.org/TR/trace-co…
5. Collector相关
5.1 Collector安装(kubernetes版本)
- collector官网:opentelemetry.io/docs/collec…
- 关于Collector,github上有些图,可能会有所启发:github.com/open-teleme…
helm chart add:
helm repo add open-telemetry open-telemetry.github.io/opentelemet…
列出chart:
helm search repo open-telemetry
可以看到主要有两个版本:
opentelemtry-collector:- 这个版本只是collecor的安装,需要在项目中自挂第4章的agent.jar,也就是java在打docker image的时候也要Include进这个agent.jar,这样比较麻烦。
- Github:github.com/open-teleme…
opentelemetry-operator:- 后来官方出了全自动的方式,即通过operator管理,然后自定义两个CRD组件(
Instrumentation和OpenTelemetryCollector) - Github:github.com/open-teleme…
- 【这里强列建议直接在prod上使用operator的方式进行管理】。所以本文也就不单独安装上述的collector了。
- 后来官方出了全自动的方式,即通过operator管理,然后自定义两个CRD组件(
5.2 配置介绍
官网:opentelemetry.io/docs/collec…
无论采用上述哪种安装方式,都会有三个方面的配置:
从Github上的图可以看出,每个组件都支持多个配置。
比如把上述helm chart collector相关的value输出到本地,helm show values open-telemetry/opentelemetry-collector > collector-value.yaml -n monitoring,可以看到config的receivers配置了:
jaeger,关于jaeger可参考网友的文章:一分钟部署高可用的分布式链路追踪系统-Jaegerotlp,这个为collector自带的grpc收集器prometheuszipkin
也可配多个exporters,如tempo,jaeger等等。