Files
Kristopher Overholt 50f7df7f46 Add Kotlin language support to ADK docs (#1768)
* Add Kotlin to hero / front page

* Add quickstart page for Kotlin

* Complete Kotlin quickstart guide and fix hero code sample (#2)

* Replace GitHub repo links with language icons in header (#3)

* Fix header icon FOUC and homepage font weight regression (#4)

* Testing staging pipeline

* Revert test edit (for staging pipeline)

* Update language icon tooltips to indicate GitHub destination (#5)

* Add link to ADK Kotlin release notes (#7)

* Initial commit of ADK Kotlin API reference docs (#6)

* Add script to generate ADK Kotlin API reference docs (#8)

* Update links and link checker ignore list (temporarily) (#9)

* Add ADK Kotlin for Android getting started guide to Advanced setup page (#10)

* Add advanced setup page with steps to "Use ADK Kotlin in Android projects"

* Update temp link checker rules

* Add placeholder folder for adk-samples (#13)

* adding linter/compilation checks for kotlin snippets (#12)

* adding linter/compilation checks for kotlin snippets

* Add Kotlin validation scripts

* Initial commit of Kotlin sample agents for adk-samples (#15)

* Adding kotlin snippet for llm agents (#16)

* Adding kotlin snippets to  Events (#17)

* Pull changes to docs/events/index.md from glaforge-kotlin-snippets

* fixing kotlin event timestamp and longRunningToolIds

* Fix language tags (#19)

* Fix language tags

* Update

* Fix wrapping

* Fix wrapping (again)

* Fix wrapping/format

* Fix language tag on integration page

* Enable check_paths in PyMdown Snippets Extension to make the build fail if a snippet can't be found (#20)

* Update mkdocs config (#21)

* Fix broken links, update URLs to adk.dev, and improve (temp) lychee config (#22)

* Add Kotlin/maven badge to README (#23)

* Adding Kotlin snippets for artifacts  (#18)

* Pull Kotlin snippets for artifacts from glaforge-kotlin-snippets

* Add comprehensive Kotlin snippets for artifacts

* Refactor artifacts documentation to use external Kotlin snippets

* Update Kotlin model to gemini-flash-latest

* Fix GCS initialization in Kotlin artifact snippet

* afixi failing test with capital-agent added to files_to_check

* Fix snippet label syntax for MkDocs build

* Configure proper Gradle project for Kotlin snippets and fix dependencies

* Add KSP support and generated sources to Kotlin snippets build

* fixing capital_agent turnComplete

* Fix syntax error in build.gradle.kts by removing invalid placeholders (#25)

* Adding Kotlin snippets to google-gemini.md (#27)

Pulling kotlin changes to google-gemini.md from glaforge-kotlin-snippets

* Add a warning about not adding an api key to production code. (#28)

* Add a warning about not adding an api key to production code.

* Update note

---------

Co-authored-by: Kristopher Overholt <koverholt@google.com>

* Add ADK Demo App sample showcasing Gemini-powered agents (#29)

This sample demonstrates how to use the Google ADK (Agent Development Kit) in an Android application to create a chat interface powered by a Gemini-based "Fun Facts" agent. The implementation features:
*   Integration with the Kotlin ADK core and processor libraries.
*   A `FunFactsAgent` defined using `LlmAgent` and the Gemini model.
*   A `ChatViewModel` utilizing `InMemoryRunner` for asynchronous message streaming.
*   A modern UI built with Jetpack Compose and Material 3.
*   Build configuration logic for secure API key management via environment variables or `local.properties`.

* Update Kotlin docs and samples to align with adk-kotlin API changes (#30)

Rename GeminiModel to Gemini, @AdkTool/@AdkParam to @Tool/@Param,
adkTools() to generatedTools(), replace DebugRunner with InMemoryRunner,
fix AgentLoader import path, use SingleAgentLoader, bump Kotlin to
2.3.21 and KSP to 2.3.7, and update Android minSdk from 24 to 26.

* adding kotlin info to READMEs (#14)

* Reorganize Android sample agent and add READMEs (#31)

* Move Android sample agent

* Update repo README, add Android README, update sample agent README

* Minor edit to language support tags (#32)

* Remove blog post link (#33)

Will re-add after it's published

* Remove examples link (#34)

* Adding Kotlin snippets for Sessions docs (#26)

* initial kotlins snippets additions to sessions docs

* Updating memory docs with kotlin snippets

* Adding kotlin snippets to session state docs.

* update model to gemini-flash-latest

* sessions examples clean-up

* fixing sessions snippet markers

* adding kotlin session snippets to files to test

* adding callback to memory_example

* Fixing capital agent snippet  (#35)

Fixing file name
Updating adkTool > Tool
Updating GeminiModel > Gemini

* Adding kotlin snippets for tools docs (#36)

* adding function tool kotlin snippets

* adding function_tools snippets to files to test

* Adding kotlin snippets to observability docs (#37)

* initial kotlin observability updates

* adding observability snippets to file check (#38)

* Adding Kotlin snippets to Callbacks docs (#39)

*  kotlin callbacks snippets

* adding callbacks snippets to file check

* Align Kotlin and KSP versions with published 0.1.0 artifacts (#40)

* switch CLI entry points from InMemoryRunner to ReplRunner (#41)

* Switch CLI entry points from InMemoryRunner to ReplRunner

* Fix wording

* Update API reference docs for Kotlin, 2026-05-18 (#42)

* Remove ADK on Android note until published (#43)

* Update Kotlin code samples (#44)

* Rename GeminiModel to Gemini in Kotlin snippets and docs

* Remove broken SessionKey call and use sessionId directly in AgentTool snippet

* Rewrite Go hero snippet to use llmagent API

* Use isFinalResponse with safe access in CapitalAgent snippet

* Use Role.USER constant instead of raw string in SetupExample

* Use full semver v0.1.0 in Kotlin language support tags

* Remove Android setup steps, moving to new property (#45)

* Tutorial Kotlin agent (#46)

* Adding multi-tool-agent snippet and updating tutorial
* Fixing Go language order on tutorial page
* adding multi tool agent example to files to test

* Inline Kotlin get-started code sample

* Kotlin Multi agents snippets (#47)

* Multi-agent kotlin snippets

* Fixing docs tags in multiagent example

* Fix Kotlin language support tags, code samples, and google-gemini.md cleanup (#48)

* Add Kotlin v0.1.0 to language support tags across docs

* Fix MultiToolAgent.kt model string and argument style

* Update MultiAgentExample.kt to use gemini-flash-latest model string

* Fix google-gemini.md: add Kotlin sample, remove unsupported Java tabs

* Remove explicit apiKey from CallbackBasic.kt for consistency

* Standardize Gemini() constructor to use named args in all snippets

* Remove adk-samples directory (moved to google/adk-samples#1969)

* Remove adk-samples directory (moved to google/adk-samples#1969) (#49)

* Update API reference docs for ADK Kotlin 0.1.0 (#50)

* Remove adk-samples directory (moved to google/adk-samples#1969)

* Update API reference docs for ADK Kotlin 0.1.0

* Remove kotlin lycheeignore config (#51)

* Remove adk-samples directory (moved to google/adk-samples#1969)

* Remove Kotlin .lycheeignore config links

---------

Co-authored-by: Toni Klopfenstein <2359976+ToniCorinne@users.noreply.github.com>
Co-authored-by: Jolanda Verhoef <JolandaVerhoef@users.noreply.github.com>
2026-05-19 11:43:42 -05:00

11 KiB

Agent activity logging

Supported in ADKPython v0.1.0Go v0.1.0Kotlin v0.1.0

Agent Development Kit (ADK) provides flexible and powerful logging capabilities to monitor agent behavior and debug 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 logging module, Go's log package).
  • 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.

Logging schema

ADK emits logs using standard library facilities and structured GenAI events via OpenTelemetry.

Structured GenAI logs

Structured GenAI logs emitted via OpenTelemetry follow the Semantic Conventions for GenAI.

By default prompt content is elided in logs for security. You can enable prompt logging using environment variables or programmatic configuration (see Setup section below).

Log levels (Python)

The following table describes what is logged at different levels in Python when using the standard logger:

Level Description Type of Information Logged
DEBUG Crucial for debugging. The most verbose level for fine-grained diagnostic information.
  • Full LLM Prompts: The complete request sent to the language model, including system instructions, history, and tools.
  • Detailed API responses from services.
  • Internal state transitions and variable values.
INFO General information about the agent's lifecycle.
  • Agent initialization and startup.
  • Session creation and deletion events.
  • Execution of a tool, including its name and arguments.
WARNING Indicates a potential issue or deprecated feature use. The agent continues to function, but attention may be required.
  • Use of deprecated methods or parameters.
  • Non-critical errors that the system recovered from.
ERROR A serious error that prevented an operation from completing.
  • Failed API calls to external services (e.g., LLM, Session Service).
  • Unhandled exceptions during agent execution.
  • Configuration errors.

!!! 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.

Logging setup

Logging in ADK Web

When running agents using the ADK's adk web, adk api_server, adk deploy cloud_run and adk deploy gke commands, you can control the log verbosity or destination.

Logging level

To start the web server with DEBUG level logging, run:

adk web --log_level DEBUG path/to/your/agents_dir

The available log levels for the --log_level option are: DEBUG, INFO (default), WARNING, ERROR, CRITICAL.

Capture prompt content

By default a prompt content is elided in logs for security. You can enable prompt logging using the environment variable:

export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true

!!! warning The OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT setting logs the full content of user prompts and agent responses. This is useful for debugging but may capture sensitive data or PII. In production, set this to false or ensure you have appropriate data handling policies in place.

OTLP export

To export logs to an OTLP-compatible backend, set the standard OTel environment variables:

export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="http://your-collector:4318/v1/logs"
adk web path/to/your/agents_dir

!!! note You can also set the general OTEL_EXPORTER_OTLP_ENDPOINT environment variable if you would like to send metrics and traces to the same endpoint in addition to logs.

GCP export setup

You can enable GCP export using the --otel_to_cloud flag:

adk web --otel_to_cloud path/to/your/agents_dir

Python programmatic setup

In Python, ADK uses the standard logging module and OpenTelemetry for structured GenAI logs.

Logging level

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'
)

Capture prompt content

You can enable full prompt logging programmatically by setting an environment variable:

import os

os.environ["OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"] = "true"

OTLP export

To export logs to an OpenTelemetry Collector (or an OTLP-compatible backend) programmatically:

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 export setup

To export logs to Google Cloud Logging programmatically, use the OpenTelemetry Google Cloud exporter. Here is an example in 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])

Kotlin programmatic setup

In Kotlin, ADK uses standard JVM logging facilities (defaulting to Flogger) and OpenTelemetry for structured GenAI logs.

Capture prompt content

You can enable full prompt logging by configuring the global TelemetryConfig:

--8<-- "examples/kotlin/snippets/observability/LoggingExamples.kt:
capture_content"

Activity logging with Plugins

To get detailed logs of agent activity (user messages, model requests/responses, tool calls) in the console, use the LoggingPlugin:

--8<-- "examples/kotlin/snippets/observability/LoggingExamples.kt:logging_plugin"

Go programmatic setup

In Go, ADK uses the google.golang.org/adk/telemetry package for OpenTelemetry configuration and the standard log package for general events.

Capture prompt content

You can enable full prompt logging programmatically when initializing telemetry:

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 {
		// handle error
	}
	defer tp.Shutdown(ctx)
	tp.SetGlobalOtelProviders()
}

OTLP export

To export logs to an OTLP-compatible backend, configure the standard OpenTelemetry environment variables (e.g., OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_LOGS_ENDPOINT). The ADK telemetry package will automatically use these settings when initialized.

GCP export setup

To export logs to Google Cloud Logging, use the WithOtelToCloud option:

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 {
		// handle error
	}
	defer tp.Shutdown(ctx)
	tp.SetGlobalOtelProviders()
}

If using the Go launcher, you can also enable GCP export via the CLI flag:

go run main.go web -otel_to_cloud

General events (like server startup or HTTP requests) are logged using the standard Go log package. These logs are written to stderr by default.

Understanding log output

Sample Python log entry

2025-07-08 11:22:33,456 - DEBUG - google_adk.models.google_llm - LLM Request: contents { ... }
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 example

After enabling DEBUG logging (see Logging level above), run your agent and look for messages from the google.adk.models.google_llm logger. The output shows the full LLM request and response:

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.
...

From this output you can verify:

  • Is the system instruction correct?
  • Is the conversation history (user and model turns) accurate?
  • 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?