使用 OpenTelemetry 监控 OpenAI——追踪 Token 用量与成本
- Token 用量——追踪每次请求的输入和输出 token,了解成本构成
- 模型延迟——衡量不同模型和请求类型的响应时间
- 错误率——在 API 故障、限流错误和超时影响用户之前及时发现
- 请求追踪——在完整的应用调用链中跟踪每次 LLM 调用
环境要求
- Python 3.8 或更高版本
- OpenAI Python 库(
openai >= 1.0.0) - 有效的 OpenAI API key
- SigNoz 环境(二选一):
- SigNoz Cloud 账号,并持有有效的 ingestion key
- 自托管的 SigNoz 实例
搭建步骤
第 1 步:创建虚拟环境
Copypython3 -m venv .venv
source .venv/bin/activate第 2 步:安装 OpenTelemetry 依赖
Copypip install opentelemetry-distro opentelemetry-exporter-otlp
pip install httpx无需手动安装 opentelemetry-instrumentation-openai-v2。下一步的 opentelemetry-bootstrap 会检测环境中的 openai,并自动安装对应的 instrumentation,处理 requests、fastapi、psycopg 时也是同样的方式。
httpx 是 bootstrap 唯一不会自动处理的依赖,即使你不直接使用它也必须安装。OpenAI Python SDK v3 自带的 HTTP client 模块名为 httpx2,而 opentelemetry-instrumentation-openai-v2 仍在使用 from httpx import URL。如果没装 httpx,这个 import 会抛出 ModuleNotFoundError,opentelemetry-instrument 会静默跳过 OpenAI instrumentor,导致你的 OpenAI 调用只显示为普通的 POST span,没有 gen_ai.* 属性,也不会有任何报错提示原因。
第 3 步:添加自动埋点
Copyopentelemetry-bootstrap --action=install
InfoBootstrap 探针仅对环境变量中已安装的组件进行插桩,因此请在应用自身依赖(包括 openai)安装完成后运行此命令。若后续添加了新库,请重新运行该命令。
第四步:运行应用
CopyOTEL_SERVICE_NAME=<service-name> \
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443" \
OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>" \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true \
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_AND_EVENT \
OPENAI_API_KEY=<your-openai-key> \
opentelemetry-instrument <your_run_command>环境变量说明:
-
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED- 启用日志自动插桩 -
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT- 将提示词和补全结果捕获为日志 -
<region>:您的 SigNoz Cloud 区域 -
<your-ingestion-key>:您的 SigNoz 数据接入密钥 -
将
<service-name>替换为您的服务名称 -
将
<your-openai-key>替换为您的 OpenAI API key
使用自建 SigNoz?大部分步骤相同。如需适配此指南,请按照Cloud → 自建中的说明,更新 endpoint 并移除 ingestion key 头部。
ManualAuto(Java Agent)要求
- Java 8 或更高版本
- OpenAI Java SDK(
openai-java >= 1.1.0) - 有效的 OpenAI API key
- SigNoz 配置(二选一):
- 拥有有效数据接入密钥的 SigNoz Cloud 账户
- 自建 SigNoz 实例
配置
第一步:添加依赖
Gradle(build.gradle.kts)配置:
dependencies {
implementation("com.openai:openai-java:3.6.1")
implementation("io.github.cdimascio:dotenv-java:3.0.0")
implementation("io.opentelemetry:opentelemetry-api:1.54.1")
implementation("io.opentelemetry:opentelemetry-sdk:1.54.1")
implementation("io.opentelemetry:opentelemetry-sdk-trace:1.54.1")
implementation("io.opentelemetry:opentelemetry-sdk-metrics:1.54.1")
implementation("io.opentelemetry:opentelemetry-sdk-logs:1.54.1")
implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.54.1")
implementation("io.opentelemetry:opentelemetry-semconv:1.27.0-alpha")
implementation(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.20.1-alpha"))
implementation("io.opentelemetry.instrumentation:opentelemetry-openai-java-1.1")
}如果使用 Maven(pom.xml):
Copy<dependencies>
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-java</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-metrics</artifactId>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-logs</artifactId>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>1.27.0-alpha</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-openai-java-1.1</artifactId>
<version>2.20.1-alpha</version>
</dependency>
</dependencies>第 2 步:在 Java 应用中导入所需模块
OpenTelemetry:
Copyimport io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.openai.v1_1.OpenAITelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ServiceAttributes;Traces(链路追踪):
Copyimport io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;Logs(日志):
Copyimport io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;Metrics(指标):
Copyimport io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;第 3 步:配置 Traces
Copyimport io.github.cdimascio.dotenv.Dotenv;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ServiceAttributes;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
Dotenv dotenv = Dotenv.load();
String serviceName = "<service_name>";
Resource resource = Resource.getDefault()
.toBuilder()
.put(ServiceAttributes.SERVICE_NAME, serviceName)
.build();
OtlpHttpSpanExporter otlpSpanExporter = OtlpHttpSpanExporter.builder()
.setEndpoint(System.getenv("OTEL_EXPORTER_TRACES_ENDPOINT"))
.addHeader("signoz-ingestion-key", System.getenv("SIGNOZ_INGESTION_KEY"))
.build();
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setResource(resource)
.addSpanProcessor(BatchSpanProcessor.builder(otlpSpanExporter).build())
.build();<service_name>是你的服务名称OTEL_EXPORTER_TRACES_ENDPOINT→ 配置为带有对应区域的 SigNoz Cloud 端点:https://ingest.<region>.signoz.cloud:443/v1/tracesSIGNOZ_INGESTION_KEY→ 你的 SigNoz 数据接入密钥
使用自托管的 SigNoz?大部分步骤相同。要将本指南适配为自托管环境,请按照云到自托管中的说明更新端点,并移除数据接入密钥头。
第 4 步:配置日志
Copyimport io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
OtlpHttpLogRecordExporter otlpLogExporter = OtlpHttpLogRecordExporter.builder()
.setEndpoint(System.getenv("OTEL_EXPORTER_LOGS_ENDPOINT"))
.addHeader("signoz-ingestion-key", System.getenv("SIGNOZ_INGESTION_KEY"))
.build();
SdkLoggerProvider loggerProvider = SdkLoggerProvider.builder()
.setResource(resource)
.addLogRecordProcessor(BatchLogRecordProcessor.builder(otlpLogExporter).build())
.build();OTEL_EXPORTER_LOGS_ENDPOINT→ 配置为带有对应区域的 SigNoz Cloud 端点:https://ingest.<region>.signoz.cloud:443/v1/logsSIGNOZ_INGESTION_KEY
