Datadog 集成
CrewAI 原生支持 Datadog:提供两条日志摄取路径、专为低成本索引设计的 JSON 日志 schema,以及一个你可以在五分钟内导入的现成运维仪表板。
CrewAI 支持两种将日志发送到 Datadog 的方式 - 两者都是一等公民,并会生成相同的结构化字段,为仪表板提供数据。请选择最适合你基础设施的一种。
Datadog Agent 与你的 CrewAI 容器并行运行(在 Kubernetes 中通常作为 DaemonSet),并抓取它们的 stdout。设置 CREWAI_LOG_FORMAT=json 后,每条日志事件都会作为一条带结构化属性的可计费日志行发送。
设置:
- 在你的 CrewAI 容器旁边运行 Datadog Agent - 关于 Kubernetes、ECS 或 VM 的设置,请参阅 Datadog 的部署文档。启用日志收集(
logs_enabled: true)和容器日志收集(logs_config.container_collect_all: true)。 - 在 CrewAI AMP 中将
CREWAI_LOG_FORMAT=json设为自动化环境变量(打开你的 automation → Settings → Environment Variables),这样每条日志事件都会变成单行,而不是多行 traceback。AMP 会将该值传播到部署中的所有容器(API + workers)- 不要直接在容器或主机上设置。有关 AMP UI 流程,请参阅下面的 启用 JSON 输出,以及完整字段契约的 日志 schema 参考。 - 确认日志在 Datadog Logs 中以解析后的 JSON 字段到达 - 请参阅 验证摄取。
当你符合以下情况时选择此路径: 你已经在使用 Datadog Agent(例如用于基础设施指标),或者你的日志量大到按事件计费的成本需要认真考虑 - 将 traceback 折叠为单个事件可让 Agent 摄取成本在规模上保持较低。
CrewAI AMP 会将 OpenTelemetry 流量直接导出到 Datadog 的 OTLP 终端节点,无需 Agent。日志和 traces 走同一条在 AMP UI 中配置的导出管道,使用的协议与你对任何其他 OTLP 后端使用的协议相同。
设置:
- 在 CrewAI AMP 中,前往 Settings → OpenTelemetry Collectors → Add Collector,并选择 Datadog。
- 配置连接:
- Datadog Site Domain - 只填写你 Datadog 站点的 OTLP 主机,不要包含协议或路径。CrewAI 会为你构建完整的 HTTPS OTLP 终端节点。使用与你的 Datadog site 匹配的主机:
otlp.datadoghq.com(US1)otlp.us3.datadoghq.com(US3)otlp.us5.datadoghq.com(US5)otlp.datadoghq.eu(EU1)otlp.ap1.datadoghq.com(AP1)
- API Key - 你的 Datadog API key。参见 如何创建。
- Datadog Site Domain - 只填写你 Datadog 站点的 OTLP 主机,不要包含协议或路径。CrewAI 会为你构建完整的 HTTPS OTLP 终端节点。使用与你的 Datadog site 匹配的主机:
- Datadog 模板会一次性配置两种信号 - 保存后,AMP 会创建一个指向
/v1/traces的 traces 收集器,以及一个指向/v1/logs的 logs 收集器,两者共享相同的 Datadog OTLP 主机和 API key。你会在 OTel collectors 列表中看到两行独立记录。 - (可选) 点击 Test Connection,验证 CrewAI 是否能使用你提供的凭据访问该终端节点。然后点击 Save - 两个收集器会一次创建完成。
当你符合以下情况时选择此路径: 你不想运维 Datadog Agent,或者你已经使用 OTLP 处理 traces 并希望只有一条导出管道,或者你未来可能希望将同一遥测分发到其他后端(Grafana、Honeycomb 等)而无需更改应用配置。
无论选择哪条路径,进入 Datadog 的结构化字段都是相同的(@automation_id、@kickoff_id、@execution_id、@automation_name、@crewai_version、@exception.type、@gen_ai.*),因此仪表板在两种选择下都能正常工作。
日志 schema 参考
Section titled “日志 schema 参考”当设置了 CREWAI_LOG_FORMAT=json 时,每条日志事件都会作为 stdout 上的单个 JSON 对象逐行输出,内部换行符会被转义。该格式是纯 JSON - Datadog 可以原生解析,同一 payload 也可被 Splunk、Loki、Elasticsearch 和 CloudWatch 无需自定义日志管道地消费。
为什么使用 JSON 输出
Section titled “为什么使用 JSON 输出”更低的摄取成本
大多数托管日志后端按事件计费。文本格式下的 Python traceback 会被算作多行日志 - 一个错误可能对应 30 多条事件。JSON 输出会将每个 traceback 折叠为单个事件,并将堆栈作为转义字符串字段保存。
结构化搜索
可以按 @automation_id、@exception.type、@kickoff_id 搜索,而不是在自由文本里 grep。无需配置解析器,就能基于类型化字段构建仪表板。
APM ↔ 日志关联
每条事件在录制 span 内触发时都会携带 trace_id 和 span_id,因此后端会自动把日志链接到 traces。
稳定契约
schema 字段用于控制兼容性 - 在 v1 内,只会新增字段,不会重命名或删除字段。
启用 JSON 输出
Section titled “启用 JSON 输出”CREWAI_LOG_FORMAT=json 必须作为 CrewAI AMP 中的自动化环境变量设置 - 它不是容器、主机或 Docker 设置。打开 AMP 中的 automation,点击 Settings 图标,并在 Environment Variables 部分添加该变量。AMP 会在下次重启时将该值应用到部署中的所有容器(API + workers)。关于完整 UI 流程,请参阅 Update Your Crew。
CREWAI_LOG_FORMAT=json重启部署以使更改生效。从那一刻起,stdout 上的每一行日志都将是一个 JSON 对象。
活动 automation kickoff 中的一条 info 级日志:
{ "schema": "v1", "ts": "2026-06-17T16:14:23.482914Z", "level": "INFO", "logger": "crewai_enterprise.utilities.pii_redaction", "crewai_version": "1.14.7", "msg": "PII tracking state reset (engines preserved)", "automation_id": "12", "task_id": "0843a930-b306-464b-89c8-bfafa78cc711", "kickoff_id": "0843a930-b306-464b-89c8-bfafa78cc711", "execution_id": "0843a930-b306-464b-89c8-bfafa78cc711", "automation_name": "research_flow"}一个带 Python exception 的错误会被折叠为单条事件,traceback 作为字符串保存:
{ "schema": "v1", "ts": "2026-06-17T16:14:31.218450Z", "level": "ERROR", "logger": "api.tasks.flow_run_task", "crewai_version": "1.14.7", "msg": "Flow execution failed", "automation_id": "12", "kickoff_id": "0843a930-b306-464b-89c8-bfafa78cc711", "execution_id": "0843a930-b306-464b-89c8-bfafa78cc711", "automation_name": "research_flow", "exception": { "type": "ValueError", "message": "Topic cannot be empty", "stacktrace": "Traceback (most recent call last):\n File \"/app/flow.py\", line 42, in summarize\n ...\nValueError: Topic cannot be empty\n" }}旧版文本模式下的同一个错误会产生大约 25 条独立日志事件(traceback 每行一条)- 后端会分别计费和索引这些事件。
Schema v1 字段
Section titled “Schema v1 字段”在 v1 schema 中,字段只会新增,不会重命名或删除。升级部署后,新字段会立即出现。
| 字段 | 类型 | 始终存在 | 来源 |
|---|---|---|---|
schema | string | 是 | 常量 "v1"。增量表示存在破坏性 schema 更改。 |
ts | string(ISO-8601 UTC,微秒) | 是 | 记录创建时间,例如 2026-06-17T16:14:23.482914Z。 |
level | string | 是 | Python 日志级别名称:DEBUG / INFO / WARNING / ERROR / CRITICAL。 |
logger | string | 是 | 点分 logger 名称,例如 api.tasks.flow_run_task。 |
crewai_version | string | 是(当 crewai 包元数据可解析时) | 已安装 crewai 包版本,例如 "1.14.7"。 |
msg | string | 是 | 渲染后的日志消息(在 % 格式化 / {} 格式化之后)。 |
automation_id | string | 当设置了 CREWAI_PLUS_ID 环境变量时 | 数字型部署 ID(AMP 会在每个容器中注入)。 |
task_id | string | 在 Celery worker 日志中 | Celery task UUID,或非任务上下文下的 "no-task"。 |
kickoff_id | string | 在 automation kickoff 内部 | 当前 kickoff 的 UUID。 |
execution_id | string | 在 automation kickoff 内部 | 当前子执行的 UUID。顶层时等于 kickoff_id;当嵌套 flow 方法生成子执行时则不同。 |
automation_name | string | 在 automation kickoff 内部 | 人类可读的 automation/flow 名称,例如 "research_flow"。 |
trace_id | string(32 位十六进制) | 在录制中的 OpenTelemetry span 内部 | 十六进制 trace ID。若没有活动 span,则省略。 |
span_id | string(16 位十六进制) | 在录制中的 OpenTelemetry span 内部 | 十六进制 span ID。若没有活动 span,则省略。 |
exception | object | 当日志记录包含 exc_info 时 | {type, message, stacktrace} - 完整 traceback 作为单个转义字符串。 |
schema 字段定义了契约。在 v1 中,CrewAI 承诺:
- 永不删除客户可能已经用来构建查询或仪表板的字段。
- 永不就地重命名字段 - 重命名会通过 schema 升级完成(例如
v2),旧名称会作为弃用别名至少保留一个发布周期。 - 随时新增字段。消费者应忽略未知的顶层键。
当引入 v2 时,schema 字段和迁移指南都会提前发布,而 v1 会继续输出一个发布周期,以便仪表板和查询有时间迁移。
前提:提升字段为 facet
Section titled “前提:提升字段为 facet”Datadog 会在首次看到字段时自动发现它们,但在你将它们提升为 facets 之前,不能在 widget 中对它们进行查询。这是你 Datadog 账号中的一次性设置。
- 搜索 CrewAI 日志
打开 Logs Explorer 并搜索
service:crewai*。你应该至少能看到一条日志事件。 - 提升每个字段
点击任意日志条目以打开右侧详情面板。对下面每个字段,悬停字段名 → 点击齿轮图标 → Create facet。
automation_id、automation_name、execution_id、kickoff_id、task_idcrewai_version、model_idexception.type、exception.message
跳过任何字段名旁边已经显示星标图标的字段 - 这表示它已经是 facet。
gen_ai.usage.input_tokens、gen_ai.usage.output_tokens和gen_ai.request.model这些 facet 通常会被 Datadog 的 LLM Observability 自动发现自动提升,但在导入仪表板前请确认它们确实存在。
- 下载仪表板 JSON
将
datadog_dashboard.json保存到你的本机。 - 打开 Datadog 的导入对话框
导航到 Dashboards → New Dashboard。在空白仪表板右上角点击 gear icon,然后选择 Import Dashboard JSON。
- 粘贴或上传 JSON
将
datadog_dashboard.json的内容粘贴到导入对话框中(或直接拖入文件)。点击 Import。Datadog 会立即创建仪表板并跳转到该页面。首次加载时,widget 可能会在几秒钟内为空,因为查询正在基于当前时间范围执行。
你会得到什么
Section titled “你会得到什么”该仪表板分为四个部分,并额外留有一个自定义下钻 widget 的占位:
| 部分 | Widget | 适用场景 |
|---|---|---|
| Header | Total Executions · Error Rate (%) · Active Automations · CrewAI Versions in Use | 用于查看过去一小时的整体健康状况。Error Rate 带有条件格式(绿色 ≤ 5%,黄色 ≤ 10%,红色 > 10%)。 |
| Throughput | Executions per Hour by Automation(前 10,堆叠柱状图) | 观察流量变化、发现忙碌的自动化、验证 rollout 是否改变了基线流量。 |
| Errors | Errors by Exception Type(前 5,堆叠柱状图) · Top Exception Types by Count(toplist) | 用于排查故障 - 哪些异常类型在激增,影响了哪些自动化。 |
| Cost | Total Tokens per Hour by Model(input + output,堆叠面积图) | 跟踪按模型划分的 LLM token 消耗。对于捕捉自动化切换模型或开始循环时的成本回退非常有用。 |
| Drill-Down | (空占位) | 参见 自定义,了解如何在此添加近期错误日志流。 |
仪表板顶部的三个模板变量会一次性重新作用于所有 widget:
$automation- 过滤到单个 automation 名称。$version- 过滤到单个crewaiSDK 版本(便于比较升级前后的行为)。$service- 过滤到特定 Datadogservice标签(适合多个 CrewAI 部署共享一个 Datadog 账号的情况)。
打开 Logs Explorer,并运行与你的摄取路径匹配的查询:
搜索 service:crewai* @schema:v1。你应该能看到结构化日志,JSON 字段已解析为 Datadog facets。选择一条最近的事件,确认其包含 @automation_id、@kickoff_id、@execution_id、@crewai_version,以及(在 span 内运行时)@trace_id / @span_id。
如果没有任何内容,确认在 AMP 中你的 automation 的 Environment Variables 下已设置 CREWAI_LOG_FORMAT=json,更改后已重启部署,并且 Datadog Agent 正在抓取容器 stdout。
搜索 source:otlp service:crewai*。OTLP 属性会以 OpenTelemetry 名称进入(例如 automation_id、crewai.kickoff.id 等),而不是 stdout JSON 键,但在 facet 提升 后,它们会映射到相同的仪表板字段。
如果没有任何内容,请确认 collector 终端节点正确(日志使用 /v1/logs,traces 使用 /v1/traces),并且保存 collector 时 Test Connection 已成功。
该仪表板预留了有意留白的区域,因此你可以在不卸载和重新导入的情况下扩展它。
添加 Recent Errors 日志流
Section titled “添加 Recent Errors 日志流”Drill-Down 部分是故意留空的。你可以在其中添加一个 Log Stream widget,用于内联查看最近的故障:
- 编辑仪表板,并在 Drill-Down 组内点击 + Add Widgets。
- 拖入一个 Log Stream widget。
- 将过滤查询设为
status:error $automation $version $service。 - 选择列:
@timestamp、@automation_name、@exception.type、@exception.message、@execution_id。 - 按最近时间排序,限制为 25 条记录。