1. 前言

前几天我写了一篇文章,简单介绍了OpenTelemetry OBI,也就是OpenTelemetry+eBPF的方案。这个方案采用零侵入的方式,做起来很容易,工具下载下来以后几分钟搞定演示程序,适用于各种编程语言。但是这种方式监控的metrics和trace都比较受限。

有人问我为什么不介绍一下最近OpenTelemetry发展起来的对Profiling的支持(traces,metrics,logs之外的第4类监控信号数据)。这个主要是因为OpenTelemetry对Profiling的支持还在发展之中。另外很多人不喜欢那种修改代码的侵入式解决方案。OpenTelemetry有基于eBPF的零侵入方案支持Profiling,但是它对系统安装和编译的要求又比较繁琐,出来的火焰图与高级编程语言的堆栈很难对照。

相对而言,如果采用OpenTelemetry加上Grafana提供的LGTM(Looks Good To Me)后端系统,可以轻松地得到traces,metrics,logs和profiles,可以很容易做一个演示程序。其中traces,metrics,logs是纯粹OpenTelemetry的解决方案。而profiles只是一个过渡方案,等OpenTelemetry Profiles稳定下来,就会并入纯OpenTelemetry工具。

这篇文章只选择Java应用的做法。其它语言也有类似的方案。有些语言在非侵入监控方面还做得不够好。
我在这个演示里面没有直接用到OpenTelemetry Collector。OpenTelemetry Collector是极其重要的工具,但LGTM里面已经内置了OpenTelemetry Collector。


2. 下载工具并运行Java应用

 2.1 搭建一个支持OTLP端口的后端监控系统

 OpenTelemetry的后端工具,就是支持OpenTelemetry metrics/traces/logs/profiles的数据库和UI的工具集。最常见的做法还是使用OpenTelemetry Collector来连接不同的后端工具。假如您是初学者,或者系统很小,可以直接使用基于Docker的Grafana LGTM,几乎是一键安装完成,非常简单易行。前提是需要您有个支持Docker的环境。

假设您想把LGTM安装到/opt/lgtm目录 (任何目录均可),下面是命令(假设在Linux系统):

docker pull grafana/otel-lgtm

mkdir /opt/lgtm
cd /opt/lgtm
wget https://raw.githubusercontent.com/grafana/docker-otel-lgtm/main/run-lgtm.sh
chmod +x run-lgtm.sh
sed -i 's/3000:3000/3100:3000/' run-lgtm.sh

注意最后一行命令,因为LGTM的Grafana的默认对外端口是3000,这个端口经常和一些应用程序冲突,我就改成了3100.

下面是启动LGTM的方法,就一个命令:

cd /opt/lgtm
./run-lgtm.sh

LGTM要监听以下的端口:

  • 4317/4318 是OTLP端口,用来接受metrics/traces/logs数据
  • 3100 是Grafana UI的端口
  • 9090 是Prometheus的端口,用于调试
  • 4040 是Pyroscope接受Profiles的端口,将来会整合进入4317/4318

2.2 下载OpenTelemetry Java Agent (opentelemetry-javaagent.jar)

这个Agent被用于自动注入Java应用,输出OpenTelemetry traces,metrics,logs。到这个地址下载最新版本即可。

2.3 下载pyroscope.jar

这个Agent被用于自动注入Java应用,输出profiles。到这个地址下载最新版本即可。等OpenTelemetry Profiles成熟了,应该会被加入到上面那个标准的opentelemetry-javaagent.jar。如果您不想用OpenTelemetry Profiles,也可以不下载这个Agent。

2.4 运行一个自己的Java应用

如果手头没有Java应用的话,可以到这里下载一个(这个示例程序叫做petclinic)。注意这个应用要用JDK17和比较新版本的Maven进行编译:

./mvnw clean package -Dmaven.test.skip=true

然后用以下命令去执行它(opentelemetry-javaagent.jar和pyroscope.jar要在当前的目录):

export OTEL_SERVICE_NAME=my-service
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
java -javaagent:./opentelemetry-javaagent.jar -javaagent:./pyroscope.jar  -jar target/*.jar --server.port=28080

注意:

  • 如果您不用OpenTelemetry Profiles,可以删除“-javaagent:/opt/dev/otel/res/pyroscope.jar”。
  • 上面列出的环境变量都是OpenTelemetry的标准环境变量,适用于各种编程语言。读者可自行查询其含义。
  • 如果OpenTelemetry后端或者Collector(本例是LGTM)不在本机,那么OTEL_EXPORTER_OTLP_ENDPOINT的值就不要写localhost,换成实际的IP地址或者主机名。

3. 配置LGTM的Grafana来观察metrics,traces,logs和profiles

使用“http://localhost:3100”就可以访问LGTM的Grafana UI界面(如果是远程的话,用主机名或者IP替换localhost),使用admin/admin登录。

这是系统自带的一个Dashboard(名字叫做JVM Overview)的片段,读者可以自己看它的源码。OpenTelemetry Java Agent提供的metrics非常多,可以做一个内容非常丰富的Dashboard:

 以下是在Explorer上配置metrics的页面:

以下是查看Traces(追踪)的页面:

以下是查看Logs(日志)的页面(没有出错的情况下这个Agent收集的日志较少):

以下是查看Profiles的页面(我选择了火焰图(Flame Graph),可以看出不同调用栈的CPU消耗):

4. 总结

从上面的描述可以看出,使用OpenTelemetry监控Java应用是非常容易的。其主要工具是一个OpenTelemetry Java agent。另外还可以采用一个Grafana提供的Agent来采基Profiles的数据。其实,如果应用使用了Spring Boot 3提供的OpenTelemetry内置支持,OpenTelemetry Java agent也可以省略。当然OpenTelemetry Java agent可以支持各种Java框架,不一定是Spring Boot。
支持OpenTelemetry非侵入式的注入(或者说Automatic Instrumentation)的编程语言有很多,比如Java, Python, .Net, Node.JS等等。其它编程语言也各自有自己的办法。比如Go语言与eBPF结合的效果特别好。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