DB-GPT 可观测性实践:日志、链路追踪与 OpenTelemetry/Jaeger 集成指南
【免费下载链接】DB-GPTopen-source agentic AI data assistant for the next generation of AI + Data products.项目地址: https://gitcode.com/GitHub_Trending/db/DB-GPT
**Observability(可观测性)**是衡量一个系统能否通过其外部输出推断出内部状态的能力。对于 DB-GPT 这类同时包含 Web 服务、模型 Worker、Embedding 服务与 Agent 编排的复杂 AI 数据应用来说,可观测性直接决定了故障排查、性能分析与日常监控的效率。本文基于 DB-GPT 官方文档《Observability》及其底层源码,系统讲解 DB-GPT 的两大可观测性机制——日志(Logging)与链路追踪(Tracing),并给出从本地 JSONL 存储、dbgpt trace命令行分析,到 OpenTelemetry 协议导出、Jaeger 可视化,乃至 Docker Compose 多服务集群全链路追踪的完整落地步骤。读完本文,你将能独立完成 DB-GPT 的日志与追踪配置,并在单机或集群环境下借助 Jaeger 洞察一次对话请求在 controller、LLM worker、embedding-worker 与 webserver 之间的完整调用链路。
一、可观测性在 DB-GPT 中的落地机制
在软件系统中,可观测性是通过检查系统输出来理解其内部状态的能力,对于调试(debugging)、监控(monitoring)和系统维护(maintaining)至关重要。DB-GPT 通过以下两大机制提供可观测性:
- 日志(Logging):DB-GPT 会记录各类事件与指标,帮助理解系统的内部状态;
- 追踪(Tracing):DB-GPT 内置追踪能力,帮助理解请求在系统中的流转过程。
从源码结构看,日志与追踪分别由dbgpt.util.utils与dbgpt.util.tracer两个模块承载,后者是 DB-GPT 可观测性的核心,包含base.py(Span 数据模型与 SpanType 定义)、tracer_impl.py(Tracer 实现与初始化)、span_storage.py(本地文件/内存存储)、opentelemetry.py(OTLP 导出)以及tracer_cli.py(trace 分析命令行),相关文件均位于 packages/dbgpt-core/src/dbgpt/util/tracer 目录下。
二、日志(Logging)配置:级别与存储位置
DB-GPT 允许你配置日志级别和存储位置。默认情况下,日志存储在 DB-GPT 根目录下的logs目录中。你可以通过设置DBGPT_LOG_LEVEL和DBGPT_LOG_DIR环境变量来更改日志级别与存储位置。
2.1 环境变量配置
# 日志级别:FATAL / ERROR / WARNING / INFO / DEBUG / NOTSET export DBGPT_LOG_LEVEL=DEBUG # 日志存储目录 export DBGPT_LOG_DIR=/path/to/your/logs2.2 源码级参数说明
从 packages/dbgpt-core/src/dbgpt/util/utils.py 的实现可以看到日志机制的核心细节:
_get_logging_level()读取DBGPT_LOG_LEVEL环境变量,默认值为INFO(见 utils.py#L28-L29);LoggingParameters定义了level与file两个配置项,其中level支持的合法取值为FATAL、ERROR、WARNING、INFO、DEBUG、NOTSET,并通过${env:DBGPT_LOG_LEVEL:-INFO}形式与系统参数配置系统打通(见 utils.py#L32-L54);_build_logger()在写入文件时使用logging.handlers.TimedRotatingFileHandler,按天(when="D")轮转日志文件,日志格式统一为%(asctime)s | %(levelname)s | %(name)s | %(message)s(见 utils.py#L132-L158)。
DBGPT_LOG_DIR用于指定日志根目录,实际日志文件名由各服务通过setup_logging(logger_name, ...)传入,最终通过resolve_root_path解析为绝对路径。设置DBGPT_LOG_LEVEL=DEBUG可以获得最详尽的调用信息,是排查问题时的首选级别。
三、链路追踪(Tracing)核心机制
DB-GPT 内置追踪能力,允许你追踪请求在系统中的流转。其核心设计在 tracer_impl.py 中:
- Span 数据模型:一次操作(如一次函数调用、一次模型请求)对应一个 Span,每个 Span 携带
trace_id、span_id、parent_span_id、operation_name、span_type和metadata等字段,通过parent_span_id形成父子层级,共同构成一条完整的调用链; - Span 类型(见 base.py#L23-L27):
BASE(基础操作)、RUN(服务启动运行)、CHAT(对话)、AGENT(Agent 行为); - Tracer 架构:
DefaultTracer负责 Span 的创建、结束与存储分发;TracerManager通过root_tracer全局单例提供start_span/end_span/get_current_span等无侵入接口,并确保"任何情况下都不抛异常、尽量不阻塞"; trace装饰器:开发人员只需在目标函数上添加@trace(operation_name="xxx")即可自动生成 Span,装饰器会自动提取函数参数作为metadata(默认排除self、cls,可额外指定exclude_params),并同时支持同步函数与异步函数(见 tracer_impl.py#L207-L262)。
initialize_tracer()(见 tracer_impl.py#L400-L453)负责在服务启动时装配整个追踪体系:注册DefaultTracer、SpanStorageContainer(可同时挂载多个存储后端)、FileSpanStorage,并根据TracerParameters判断是否需要额外挂载OpenTelemetrySpanStorage。
四、Trace 存储与本地分析
4.1 本地存储(Local Storage)
DB-GPT 默认将 traces 存储在 DB-GPT 日志目录下的traces目录中,实际文件位于logs/dbgpt*.jsonl(每行一条 JSON 格式的 Span 记录)。
从 span_storage.py 的实现可以看到本地存储的细节:
FileSpanStorage将每个 Span 序列化为 JSON 写入文件,并按日期自动滚动:跨天时会把当日文件重命名为文件名_YYYY-MM-DD.jsonl的格式(见 span_storage.py#L141-L153);SpanStorageContainer采用异步批量写入策略:Span 先进入内存队列,达到批量阈值(默认batch_size=10)或刷新间隔(默认flush_interval=10秒)后,由后台线程统一分发到各存储后端,且单条写入失败不会影响整体(见 span_storage.py#L28-L113)。
4.2 使用 dbgpt trace 命令行分析本地 Trace
dbgpt trace是 DB-GPT 内置的 trace 分析命令行工具(见 tracer_cli.py),默认读取logs目录下的dbgpt*.jsonl文件,提供三个子命令:
# 列出最近 20 条 Span,支持按 trace_id / span_id / span_type / parent_span_id 过滤, # 支持 --search 全文搜索、--start_time / --end_time 时间过滤、--desc 倒序, # 以及 --output text|html|csv|latex|json 输出格式 dbgpt trace list # 将指定 trace 的 Span 层级结构以树形展示 dbgpt trace tree --trace_id {your_trace_id} # 展示对话详情:服务运行参数、系统信息、用户输入、模型输出、错误信息等, # 支持 --tree 树形展示、--hide_conv 隐藏对话内容、--hide_run_params 隐藏运行参数 dbgpt trace chatdbgpt trace list还支持--json_path(JSONPath 提取,例如$.metadata.messages[0].content)、--value(仅显示提取值)等高级选项,便于从 trace 中精准抽取所需字段。
4.3 Debugging 文档
如果你希望更深入地了解本地 trace 存储的用法与分析手段,可继续阅读 调试指南。
五、OpenTelemetry 支持:导出分布式追踪
DB-GPT 同时支持 OpenTelemetry 分布式追踪。现在,你可以通过 OpenTelemetry Protocol(OTLP)将 traces 导出到 Jaeger、Zipkin 等兼容 OpenTelemetry 的后端。
5.1 安装依赖
要启用 OpenTelemetry 支持,需要先安装以下包:
pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp这些依赖与源码中OpenTelemetrySpanStorage的导入要求一致——若缺失,opentelemetry.py 会抛出明确的安装提示(见 opentelemetry.py#L5-L19)。
5.2 修改 .env 启用 OpenTelemetry 追踪
## 是否启用 DB-GPT 向 OpenTelemetry 发送 trace TRACER_TO_OPEN_TELEMETRY=True ## 更多细节参见 OTLP exporter 文档 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317在上述配置中,OTEL_EXPORTER_OTLP_TRACES_ENDPOINT可以改为你自己的 OTLP Collector 或后端地址,默认使用gRPC端点(端口 4317;若使用 HTTP 协议,则为 4318)。
5.3 底层导出实现
从源码看,TRACER_TO_OPEN_TELEMETRY=True会在TracerParameters.__post_init__中把 exporter 自动设置为telemetry(见 tracer_impl.py#L386-L389),随后initialize_tracer()会挂载OpenTelemetrySpanStorage(见 tracer_impl.py#L424-L434)。OpenTelemetrySpanStorage使用OTLPSpanExporter与BatchSpanProcessor将 Span 批量上报,并把 DB-GPT 的trace_id、span_id、parent_span_id、span_type以及可序列化的 metadata 写入 OTel Span 属性(dbgpt_trace_id、dbgpt_span_id、dbgpt_parent_span_id等),同时通过SpanContext重建父级上下文以保留调用层级(见 opentelemetry.py#L22-L119)。
此外,TracerParameters还支持以下环境变量以微调 OTLP 连接行为(见 tracer_impl.py#L351-L378):
| 配置项 | 对应环境变量 | 说明 |
|---|---|---|
otlp_endpoint | OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | OTLP 上报端点 |
otlp_insecure | OTEL_EXPORTER_OTLP_TRACES_INSECURE | 是否使用非安全连接 |
otlp_timeout | OTEL_EXPORTER_OTLP_TRACES_TIMEOUT | 连接超时时间(秒) |
六、Jaeger 支持:Docker 单机示例
下面以 Jaeger 为例,展示如何使用 OpenTelemetry 对 DB-GPT 进行链路追踪。
6.1 启动 Jaeger all-in-one 镜像
docker run --rm --name jaeger \ -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ -p 6831:6831/udp \ -p 6832:6832/udp \ -p 5778:5778 \ -p 16686:16686 \ -p 4317:4317 \ -p 4318:4318 \ -p 14250:14250 \ -p 14268:14268 \ -p 14269:14269 \ -p 9411:9411 \ jaegertracing/all-in-one:1.58各端口用途:
| 端口 | 协议 | 用途 |
|---|---|---|
16686 | TCP | Jaeger UI 前端 |
4317 | gRPC | 接收 OpenTelemetry Protocol(OTLP)gRPC 数据 |
4318 | HTTP | 接收 OpenTelemetry Protocol(OTLP)HTTP 数据 |
6831 | UDP | 接收 jaeger.thrift 紧凑协议(多数 SDK 使用) |
6832 | UDP | 接收 jaeger.thrift 二进制协议 |
14268 | HTTP | 接收 jaeger.thrift 直连上报 |
14250 | gRPC | 接收 model.proto 格式数据 |
9411 | HTTP | 兼容 Zipkin 上报 |
5778、14269 | HTTP | 配置与管理接口 |
6.2 配置 .env 并启动 DB-GPT
与前面一致,修改.env文件启用 OpenTelemetry 追踪:
TRACER_TO_OPEN_TELEMETRY=True OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317启动 DB-GPT 服务:
dbgpt start webserver现在即可访问 Jaeger UIhttp://localhost:16686查看 traces。
6.3 Jaeger UI 界面示例
以下为 Jaeger UI 的实际界面截图,帮助你快速定位需要关注的功能区域:
Search Traces 页面——在该页面可以选择服务名、时间范围并搜索 trace:
普通对话 Trace——一次常规对话请求的完整调用链视图:
RAG 对话跨服务 Trace——在集群模式下,可以看到 DB-GPT controller、LLM worker 与 webserver 之间的跨服务通信:
七、Jaeger + Docker Compose:集群可观测性方案
如果你希望用 docker-compose 一次性启动 DB-GPT 集群与 Jaeger,可以使用下面的docker-compose.yml:
# An example of using docker-compose to start a cluster with observability enabled. version: '3.10' services: jaeger: image: jaegertracing/all-in-one:1.58 restart: unless-stopped networks: - dbgptnet ports: # serve frontend - "16686:16686" # accept jaeger.thrift over Thrift-compact protocol (used by most SDKs) - "6831:6831" # accept OpenTelemetry Protocol (OTLP) over HTTP - "4318:4318" # accept OpenTelemetry Protocol (OTLP) over gRPC - "4317:4317" - "14268:14268" environment: - LOG_LEVEL=debug - SPAN_STORAGE_TYPE=badger - BADGER_EPHEMERAL=false - BADGER_DIRECTORY_VALUE=/badger/data - BADGER_DIRECTORY_KEY=/badger/key volumes: - jaeger-badger:/badger user: root controller: image: eosphorosai/dbgpt:latest command: dbgpt start controller restart: unless-stopped environment: - TRACER_TO_OPEN_TELEMETRY=True - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://jaeger:4317 - DBGPT_LOG_LEVEL=DEBUG networks: - dbgptnet llm-worker: image: eosphorosai/dbgpt:latest command: dbgpt start worker --model_type proxy --model_name chatgpt_proxyllm --model_path chatgpt_proxyllm --proxy_server_url ${OPENAI_API_BASE}/chat/completions --proxy_api_key ${OPENAI_API_KEY} --controller_addr http://controller:8000 environment: # Your real openai model name, e.g. gpt-3.5-turbo, gpt-4o - PROXYLLM_BACKEND=gpt-3.5-turbo - TRACER_TO_OPEN_TELEMETRY=True - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://jaeger:4317 - DBGPT_LOG_LEVEL=DEBUG depends_on: - controller restart: unless-stopped networks: - dbgptnet ipc: host embedding-worker: image: eosphorosai/dbgpt:latest command: dbgpt start worker --worker_type text2vec --model_name proxy_http_openapi --model_path proxy_http_openapi --proxy_server_url ${OPENAI_API_BASE}/embeddings --proxy_api_key ${OPENAI_API_KEY} --controller_addr http://controller:8000 environment: - proxy_http_openapi_proxy_backend=text-embedding-3-small - TRACER_TO_OPEN_TELEMETRY=True - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://jaeger:4317 - DBGPT_LOG_LEVEL=DEBUG depends_on: - controller restart: unless-stopped networks: - dbgptnet ipc: host webserver: image: eosphorosai/dbgpt:latest command: dbgpt start webserver --light --remote_embedding --controller_addr http://controller:8000 environment: - LLM_MODEL=chatgpt_proxyllm - EMBEDDING_MODEL=proxy_http_openapi - TRACER_TO_OPEN_TELEMETRY=True - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://jaeger:4317 depends_on: - controller - llm-worker - embedding-worker volumes: - dbgpt-data:/app/pilot/data - dbgpt-message:/app/pilot/message ports: - 5670:5670/tcp restart: unless-stopped networks: - dbgptnet volumes: dbgpt-data: dbgpt-message: jaeger-badger: networks: dbgptnet: driver: bridge name: dbgptnet7.1 启动集群
OPENAI_API_KEY="{your api key}" OPENAI_API_BASE="https://api.openai.com/v1" docker compose up -d请将{your api key}替换为真实的 OpenAI API Key,将https://api.openai.com/v1替换为真实的 OpenAI API Base URL。
7.2 方案要点解读
- Jaeger 持久化:示例使用 Badger 作为 Jaeger 的存储引擎(
SPAN_STORAGE_TYPE=badger),并通过jaeger-badger卷持久化/badger目录,避免容器重启后 trace 丢失; - 逐服务开启追踪:controller、llm-worker、embedding-worker、webserver 四个服务都设置了
TRACER_TO_OPEN_TELEMETRY=True,且上报端点统一指向http://jaeger:4317(容器网络内直接使用服务名jaeger,无需经过宿主机端口映射); - 全链路打通:所有服务都加入同一个 bridge 网络
dbgptnet,并依赖 controller 先启动,从而保证 webserver 可以同时发现 LLM worker 与 embedding worker,使一次对话请求的 trace 能跨越 controller、worker 与 webserver 三个进程完整串联。
集群启动后,访问http://localhost:16686即可在 Jaeger UI 中查看 traces。在上面的 RAG 对话截图中,你可以看到 DB-GPT controller、LLM worker 与 webserver 之间跨服务通信的完整链路。
仓库中提供了与此示例等价的可直接运行文件,详见 docker/compose_examples/observability/docker-compose.yml(该文件默认使用eosphorosai/dbgpt-openai:latest镜像,构建方式参见 docker/base/build_proxy_image.sh 中的注释说明),同时可结合 HA 集群配置示例 理解生产化部署的扩展方向。
八、最佳实践小结
- 先本地、后远程:排查问题时应优先使用本地
logs/dbgpt*.jsonl文件配合dbgpt trace list / tree / chat命令快速定位;确认问题方向后再开启 OpenTelemetry 导出,避免无谓的链路开销; - 按需开启追踪:
TRACER_TO_OPEN_TELEMETRY=True对所有服务(webserver、controller、worker、embedding worker)都要一致配置,否则跨服务调用链会断裂; - 利用日志级别:集群排障时建议将
DBGPT_LOG_LEVEL提升到DEBUG,与 Jaeger 中的 Span 时间线相互印证; - 善用 metadata 属性:Jaeger 中每个 Span 都会携带
dbgpt_trace_id、dbgpt_span_id、dbgpt_parent_span_id、span_type等属性,以及函数级参数 metadata,可按这些字段在 Jaeger UI 中进行标签搜索,快速定位慢请求与异常 Span。
【免费下载链接】DB-GPTopen-source agentic AI data assistant for the next generation of AI + Data products.项目地址: https://gitcode.com/GitHub_Trending/db/DB-GPT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考