← 文章 / 云原生与基础设施
signoz 4小时前 · 2026-10-08 04:11:31 · 3 阅读

NGINX OpenTelemetry 插桩 - 追踪请求

本指南介绍如何用 OpenTelemetry 在 NGINX 中追踪请求,并把 span 发送到 SigNoz。你只需加载 NGINX 原生的 OpenTelemetry 模块(ngx_otel_module),将其指向 SigNoz,NGINX 就会为它处理的每个请求创建一个 server span。

使用自托管 SigNoz?

大部分步骤完全相同。只需把 exporter 端点设为 http://<signoz-host>:4317,并删除 header signoz-ingestion-key 这一行。详情参见 Cloud → Self-Hosted。

前提条件

  • x86-64 或 ARM64 架构的 Linux
  • 来自 nginx.org 软件包的 NGINX,或官方 nginx Docker 镜像。模块软件包与这些构建版本匹配,Ubuntu 和 Debian 官方仓库不提供该模块。
  • 一个 SigNoz 实例(Cloud 或 Self-Hosted 均可)

将 trace 发送到 SigNoz

VM / Docker / Kubernetes / 哪些算 VM?

VM 是运行在物理硬件上的虚拟计算机,包括:

  • 云 VM:AWS EC2、Google Compute Engine、Azure VM、DigitalOcean Droplet
  • 本地 VM:VMware、VirtualBox、Hyper-V、KVM
  • 裸金属服务器:运行 Linux 的物理服务器

如果你在服务器或 VM 上以非容器方式运行 NGINX,请参考本节。

第 1 步:安装 OpenTelemetry 模块

按照官方 NGINX 指南为你的发行版配置 nginx.org 软件包仓库,然后安装 NGINX 和模块:

Debian / Ubuntu / RHEL 及其衍生版 / 复制
sudo apt update
sudo apt install nginx nginx-module-otel
复制
sudo yum install nginx nginx-module-otel

该软件包会把 ngx_otel_module.so 安装到 /etc/nginx/modules/ 目录。

第 2 步:加载模块

在 /etc/nginx/nginx.conf 文件顶部、所有 block 之外添加这一行:

/etc/nginx/nginx.conf
load_module modules/ngx_otel_module.so;

第 3 步:配置 exporter

