Logging 日志记录
智能体开发套件(ADK)提供灵活且强大的日志记录功能,可有效监控智能体行为并进行调试。
日志记录理念¶
ADK 的日志记录方法是在默认情况下不过于冗长的前提下提供详细的诊断信息。它由应用程序开发者配置,让你能够根据特定需求(无论是在开发环境还是生产环境)定制日志输出。
- 标准库集成: ADK 使用宿主语言的标准日志记录工具(如 Python 的
logging模块、Go 的log包)。 - 结构化 GenAI 日志记录: ADK 使用 OpenTelemetry 记录 GenAI 请求和响应的结构化事件,支持在云环境中进行高级监控和调试。
- 用户配置: 虽然 ADK 提供了默认设置并与 CLI 工具集成,但最终配置日志以适合特定环境的责任在于应用程序开发者。
日志记录方案¶
ADK 使用标准库工具发出日志,并通过 OpenTelemetry 发出结构化 GenAI 事件。
结构化 GenAI 日志¶
通过 OpenTelemetry 发出的结构化 GenAI 日志遵循 GenAI 语义约定。
默认情况下,出于安全考虑,提示内容在日志中被省略。你可以使用环境变量或编程配置启用提示日志记录(请参阅下面的设置部分)。
日志级别(Python)¶
下表描述了在使用标准日志记录器时 Python 中不同级别记录的内容:
| 级别 | 描述 | 记录的信息类型 |
|---|---|---|
DEBUG |
对调试至关重要。 最详细的级别,用于细粒度的诊断信息。 |
|
INFO |
关于智能体生命周期的一般信息。 |
|
WARNING |
指示潜在问题或已弃用功能的使用。智能体继续运行,但可能需要关注。 |
|
ERROR |
阻止操作完成的严重错误。 |
|
Note
建议在生产环境中使用 INFO 或 WARNING。
仅在主动排查问题时启用 DEBUG,因为 DEBUG 日志可能非常冗长且包含敏感信息。
日志记录设置¶
在 ADK Web 中日志记录¶
使用 ADK 的 adk web、adk api_server、adk deploy cloud_run 和 adk deploy gke 命令运行智能体时,你可以控制日志的详细程度或目标位置。
日志级别¶
要以 DEBUG 级别日志启动 Web 服务器,请运行:
--log_level 选项可用的日志级别为:DEBUG、INFO(默认)、WARNING、ERROR、CRITICAL。
捕获提示内容¶
默认情况下,出于安全考虑,提示内容在日志中被省略。你可以使用环境变量启用提示日志记录:
Warning
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT 设置会记录用户提示和智能体响应的完整内容。这对于调试很有用,但可能会捕获敏感数据或 PII。在生产环境中,请将其设置为 false,或确保你有适当的数据处理策略。
OTLP 导出¶
要将日志导出到 OTLP 兼容的后端,请设置标准的 OTel 环境变量:
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="http://your-collector:4318/v1/logs"
adk web path/to/your/agents_dir
Note
如果你希望将指标和追踪也发送到同一端点,还可以设置通用的 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量。
GCP 导出设置¶
你可以使用 --otel_to_cloud 标志启用 GCP 导出:
Python 编程设置¶
在 Python 中,ADK 使用标准的 logging 模块和 OpenTelemetry 进行结构化 GenAI 日志记录。
日志级别¶
要启用详细日志记录(包括 DEBUG 级别消息),请将以下内容添加到脚本顶部:
import logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
捕获提示内容¶
你可以通过设置环境变量以编程方式启用完整的提示日志记录:
OTLP 导出¶
要以编程方式将日志导出到 OpenTelemetry Collector(或 OTLP 兼容的后端):
from google.adk.telemetry.setup import maybe_set_otel_providers
import os
os.environ["OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"] = "http://your-collector:4318/v1/logs"
os.environ["OTEL_SERVICE_NAME"] = "your-adk-agent"
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = "key1=value1,key2=value2"
maybe_set_otel_providers()
GCP 导出设置¶
要以编程方式将日志导出到 Google Cloud Logging,请使用 OpenTelemetry Google Cloud 导出器。以下是一个 Python 示例:
from google.adk.telemetry.google_cloud import get_gcp_exporters
from google.adk.telemetry.setup import maybe_set_otel_providers
import os
gcp_exporters = get_gcp_exporters(
enable_cloud_logging = True,
)
os.environ["OTEL_SERVICE_NAME"] = "your-adk-agent"
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = "key1=value1,key2=value2"
maybe_set_otel_providers([gcp_exporters])
Go 编程设置¶
在 Go 中,ADK 使用 google.golang.org/adk/telemetry 包进行 OpenTelemetry 配置,并使用标准的 log 包记录一般事件。
捕获提示内容¶
你可以在初始化遥测时以编程方式启用完整的提示日志记录:
package main
import (
"context"
"google.golang.org/adk/telemetry"
)
func main() {
ctx := context.Background()
tp, err := telemetry.New(ctx,
telemetry.WithGenAICaptureMessageContent(true),
)
if err != nil {
// 处理错误
}
defer tp.Shutdown(ctx)
tp.SetGlobalOtelProviders()
}
OTLP 导出¶
要导出日志到 OTLP 兼容的后端,请配置标准的 OpenTelemetry 环境变量(如 OTEL_EXPORTER_OTLP_ENDPOINT 或 OTEL_EXPORTER_OTLP_LOGS_ENDPOINT)。ADK 遥测包在初始化时会自动使用这些设置。
GCP 导出设置¶
要导出日志到 Google Cloud Logging,请使用 WithOtelToCloud 选项:
package main
import (
"context"
"google.golang.org/adk/telemetry"
)
func main() {
ctx := context.Background()
tp, err := telemetry.New(ctx,
telemetry.WithOtelToCloud(true),
)
if err != nil {
// 处理错误
}
defer tp.Shutdown(ctx)
tp.SetGlobalOtelProviders()
}
如果使用 Go 启动器,你也可以通过 CLI 标志启用 GCP 导出:
一般事件(如服务器启动或 HTTP 请求)使用标准 Go log 包记录。这些日志默认写入 stderr。
理解日志输出¶
Python 日志条目示例¶
| 日志段 | 格式说明符 | 含义 |
|---|---|---|
2025-07-08 11:22:33,456 |
%(asctime)s |
时间戳 |
DEBUG |
%(levelname)s |
严重级别 |
google_adk.models.google_llm |
%(name)s |
日志记录器名称(产生日志的模块) |
LLM Request: contents { ... } |
%(message)s |
实际日志消息 |
通过读取日志记录器名称,你可以立即定位日志来源并理解其在智能体架构中的上下文。
调试示例¶
启用 DEBUG 日志后(请参阅上面的日志级别),运行你的智能体并查找来自 google.adk.models.google_llm 日志记录器的消息。输出显示完整的 LLM 请求和响应:
2025-07-10 15:26:13,778 - DEBUG - google_adk.google.adk.models.google_llm -
LLM Request:
-----------------------------------------------------------
System Instruction:
You roll dice and answer questions about the outcome of the dice rolls.
...
-----------------------------------------------------------
Contents:
{"parts":[{"text":"Roll a 6 sided dice"}],"role":"user"}
{"parts":[{"function_call":{"args":{"sides":6},"name":"roll_die"}}],"role":"model"}
{"parts":[{"function_response":{"name":"roll_die","response":{"result":2}}}],"role":"user"}
-----------------------------------------------------------
Functions:
roll_die: {'sides': {'type': <Type.INTEGER: 'INTEGER'>}}
check_prime: {'nums': {'items': {'type': <Type.INTEGER: 'INTEGER'>}, 'type': <Type.ARRAY: 'ARRAY'>}}
-----------------------------------------------------------
2025-07-10 15:26:14,309 - INFO - google_adk.google.adk.models.google_llm -
LLM Response:
-----------------------------------------------------------
Text:
I have rolled a 6 sided die, and the result is 2.
...
从该输出中,你可以验证:
- 系统指令是否正确?
- 对话历史(
user和model轮次)是否准确? - 是否向模型提供了正确的工具?
- 工具是否被模型正确调用?
- 模型响应需要多长时间?