Skip to content

Commit 69b9f89

Browse files
docs: add ADK logging documentation (#502)
* docs: add ADK logging documentation * updated mkdocs.yml with the new guide --------- Co-authored-by: Lavi Nigam <[email protected]> Co-authored-by: Lavi Nigam <[email protected]>
1 parent ae18ef6 commit 69b9f89

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

docs/observability/logging.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Logging in the Agent Development Kit (ADK)
2+
3+
The Agent Development Kit (ADK) uses Python's standard `logging` module to provide flexible and powerful logging capabilities. Understanding how to configure and interpret these logs is crucial for monitoring agent behavior and debugging issues effectively.
4+
5+
## Logging Philosophy
6+
7+
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.
8+
9+
- **Standard Library:** It uses the standard `logging` library, so any configuration or handler that works with it will work with ADK.
10+
- **Hierarchical Loggers:** Loggers are named hierarchically based on the module path (e.g., `google_adk.google.adk.agents.llm_agent`), allowing for fine-grained control over which parts of the framework produce logs.
11+
- **User-Configured:** The framework does not configure logging itself. It is the responsibility of the developer using the framework to set up the desired logging configuration in their application's entry point.
12+
13+
## How to Configure Logging
14+
15+
You can configure logging in your main application script (e.g., `main.py`) before you initialize and run your agent. The simplest way is to use `logging.basicConfig`.
16+
17+
### Example Configuration
18+
19+
To enable detailed logging, including `DEBUG` level messages, add the following to the top of your script:
20+
21+
```python
22+
import logging
23+
24+
logging.basicConfig(
25+
level=logging.DEBUG,
26+
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
27+
)
28+
29+
# Your ADK agent code follows...
30+
# from google.adk.agents import LlmAgent
31+
# ...
32+
```
33+
34+
### Log Levels
35+
36+
ADK uses standard log levels to categorize the importance of a message:
37+
38+
- `DEBUG`: The most verbose level. Used for fine-grained diagnostic information, such as the full prompt sent to the LLM, detailed state changes, and internal logic flow. **Crucial for debugging.**
39+
- `INFO`: General information about the agent's lifecycle. This includes events like agent startup, session creation, and tool execution.
40+
- `WARNING`: Indicates a potential issue or the use of a deprecated feature. The agent can continue to function, but the issue may require attention.
41+
- `ERROR`: A serious error occurred that prevented the agent from performing an operation.
42+
43+
> **Note:** It is recommended to use `INFO` or `WARNING` in production environments and only enable `DEBUG` when actively troubleshooting an issue, as `DEBUG` logs can be very verbose and may contain sensitive information.
44+
45+
## What is Logged
46+
47+
Depending on the configured log level, you can expect to see the following information:
48+
49+
| Level | Type of Information Logged |
50+
| :-------- | :--------------------------------------------------------------------------------------------------------------------- |
51+
| **DEBUG** | - **Full LLM Prompts:** The complete request sent to the language model, including system instructions, history, and tools. |
52+
| | - Detailed API responses from services. |
53+
| | - Internal state transitions and variable values. |
54+
| **INFO** | - Agent initialization and startup. |
55+
| | - Session creation and deletion events. |
56+
| | - Execution of a tool, including the tool name and arguments. |
57+
| **WARNING**| - Use of deprecated methods or parameters. |
58+
| | - Non-critical errors that the system can recover from. |
59+
| **ERROR** | - Failed API calls to external services (e.g., LLM, Session Service). |
60+
| | - Unhandled exceptions during agent execution. |
61+
| | - Configuration errors. |
62+
63+
## Reading and Understanding the Logs
64+
65+
The `format` string in the `basicConfig` example determines the structure of each log message. Let's break down a sample log entry:
66+
67+
`2025-07-08 11:22:33,456 - DEBUG - google_adk.google.adk.models.google_llm - LLM Request: contents { ... }`
68+
69+
- `2025-07-08 11:22:33,456`: `%(asctime)s` - The timestamp of when the log was recorded.
70+
- `DEBUG`: `%(levelname)s` - The severity level of the message.
71+
- `google_adk.google.adk.models.google_llm`: `%(name)s` - The name of the logger. This hierarchical name tells you exactly which module in the ADK framework produced the log. In this case, it's the Google LLM model wrapper.
72+
- `Request to LLM: contents { ... }`: `%(message)s` - The actual log message.
73+
74+
By reading the logger name, you can immediately pinpoint the source of the log and understand its context within the agent's architecture.
75+
76+
## Debugging with Logs: A Practical Example
77+
78+
**Scenario:** Your agent is not producing the expected output, and you suspect the prompt being sent to the LLM is incorrect or missing information.
79+
80+
**Steps:**
81+
82+
1. **Enable DEBUG Logging:** In your `main.py`, set the logging level to `DEBUG` as shown in the configuration example.
83+
84+
```python
85+
logging.basicConfig(
86+
level=logging.DEBUG,
87+
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
88+
)
89+
```
90+
91+
2. **Run Your Agent:** Execute your agent's task as you normally would.
92+
93+
3. **Inspect the Logs:** Look through the console output for a message from the `google.adk.models.google_llm` logger that starts with `LLM Request:`.
94+
95+
```log
96+
...
97+
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
98+
2025-07-10 15:26:13,778 - DEBUG - google_adk.google.adk.models.google_llm -
99+
LLM Request:
100+
-----------------------------------------------------------
101+
System Instruction:
102+
103+
You roll dice and answer questions about the outcome of the dice rolls.
104+
You can roll dice of different sizes.
105+
You can use multiple tools in parallel by calling functions in parallel(in one request and in one round).
106+
It is ok to discuss previous dice roles, and comment on the dice rolls.
107+
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.
108+
You should never roll a die on your own.
109+
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.
110+
You should not check prime numbers before calling the tool.
111+
When you are asked to roll a die and check prime numbers, you should always make the following two function calls:
112+
1. You should first call the roll_die tool to get a roll. Wait for the function response before calling the check_prime tool.
113+
2. After you get the function response from roll_die tool, you should call the check_prime tool with the roll_die result.
114+
2.1 If user asks you to check primes based on previous rolls, make sure you include the previous rolls in the list.
115+
3. When you respond, you must include the roll_die result from step 1.
116+
You should always perform the previous 3 steps when asking for a roll and checking prime numbers.
117+
You should not rely on the previous history on prime results.
118+
119+
120+
You are an agent. Your internal name is "hello_world_agent".
121+
122+
The description about you is "hello world agent that can roll a dice of 8 sides and check prime numbers."
123+
-----------------------------------------------------------
124+
Contents:
125+
{"parts":[{"text":"Roll a 6 sided dice"}],"role":"user"}
126+
{"parts":[{"function_call":{"args":{"sides":6},"name":"roll_die"}}],"role":"model"}
127+
{"parts":[{"function_response":{"name":"roll_die","response":{"result":2}}}],"role":"user"}
128+
-----------------------------------------------------------
129+
Functions:
130+
roll_die: {'sides': {'type': <Type.INTEGER: 'INTEGER'>}}
131+
check_prime: {'nums': {'items': {'type': <Type.INTEGER: 'INTEGER'>}, 'type': <Type.ARRAY: 'ARRAY'>}}
132+
-----------------------------------------------------------
133+
134+
2025-07-10 15:26:13,779 - INFO - google_genai.models - AFC is enabled with max remote calls: 10.
135+
2025-07-10 15:26:14,309 - INFO - google_adk.google.adk.models.google_llm -
136+
LLM Response:
137+
-----------------------------------------------------------
138+
Text:
139+
I have rolled a 6 sided die, and the result is 2.
140+
...
141+
```
142+
143+
4. **Analyze the Prompt:** By examining the `System Instruction`, `contents`, `functions` sections of the logged request, you can verify:
144+
- Is the system instruction correct?
145+
- Is the conversation history (`user` and `model` turns) accurate?
146+
- Is the most recent user query included?
147+
- Are the correct tools being provided to the model?
148+
- Are the tools correctly called by the model?
149+
- How long it takes for the model to respond?
150+
151+
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.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ nav:
165165
- Observability:
166166
- Arize AX: observability/arize-ax.md
167167
- Phoenix: observability/phoenix.md
168+
- Logging: observability/logging.md
168169
- Evaluate:
169170
- evaluate/index.md
170171
- MCP:

0 commit comments

Comments
 (0)