Agent activity logging¶
Agent Development Kit (ADK) provides flexible and powerful logging capabilities to monitor agent behavior and debug issues effectively. Understanding how to configure and interpret these logs is crucial for monitoring agent behavior and debugging issues effectively.
Logging Philosophy¶
ADK's approach to logging is to provide detailed diagnostic information without being overly verbose by default. It is designed to be configured by the application developer, allowing you to tailor the log output to your specific needs, whether in a development or production environment.
- Standard Library Integration: ADK uses the standard logging facilities of the host language (e.g., Python's
loggingmodule, Go'slogpackage). - Structured GenAI Logging: ADK uses OpenTelemetry to log structured events for GenAI requests and responses, allowing for advanced monitoring and debugging in cloud environments.
- User-Configured: While ADK provides defaults and integration with its CLI tools, it is ultimately the responsibility of the application developer to configure logging to suit their specific environment.
Configuring Logging in Python¶
In Python, ADK uses the standard logging module.
Example Configuration¶
To enable detailed logging, including DEBUG level messages, add the following to the top of your script:
import logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
Configuring Logging with the ADK CLI (Python)¶
When running Python agents using the ADK's built-in web or API servers, you can easily control the log verbosity directly from the command line. The adk web, adk api_server, and adk deploy cloud_run commands all accept a --log_level option.
To start the web server with DEBUG level logging, run:
The available log levels for the --log_level option are:
DEBUGINFO(default)WARNINGERRORCRITICAL
Log Levels (Python)¶
| Level | Description | Type of Information Logged |
|---|---|---|
DEBUG |
Crucial for debugging. The most verbose level for fine-grained diagnostic information. |
|
INFO |
General information about the agent's lifecycle. |
|
WARNING |
Indicates a potential issue or deprecated feature use. The agent continues to function, but attention may be required. |
|
ERROR |
A serious error that prevented an operation from completing. |
|
Note: It is recommended to use INFO or WARNING in production environments. Only enable DEBUG when actively troubleshooting an issue, as DEBUG logs can be very verbose and may contain sensitive information.¶
Configuring Logging in Go¶
In Go, ADK uses the standard log package for general events and OpenTelemetry for GenAI activity logging.
OpenTelemetry Logging¶
ADK Go uses OpenTelemetry (OTel) to log GenAI requests and responses. By default, prompt content is elided in logs for security. You can enable prompt logging using environment variables or programmatic configuration.
Enabling Prompt Logging¶
Set the following environment variable to true to include full prompts in your OTel logs:
Programmatic Configuration¶
You can configure telemetry providers using the google.golang.org/adk/telemetry package.
import (
"context"
"google.golang.org/adk/telemetry"
)
func main() {
ctx := context.Background()
// Initialize telemetry with prompt content logging enabled
tp, err := telemetry.New(ctx,
telemetry.WithGenAICaptureMessageContent(true),
// Add other options like WithOtelToCloud(true) for GCP export
)
if err != nil {
// handle error
}
defer tp.Shutdown(ctx)
// Register as global OTel providers
tp.SetGlobalOtelProviders()
// Your ADK agent code follows...
}
General Logging¶
General events (like server startup or HTTP requests) are logged using the standard Go log package. These logs are written to stderr by default.
Configuring Logging with the ADK Go Launcher¶
When using the ADK Go full.Launcher or prod.Launcher, telemetry is automatically initialized. You can enable GCP export using the -otel_to_cloud flag:
Reading and Understanding the Logs¶
The structure of logs depends on your configuration. Structured GenAI logs emitted via OpenTelemetry follow the Semantic Conventions for GenAI.
Sample Python Log Entry¶
| Log Segment | Format Specifier | Meaning | | ------------------------------- | ---------------- | ---------------------------------------------- | |2025-07-08 11:22:33,456 | %(asctime)s | Timestamp |
| DEBUG | %(levelname)s | Severity level |
| google_adk.models.google_llm | %(name)s | Logger name (the module that produced the log) |
| LLM Request: contents { ... } | %(message)s | The actual log message |
By reading the logger name, you can immediately pinpoint the source of the log and understand its context within the agent's architecture.
Debugging with Logs: A Practical Example (Python)¶
Scenario: Your agent is not producing the expected output, and you suspect the prompt being sent to the LLM is incorrect.
Steps:
1. Enable DEBUG Logging: In your main.py, set the logging level to DEBUG as shown in the configuration example.
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
google.adk.models.google_llm logger that starts with LLM Request:.
...
2025-07-10 15:26:13,778 - DEBUG - google_adk.google.adk.models.google_llm - Sending out request, model: gemini-2.0-flash, backend: GoogleLLMVariant.GEMINI_API, stream: False
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.
You can roll dice of different sizes.
You can use multiple tools in parallel by calling functions in parallel(in one request and in one round).
It is ok to discuss previous dice roles, and comment on the dice rolls.
When you are asked to roll a die, you must call the roll_die tool with the number of sides. Be sure to pass in an integer. Do not pass in a string.
You should never roll a die on your own.
When checking prime numbers, call the check_prime tool with a list of integers. Be sure to pass in a list of integers. You should never pass in a string.
You should not check prime numbers before calling the tool.
When you are asked to roll a die and check prime numbers, you should always make the following two function calls:
1. You should first call the roll_die tool to get a roll. Wait for the function response before calling the check_prime tool.
2. After you get the function response from roll_die tool, you should call the check_prime tool with the roll_die result.
2.1 If user asks you to check primes based on previous rolls, make sure you include the previous rolls in the list.
3. When you respond, you must include the roll_die result from step 1.
You should always perform the previous 3 steps when asking for a roll and checking prime numbers.
You should not rely on the previous history on prime results.
You are an agent. Your internal name is "hello_world_agent".
The description about you is "hello world agent that can roll a dice of 8 sides and check prime numbers."
-----------------------------------------------------------
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:13,779 - INFO - google_genai.models - AFC is enabled with max remote calls: 10.
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.
...
System Instruction, contents, functions sections of the logged request, you can verify:
- Is the system instruction correct?
- Is the conversation history (user and model turns) accurate?
- Is the most recent user query included?
- Are the correct tools being provided to the model?
- Are the tools correctly called by the model?
- How long it takes for the model to respond?
This detailed output allows you to diagnose a wide range of issues, from incorrect prompt engineering to problems with tool definitions, directly from the log files.