创建 /etc/nginx/conf.d/otel.conf。默认的 nginx.conf 会在其 http 块中包含 conf.d/*.conf,因此这些指令将应用于所有服务器: /etc/nginx/conf.d/otel.conf
otel_exporter {
    endpoint https://ingest.<region>.signoz.cloud:443;
    header signoz-ingestion-key <your-ingestion-key>;
}
 
otel_service_name <service-name>;
otel_resource_attr service.version <service-version>;
otel_trace on;
otel_trace_context propagate;

请核对以下取值:

  • <region>:您的 SigNoz Cloud 区域
  • <your-ingestion-key>:您的 SigNoz ingestion key
  • <service-name>:此 NGINX 实例的描述性名称(例如 edge-nginx)
  • <service-version>(可选):您的发布版本或 git SHA(例如 1.4.2)。如果不需要,请删除该行。

两条指令控制追踪:

  • otel_trace on 会为每个请求创建一个 span。
  • otel_trace_context propagate 会延续传入的 W3C traceparent 头,并将上下文传递给上游服务器。被仪表化的后端随后会加入同一 trace。

步骤 4. 重启 NGINX

检查配置,然后重启 NGINX:

Copy
sudo nginx -t
sudo systemctl restart nginx

nginx -t 应输出 syntax is ok 和 test is successful。请使用 restart 而非 reload:新安装的 nginx.org 服务默认处于停止状态,reload 在停止的服务上会失败。

官方的 nginx 镜像提供带 -otel 标签的版本(例如 nginx:1.31-otel),这些镜像已包含该模块。镜像在启动时会在 /etc/nginx/templates/ 下的文件中填充环境变量,因此您可以在运行时传入 ingestion key。

步骤 1. 创建导出器模板

在您的 Dockerfile 旁边创建 otel.conf.template:

otel.conf.template
otel_exporter {
    endpoint https://ingest.<region>.signoz.cloud:443;
    header signoz-ingestion-key ${SIGNOZ_INGESTION_KEY};
}
 
otel_service_name <service-name>;
otel_trace on;
otel_trace_context propagate;

请核对以下值:

  • <region>:你的 SigNoz Cloud 区域
  • <service-name>:此 NGINX 实例的描述性名称(例如 edge-nginx)

请保留 ${SIGNOZ_INGESTION_KEY} 原样不变。容器启动脚本会将其替换为环境变量。

第 2 步。创建 Dockerfile

Dockerfile
FROM nginx:1.31-otel
 
# load_module 必须位于 nginx.conf 的第一行
RUN sed -i '1i load_module modules/ngx_otel_module.so;' /etc/nginx/nginx.conf
 
COPY otel.conf.template /etc/nginx/templates/otel.conf.template
COPY default.conf /etc/nginx/conf.d/default.conf

请用你自己的服务器配置替换 default.conf。该镜像会将渲染后的模板写入 /etc/nginx/conf.d/otel.conf,默认 nginx.conf 会在其 http 块中包含此文件。

第 3 步。构建并运行容器

复制
docker build -t nginx-otel .
docker run -d -p 8080:80 -e SIGNOZ_INGESTION_KEY="<your-ingestion-key>" nginx-otel

请核对以下值:

此设置运行官方的 nginx:1.31-otel 镜像,并从 ConfigMap 挂载其配置。Secret 用于存储摄入密钥。

第 1 步。创建用于摄入密钥的 Secret

复制
kubectl create secret generic signoz-ingestion \
  --from-literal=ingestion-key="<your-ingestion-key>"

请核对以下值:

第 2 步。创建 ConfigMap

ConfigMap 包含两个文件。nginx.conf 用于加载模块并存放你的 server 块。otel.conf.template 存放导出器设置,镜像会在启动时填入摄入密钥:

nginx-otel-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-otel
data:
  nginx.conf: |
    load_module modules/ngx_otel_module.so;
 
    worker_processes auto;
    events {}
 
    http {
        include /etc/nginx/conf.d/otel.conf;
 
        server {
            listen 80;
            location / {
                proxy_pass http://<upstream-service>:<port>;
            }
        }
    }
  otel.conf.template: |
    otel_exporter {
        endpoint https://ingest.<region>.signoz.cloud:443;
        header signoz-ingestion-key ${SIGNOZ_INGESTION_KEY};
    }
    otel_service_name <service-name>;
    otel_trace on;
    otel_trace_context propagate;
展开 23 行

请核对以下配置值:

  • <region>:你使用的 SigNoz Cloud 区域
  • <service-name>:这个 NGINX 实例的描述性名称(例如 edge-nginx)
  • <upstream-service>:<port>:NGINX 代理到的 Kubernetes Service。请将 server 块替换为你自己的配置。
警告

这里只能 include conf.d/otel.conf,不能用 conf.d/*.conf。镜像自带一个 conf.d/default.conf,它同样监听 80 端口,会在你的 server 块之前抢先返回欢迎页面。

步骤 3. 在 Deployment 中挂载 ConfigMap

在 Deployment 的 NGINX 容器中添加环境变量和卷挂载:

nginx-deployment.yaml
spec:
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.31-otel
        env:
        - name: SIGNOZ_INGESTION_KEY
          valueFrom:
            secretKeyRef:
              name: signoz-ingestion
              key: ingestion-key
        volumeMounts:
        - name: nginx-otel
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: nginx-otel
          mountPath: /etc/nginx/templates/otel.conf.template
          subPath: otel.conf.template
      volumes:
      - name: nginx-otel
        configMap:
          name: nginx-otel

步骤 4. 应用变更

复制
kubectl apply -f nginx-otel-configmap.yaml
kubectl apply -f nginx-deployment.yaml
kubectl rollout status deployment/<deployment-name>

请核对以下配置值:

  • <deployment-name>:运行 NGINX 的 Deployment

验证

  1. 向 NGINX 发送若干请求,例如执行 curl http://localhost/。
  2. 打开 SigNoz,进入 Traces 页面。
  3. 根据 otel_service_name 设置的 service.name 进行过滤。
SigNoz Traces Explorer listing NGINX request spans filtered by service.name edge-nginx
Traces Explorer 中按服务名过滤后的 NGINX 请求 span
  1. 点击某个 span,查看其属性,例如 http.method、http.target 和 http.status_code。
SigNoz trace detail view showing an NGINX server span with its HTTP attributes
该模块记录的包含相关属性的 NGINX 服务 span

NGINX 每 5 秒导出一次 span,请在刷新前等待几秒。

每个 span 以匹配请求的 location 块命名,例如 / 或 /api/orders。如需设置不同名称,请在 location 块内添加 otel_span_name:

Copy
location /api/orders {
    otel_span_name "GET /api/orders";
    proxy_pass http://orders:8080;
}

NGINX 将 5xx 响应的 span 标记为错误。对于 4xx 响应,span 保持未设置状态。

故障排除

NGINX 会将导出器错误写入错误日志。在虚拟机上,请检查 /var/log/nginx/error.log。在 Docker 和 Kubernetes 环境中,运行 docker logs <container> 或 kubectl logs deployment/<deployment-name>。

为什么 nginx -t 报告 unknown directive "otel_exporter"?

NGINX 未加载该模块。请在 nginx.conf 的第一行添加 load_module modules/ngx_otel_module.so;,位置需在所有块外部,

原始来源: signoz

评论 (0)