← 文章 / 云原生与基础设施
signoz 3小时前 · 2026-09-25 20:10:08 · 1 阅读

OpenTelemetry 注入器 —— Linux 零代码配置指南

OpenTelemetry Injector 可以在 Linux 主机上为 Java、Node.js、.NET 和 Python 应用自动插桩,无需修改任何代码。只需安装一个系统包,`LD_PRELOAD` 就会把它的共享库加载进每个新进程,该库会设置启动 OpenTelemetry agent 所需的环境变量。当一台主机上运行着多种语言的服务时特别好用,这样 SigNoz 端点和采集密钥可以统一放在一个文件里。 只跑一个服务?或者用的是其他语言?
  • 如果只有单个应用,各语言单独的接入指南更简单:Java、Node.js、.NET 和 Python。
  • Injector 不支持其他运行时。Go、PHP、Rust 和 C++ 需要参考各语言指南或使用 eBPF 插桩。
  • 用的是自托管版 SigNoz?

    步骤完全相同,只需把导出端点指向你自己的 OpenTelemetry Collector 或 SigNoz 实例,并去掉采集密钥请求头,具体参见Cloud -> Self-Hosted。

    前提条件

    • 一台 Linux 主机,运行 Debian、Ubuntu、RHEL、Fedora 或 Amazon Linux,架构为 amd64 或 arm64。
    • 主机上的 root 权限。Injector 需要写入 /etc/ld.so.preload,并从 /etc/opentelemetry/ 读取配置。
    • 应用运行在以下运行时之一:
      • Java
      • Node.js 20.6 及以上。Node.js 18.19 及之后的 18.x 版本也可用;Node.js 19 以及 20.0 到 20.5 不支持。
      • .NET 8 及以上
      • Python 3.10 及以上
    • 一个 SigNoz 实例(Cloud 或 Self-Hosted 均可)。

    工作原理

    Injector 库会在主机上每个新进程启动时运行。

    新进程执行 exec,动态链接器从 /etc/ld.so.preload 加载 libotelinject.so,注入器调用 setenv 为该运行时设置变量,OpenTelemetry 代理将 OTLP 导出到 SigNoz
    注入器为运行时设置启动变量,代理负责导出数据

    对于每个进程,注入器执行以下操作:

    1. 读取进程使用的 C 库,即 glibc 或 musl。静态链接的二进制文件永远不会加载注入器,因为动态链接器不会为其运行。
    2. 从 /etc/opentelemetry/injector/injector.conf 和 conf.d/ 中的 drop-in 文件读取代理路径。每种语言包会安装一个 drop-in 文件。
    3. 设置启动代理所需的环境变量,并添加 default_env.conf 中的变量,该文件包含你的 SigNoz 端点和密钥。

    注入器不建立任何网络连接。每个代理自行将遥测数据导出到你配置的端点。

    你可以从所有语言获取追踪和指标。日志仅在应用通过代理已插桩的框架记录时才会到达:Java 使用 Logback 或 Log4j,Node.js 使用 Winston、Pino 或 Bunyan,.NET 使用 ILogger,Python 使用 logging 模块。System.out.println 和 console.log 不会发送日志。

    将数据发送到 SigNoz

    第 1 步。安装包

    添加软件包仓库并安装元包。元包会安装注入器以及所有四种语言的代理。

    这些软件包较新,仓库 URL 可能会发生变化

    OpenTelemetry 打包项目发布这些软件包。当前版本为 v0.0.3。该项目在 GitHub Pages 上托管 APT 和 YUM 仓库,并将其视为一种 临时解决方案。当软件包迁移到永久基础设施时,仓库 URL 将会变更。请首先在非生产主机上测试注入器。

    Debian 和 Ubuntu RHEL、Fedora 以及 Amazon Linux 复制
    echo "deb [trusted=yes] https://open-telemetry.github.io/opentelemetry-packaging/debian stable main" | sudo tee /etc/apt/sources.list.d/opentelemetry.list
    sudo apt update
    sudo apt install opentelemetry
    Copy
    cat <<EOF | sudo tee /etc/yum.repos.d/opentelemetry.repo
    [opentelemetry]
    name=OpenTelemetry Auto-Instrumentation System Packages
    baseurl=https://open-telemetry.github.io/opentelemetry-packaging/rpm/packages
    enabled=1
    gpgcheck=0
    EOF
     
    sudo dnf install opentelemetry

    安装包 opentelemetry-injector 会在安装过程中自动把 /usr/lib/opentelemetry/injector/libotelinject.so 写入 /etc/ld.so.preload,你无需手动编辑该文件。安装成功时会输出以下提示:

    Copy
    OpenTelemetry Injector installed successfully.
    Install one language only

    若只需为单一语言安装 agent,请单独指定 injector 包和对应的 agent 包,而非使用元包。在 RHEL 及其衍生版发行版上,请将 apt 替换为 dnf。

    Copy
    sudo apt install opentelemetry-injector opentelemetry-java-autoinstrumentation

    其他可用的 agent 包包括 opentelemetry-nodejs-autoinstrumentation、opentelemetry-dotnet-autoinstrumentation 以及 opentelemetry-python-autoinstrumentation。

    Step 2. Point the agents at SigNoz

    文件 /etc/opentelemetry/injector/default_env.conf 保存了主机上所有 agent 接收的环境变量。默认情况下 agent 会将数据导出到 localhost,因此你需要在此处配置 SigNoz 的端点。

    在文件末尾追加以下三个变量:

    Copy
    cat <<'EOF' | sudo tee -a /etc/opentelemetry/injector/default_env.conf
    OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<region>.signoz.cloud:443
    OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<your-ingestion-key>
    OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
    EOF

    请核对以下值:

    Injector 只会传递以 OTEL_ 开头的变量,该文件中的其他行会被忽略。

    你的接入密钥存放在一个所有用户可读的文件里

    软件包安装的 default_env.conf 权限是 0644,主机上任何用户都能读到你的接入密钥。而 injector 是以应用用户身份读取该文件的,如果改成 0600,所有非 root 运行的服务都会失效——它会在 debug 级别记录一条 error.AccessDenied 失败日志,随后 agent 把数据导出到 localhost,什么也发不出去。

    建议把权限设为 0640 并指定一个属组,然后让服务以该组内的用户身份运行。如果不想让密钥落在应用主机上,可以改用本地 Collector 转发遥测数据。

    第 3 步:为每个服务命名

    injector 会从进程环境中读取 OTEL_INJECTOR_SERVICE_NAME,并写入 service.name 属性。这个变量需要为每个服务单独设置。如果你只在 default_env.conf 里设置了一个名字,主机上所有进程在 SigNoz 中都会以这个名字上报。

    对于由 systemd 启动的服务,把变量加到 unit override 里。把 <unit-name> 替换为对应的 systemd unit(例如 payments),把 <service-name> 替换为你希望在 SigNoz 中显示的名字:

    Copy
    sudo systemctl edit <unit-name>

    在打开的编辑器中加入下面两行,然后保存:

    Copy
    [Service]
    Environment=OTEL_INJECTOR_SERVICE_NAME=<service-name>

    第 4 步:重启应用

    injector 只对新启动的进程生效,需要重启想要插桩的每个应用:

    Copy
    sudo systemctl restart <unit-name>

    已经在运行的进程会保留旧的环境变量,直到你重启它们。

    验证

    向应用发送几个请求,然后打开 SigNoz。

    打开 Services 页面,一两分钟内就能看到你的服务及其请求速率、错误率和延迟。

    打开 Traces 页面并按服务名过滤。进来的 HTTP 请求会显示为 server span,对数据库和其他服务的调用则显示为子 span。

    SigNoz Traces Explorer filtered on service.name CONTAINS 'otel-injector', listing GET /ping, GET /call, and outbound GET spans from four services
    来自同一台主机上、由 Injector 统一采集的四种语言、四个服务的 Span

    打开 Metrics 面板并筛选至特定服务。该代理会上报 HTTP 耗时与请求次数,以及对应运行时语言的指标。

    SigNoz Metrics Explorer filtered on one injector-instrumented service, listing HTTP client and server duration histograms
    来自未引入 OpenTelemetry 代码的服务的 HTTP 耗时直方图

    打开 Logs 面板并按服务名筛选。只有通过已被插桩的框架记录日志的应用程序才会将日志上报至此。每条日志记录都携带该请求的 Trace ID 和 Span ID,因此你可以从日志直接跳转至对应的 Trace。

    SigNoz Logs Explorer showing log records from injector-instrumented services, with the detail panel showing a populated trace ID and span ID
    带有 Trace ID、Span ID 及主机资源属性的日志记录

    若要确认 Injector 已针对某个进程生效,可在启动该进程时调高 Injector 的日志级别:

    Copy
    OTEL_INJECTOR_LOG_LEVEL=debug <your start command>

    Injector 会为它设置的每个变量打印一行日志,覆盖所有语言:

    Copy
    [otel-injector] [12345] setting "JAVA_TOOL_OPTIONS"="-javaagent:/usr/lib/opentelemetry/java/opentelemetry-javaagent.jar"
    [otel-injector] [12345] setting "NODE_OPTIONS"="--require /usr/lib/opentelemetry/nodejs/register.js"
    [otel-injector] [12345] setting "PYTHONPATH"="/usr/lib/opentelemetry/python/glibc"

    Java 应用的输出首行也会标明该代理的名称:

    复制
    Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/lib/opentelemetry/java/opentelemetry-javaagent.jar
    /proc/<pid>/environ 中并未显示注入的变量

    注入器调用 setenv

    原始来源: signoz

    评论 (0)