Java 自动插桩

Java 自动插桩使用 OpenTelemetry Java agent 为 Java 应用提供全面的遥测采集。此插桩可在无需修改代码的情况下,自动从 Java 应用和常用框架中捕获 trace、指标和日志。

Java 自动插桩的工作方式

Operator 会将 OpenTelemetry Java agent 作为 Java agent JAR 文件注入到 Java 应用容器中。该 agent 使用字节码插桩在运行时自动对 Java 类进行插桩,并从以下组件中采集遥测数据:

  • HTTP 服务器和客户端(Servlet、Spring MVC、JAX-RS 等)
  • 数据库客户端(JDBC、Hibernate 等)
  • 消息传递系统(JMS、Kafka、RabbitMQ 等)
  • RPC 框架(gRPC 等)
  • 缓存库(Redis、Memcached 等)
  • 以及许多其他常用 Java 库和框架

启用 Java 插桩

要为 Java 应用启用自动插桩,请为你的 pod 或 namespace 添加注解:

apiVersion: v1
kind: Pod
metadata:
  name: java-app
  annotations:
    instrumentation.opentelemetry.io/inject-java: "true"
spec:
  containers:
  - name: app
    image: myjavaapp:latest

Operator 会自动注入 Java agent,并通过设置带有 -javaagent 标志的 JAVA_TOOL_OPTIONS 环境变量,配置 JVM 在启动时加载它。

Java Agent 环境变量

以下环境变量用于控制 Java agent 的行为:

插桩控制

  • OTEL_JAVAAGENT_ENABLED - 启用或禁用 Java agent(默认:true
  • OTEL_JAVAAGENT_DEBUG - 为 agent 启用调试日志(默认:false
  • OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED - 默认启用所有插桩(默认:true

特定插桩控制

你可以启用或禁用特定插桩:

  • OTEL_INSTRUMENTATION_JDBC_ENABLED - JDBC 插桩
  • OTEL_INSTRUMENTATION_SPRING_WEB_ENABLED - Spring Web 插桩
  • OTEL_INSTRUMENTATION_KAFKA_ENABLED - Kafka 插桩
  • OTEL_INSTRUMENTATION_REDIS_ENABLED - Redis 插桩

配置示例:

spec:
  java:
    env:
      - name: OTEL_INSTRUMENTATION_JDBC_ENABLED
        value: "true"
      - name: OTEL_INSTRUMENTATION_KAFKA_ENABLED
        value: "true"
      - name: OTEL_INSTRUMENTATION_REDIS_ENABLED
        value: "false"

扩展配置

配置额外的 agent 扩展:

  • OTEL_JAVAAGENT_EXTENSIONS - 额外 agent 扩展的路径
  • OTEL_JAVAAGENT_CONFIGURATION_FILE - agent 配置文件的路径

高级配置

自定义 Agent 镜像

你可以指定自定义 Java agent 镜像:

spec:
  java:
    image: my-registry.com/custom-java-agent:my-tag

Volume 挂载

该 agent 会挂载到应用容器中的 /otel-auto-instrumentation-java-<container-name>/

按容器注入

对于多容器 Pod,指定需要进行插桩的容器:

metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-java: "true"
    instrumentation.opentelemetry.io/container-names: "app,worker"

支持的 Java 版本

OpenTelemetry Java agent 支持:

  • Java 8 及更高版本

故障排查

验证 Agent 注入

检查 agent 是否已成功注入:

kubectl describe pod <pod-name>

在容器命令中查找 -javaagent 参数。

启用调试日志

启用调试日志以排查问题:

spec:
  java:
    env:
      - name: OTEL_JAVAAGENT_DEBUG
        value: "true"
      - name: OTEL_LOG_LEVEL
        value: "debug"

常见问题

Agent 未加载:验证 init container 是否已成功完成,以及共享卷中是否存在 agent JAR。

缺少 trace:检查 exporter 端点是否正确,并且应用 Pod 能否访问该端点。

内存使用率高:减少已启用的插桩数量,或调整 JVM 堆设置。

示例配置

Java 应用插桩完整示例:

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: java-instrumentation
  namespace: java-development
spec:
  java:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.30.0
    env:
      - name: OTEL_JAVAAGENT_DEBUG
        value: "false"
  exporter:
    endpoint: http://otel-collector.observability.svc:4318
  env:
    - name: OTEL_RESOURCE_ATTRIBUTES
      value: deployment.environment.name=development
  sampler:
    type: parentbased_traceidratio
    argument: "1"
  propagators:
    - tracecontext
    - baggage
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
  namespace: java-development
spec:
  replicas: 1
  selector:
    matchLabels:
      app: java-app
  template:
    metadata:
      labels:
        app: java-app
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
    spec:
      containers:
      - name: app
        image: myjavaapp:latest
        ports:
        - containerPort: 8080
  1. Operator 用于注入 agent 的 Java 自动插桩镜像。v2 Operator 不提供 Java agent 镜像,因此你必须自行构建或提供一个。请参见 插桩选项 中的警告。
  2. OTLP exporter 端点。请将此 URL 替换为你实际的 OpenTelemetry Collector 地址。
  3. 为此 Pod 启用 Java 自动插桩注入。有关可接受的值,请参见 注入注解支持的值

将应用日志与 Trace 关联

一旦注入了 Java agent,它还可以将当前活动的 trace_idspan_id 添加到应用日志中,让你在日志行与其 trace 之间快速切换。有关 Spring Boot、Logback 和 Log4j 2 的示例,请参见 将应用日志与 Trace 关联

配置参考

有关详细的配置选项、受支持的库和高级使用场景,请参阅官方 OpenTelemetry Operator 文档:

Java 自动插桩文档