【Monitoring】OpenTelemetry介绍,在项目中集成trace_id以及Kubernates中helm chart版本选择

1,142 阅读6分钟

【文章目标】

  1. OpenTelemetry介绍
  2. OpenTelemetry架构
  3. 在java项目中生成Distributed trace id
  4. 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 tracesmetricslogs.

OpenTelemetry,简称OTel,是专注Observability相关的开源框架,包含的功能有traces, metris, logs的自动收集、管理、导出等。

Observability:[计算机]可观察性

1.2 OpenTelemetry的一些重要概念

可以查看官网:opentelemetry.io/docs/concep…

  • Observability:可以让我们从外部了解一个系统,即可能在不了解一个系统的情况下,帮助我们了解这个系统的问题。因此,这个系统也必须暴露出一些signals,如:tracesmetricslogs。当一个程序已经有了这些指标后,那么开发人员并不需要额外的再增加更多的指标来做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)
  • 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…

image.png

可以看到:

  • (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相关的功能: image.png

【所以需要做的有】:

  • 通过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: image.png

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的路径可以是全路径。如: image.png
  • 在log的pattern中加上%X,如: image.png
  • 打印出来的日志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版本)

helm chart add:

helm repo add open-telemetry open-telemetry.github.io/opentelemet…

列出chart:

helm search repo open-telemetry

可以看到主要有两个版本: image.png

  • opentelemtry-collector
    • 这个版本只是collecor的安装,需要在项目中自挂第4章的agent.jar,也就是java在打docker image的时候也要Include进这个agent.jar,这样比较麻烦。
    • Github:github.com/open-teleme…
  • opentelemetry-operator
    • 后来官方出了全自动的方式,即通过operator管理,然后自定义两个CRD组件(InstrumentationOpenTelemetryCollector)
    • Github:github.com/open-teleme…
    • 【这里强列建议直接在prod上使用operator的方式进行管理】。所以本文也就不单独安装上述的collector了。

5.2 配置介绍

官网:opentelemetry.io/docs/collec…

无论采用上述哪种安装方式,都会有三个方面的配置:

image.png

从Github上的图可以看出,每个组件都支持多个配置。

比如把上述helm chart collector相关的value输出到本地,helm show values open-telemetry/opentelemetry-collector > collector-value.yaml -n monitoring,可以看到config的receivers配置了:

也可配多个exporters,如tempo,jaeger等等。