Java 自动插桩

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

Java 自动插桩的工作原理

operator 会将 OpenTelemetry Java agent 作为 Java agent JAR 文件注入到 Java 应用容器中。该 agent 使用字节码插桩在运行时自动为 Java 类添加埋点,从以下来源捕获 telemetry 数据:

  • 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,并通过设置 JAVA_TOOL_OPTIONS 环境变量和 -javaagent 标志,配置 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

卷挂载

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.26.1
    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 镜像,因此你必须自行构建或提供一个。请参阅 Instrumentation Options 中的警告。
  2. OTLP exporter 端点。请将此 URL 替换为你实际的 OpenTelemetry Collector 地址。
  3. 为此 pod 启用 Java 自动插桩注入。有关可接受的值,请参阅 Supported Values for Injection Annotations

将应用日志与 trace 关联

一旦注入了 Java agent,它还可以将当前活动的 trace_idspan_id 添加到应用日志中,让你能够在日志行和对应 trace 之间快速切换。有关 Spring Boot、Logback 和 Log4j 2 的示例,请参阅 Correlating Application Logs with Traces

配置参考

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

Java Auto-instrumentation Documentation