作者:来自 Elastic Sylvain Juge 及 Alexander Wert
学习如何使用 OpenTelemetry 通过 Java agent 或 jmx-scraper 收集 Tomcat JMX 指标,然后通过自定义 YAML 规则扩展覆盖范围并验证输出。
Java 管理扩展 (JMX) 是 JVM 内置的管理接口,公开运行时和组件指标,如内存、线程和请求池。它对于从 Java 服务收集运营遥测非常有用,而无需更改应用程序代码。
使用 OpenTelemetry 收集 JMX 指标主要有两种方式,取决于你的环境、需求和限制:
-
在 JVM 内部使用 OpenTelemetry Instrumentation Java agent(或 EDOT Java)
-
在 JVM 外部使用 jmx-scraper
在本文中,我们使用 “Java agent”一词指代 OpenTelemetry Java instrumentation agent,这同样适用于基于它的 Elastic 自有发行版 (EDOT Java),它提供相同功能。
本教程以 Tomcat 服务器为目标,演示如何使用 logging exporter 验证哪些指标被输出。
本文的配置示例使用 Java 系统属性,必须通过 JVM 启动命令中的 -D 参数传递,也可以使用等效的环境变量进行配置。
前提条件
-
本地 Tomcat 安装(或任何可以通过自定义 JVM 参数启动的 JVM 应用)
-
主机上安装 Java 8 及以上版本,但所使用的 Tomcat 版本可能需要更高版本
-
如果你希望将指标发送到本地日志以外的位置,需要一个 OpenTelemetry Collector 端点
选择 Java agent 与 jmx-scraper 之间的方法
当你可以修改 JVM 启动参数并希望在进程内收集完整上下文的指标时,使用 Java agent(或 EDOT Java):这允许通过单个工具部署同时捕获 traces、logs 和 metrics。
当你无法在 JVM 上安装 agent 或希望从独立主机进行进程外收集时,使用 jmx-scraper:这需要配置 JVM 和网络以支持远程 JMX 访问,同时处理认证和凭据问题。
这两种方法都依赖相同的 JMX 指标映射,可以使用 logging exporter 进行验证,然后通过 OTLP 将指标发送到 collector 或 OTLP 端点。
选项 1:使用 Java agent 在 JVM 内收集 JMX 指标
OpenTelemetry Java instrumentation 提供了一套精选的 JMX 指标映射。对于 Tomcat,你只需启用 Java agent 并设置 otel.jmx.target.system=tomcat。
步骤 1 - 下载 OpenTelemetry Java agent
Agent 默认下载到 /opt/otel,但你可以在主机上选择任意位置。确保路径与下一步的 -javaagent 参数一致。
`
1. mkdir -p /opt/otel
2. curl -L -o /opt/otel/opentelemetry-javaagent.jar \
3. https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
`AI写代码
步骤 2 - 配置 Tomcat 的 bin/setenv.sh
创建或更新 bin/setenv.sh,确保 Tomcat 启动时加载 agent 并启用 JMX 目标系统。
`
1. #!/bin/bash
2. export CATALINA_OPTS="$CATALINA_OPTS \
3. -javaagent:/opt/otel/opentelemetry-javaagent.jar \
4. -Dotel.service.name=tomcat-demo \
5. -Dotel.metrics.exporter=otlp,logging \
6. -Dotel.jmx.target.system=tomcat"
`AI写代码
这样配置后,agent 会使用 logging exporter 记录指标,同时将指标发送到 Collector。
步骤 3 - 验证输出的指标
启动 Tomcat 并查看 stdout。
`./bin/catalina.sh run` AI写代码
默认情况下,指标每分钟采样并输出一次,因此可能需要等待一会儿。必要时,可使用 otel.metric.export.interval 配置调整频率。
你应该看到 logging exporter 输出 JVM 和 Tomcat 指标,查找包含 LoggingMetricExporter 的行:
`
1. INFO io.opentelemetry.exporter.logging.LoggingMetricExporter - MetricData{name=tomcat.threadpool.currentThreadsBusy, ...}
2. INFO io.opentelemetry.exporter.logging.LoggingMetricExporter - MetricData{name=jvm.memory.used, ...}
`AI写代码
步骤 4 - 将指标发送到 Collector
验证指标捕获后,即可将指标发送到 collector。
你需要:
-
移除 logging exporter,因为生产环境不再需要
-
配置 OTLP 端点 (
otel.exporter.otlp.endpoint) 和头信息 (otel.exporter.otlp.headers)(如有必要)
修改后的 bin/setenv.sh 示例:
`
1. #!/bin/bash
2. export CATALINA_OPTS="$CATALINA_OPTS \
3. -javaagent:/opt/otel/opentelemetry-javaagent.jar \
4. -Dotel.service.name=tomcat-demo \
5. -Dotel.jmx.target.system=tomcat \
6. -Dotel.exporter.otlp.endpoint=https://your-collector:4317 \
7. -Dotel.exporter.otlp.headers=Authorization=Bearer <your-token>"
`AI写代码
使用 Java agent 时,JVM 指标会被 runtime-telemetry 模块自动捕获,因此无需在 otel.jmx.target.system 配置中包含 jvm。
选项 2:使用 jmx-scraper 在 JVM 外部收集 JMX 指标
当你无法在 JVM 内安装 agent,或者只需要收集指标时,jmx-scraper 允许你远程查询 JMX 并将指标导出到 OTLP 端点。
步骤 1 - 在 Tomcat 上启用远程 JMX
在 bin/setenv.sh 中添加 JMX 远程选项,并创建访问和密码文件。
⚠️ 注意:此示例使用简单凭据并禁用 SSL,请勿在生产环境中使用此配置。
`
1. mkdir -p /opt/jmx
2. cat <<EOF > ${CATALINA_HOME}/jmxremote.access
3. monitorRole readonly
4. EOF
6. cat <<EOF > ${CATALINA_HOME}/jmxremote.password
7. monitorRole monitorPass
8. EOF
10. chmod 600 ${CATALINA_HOME}/jmxremote.password
12. export CATALINA_OPTS="$CATALINA_OPTS \
13. -Dcom.sun.management.jmxremote \
14. -Dcom.sun.management.jmxremote.port=9010 \
15. -Dcom.sun.management.jmxremote.rmi.port=9010 \
16. -Dcom.sun.management.jmxremote.authenticate=true \
17. -Dcom.sun.management.jmxremote.ssl=false \
18. -Dcom.sun.management.jmxremote.access.file=${CATALINA_HOME}/jmxremote.access \
19. -Dcom.sun.management.jmxremote.password.file=${CATALINA_HOME}/jmxremote.password \
20. -Djava.rmi.server.host
`AI写代码
步骤 2 - 下载 jmx-scraper
agent 默认下载到 /opt/otel,但你可以选择主机上的任意位置。
`
1. mkdir -p /opt/otel
2. curl -L -o /opt/otel/opentelemetry-jmx-scraper.jar \
3. https://github.com/open-telemetry/opentelemetry-java-contrib/releases/latest/download/opentelemetry-jmx-scraper.jar
`AI写代码
步骤 3 - 检查 JMX 连接
使用上一步的凭据运行 jmx-scraper,确认能连接 Tomcat。如果凭据错误,会出现认证错误。
`
1. java -jar /opt/otel/opentelemetry-jmx-scraper.jar \
2. -Dotel.jmx.service.url=service:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi \
3. -Dotel.jmx.username=monitorRole \
4. -Dotel.jmx.password=monitorPass \
5. -Dotel.jmx.target.system=tomcat \
6. -test
`AI写代码
标准输出应显示:
-
JMX connection test OK:连接和认证成功 -
JMX connection test ERROR:连接或认证失败
步骤 4 - 验证输出的指标
使用 logging exporter 可以在发送到 collector 之前检查指标和属性。
如果要同时捕获 Tomcat 和 JVM 指标,需要将 otel.jmx.target.system 设置为 tomcat,jvm。
`
1. java -jar /opt/otel/opentelemetry-jmx-scraper.jar \
2. -Dotel.jmx.service.url=service:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi \
3. -Dotel.jmx.username=monitorRole \
4. -Dotel.jmx.password=monitorPass \
5. -Dotel.jmx.target.system=tomcat,jvm \
6. -Dotel.metrics.exporter=logging
`AI写代码
步骤 5 - 将指标发送到 Collector
验证完成后,要发送指标到 OTLP 端点,需要:
-
移除
-Dotel.metrics.exporter,以恢复 OTLP 默认值 -
配置 OTLP 端点 (
otel.exporter.otlp.endpoint) 和头信息 (otel.exporter.otlp.headers)(如有必要)
`
1. java -jar /opt/otel/opentelemetry-jmx-scraper.jar \
2. -Dotel.jmx.service.url=service:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi \
3. -Dotel.jmx.username=monitorRole \
4. -Dotel.jmx.password=monitorPass \
5. -Dotel.jmx.target.system=tomcat,jvm \
6. -Dotel.exporter.otlp.endpoint=https://your-collector:4317 \
7. -Dotel.exporter.otlp.headers="Authorization=Bearer <your-token>"
`AI写代码
在 Kibana 中使用 JMX 指标
一旦你使用本文介绍的方法收集了 JMX 指标,就可以在 Kibana 中开始使用它们。你可以构建自定义仪表板和可视化来探索和分析指标,在其基础上创建自定义告警,或者构建 MCP 工具和 AI Agents,将指标应用到 agentic 工作流中。
下面是通过 ES|QL 在 Kibana 中使用 JMX 指标的示例:
`
1. TS metrics*
2. | WHERE telemetry.sdk.language == "java"
3. | WHERE service.name == ?instance
4. | STATS
5. request_rate = SUM(RATE(tomcat.request.count))
6. BY Time = BUCKET(@timestamp, 100, ?_tstart, ?_tend)
`AI写代码
你可以使用 JMX 指标的原生 metric 和 dimension 名称来构建查询。使用 TS 命令,你可以对指标进行时间序列聚合函数和维度的一级支持。这类查询构成了仪表板、告警、工作流和 AI agent 工具的构建块。
下面是一个示例仪表板,用于可视化 Apache Tomcat 的典型 JMX 指标:
总结
在本文中,我们介绍了如何使用 OpenTelemetry 通过 Java agent 或 jmx-scraper 收集 JMX 指标。我们还演示了如何通过 ES|QL 在 Kibana 中使用 JMX 指标,构建自定义仪表板、告警、工作流和 AI agent 工具。
这只是 JMX 指标与 Elastic Observability 能力结合的开始。你可以亲自尝试,探索 JMX 指标在 Elastic Observability 平台强大功能支持下的全部潜力。