For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Store logs in a database
Store agentgateway access logs in a SQLite or PostgreSQL database to power the UI analytics and enable historical log queries.
By default, access logs are written to stdout. To persist LLM request logs, configure agentgateway to write records to a request_logs table. The database logger captures LLM traffic, rather than every HTTP or MCP access log. Agentgateway can use the configuration database or a separate request-log database.
Set up the database
Agentgateway supports SQLite and PostgreSQL as log storage backends. Set config.logging.database.url to the connection URL for your database. Agentgateway detects the backend from the URL. A postgres:// or postgresql:// URL uses PostgreSQL and any other value is treated as a SQLite file path.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
config:
logging:
database:
url: "sqlite:///data/logs.db" # SQLite
# url: "postgres://user:password@host:5432/dbname" # PostgreSQLIf you have a database configured for configuration storage in config.database, agentgateway automatically uses this database to store access logs. No additional configuration is required. Set config.logging.database explicitly when you want access logs to go to a different database than the one that is used for configuration storage. If neither config.logging.database nor config.database is set, no database log store is initialized and access logs are written to stdout only.
For database setup instructions, including how to deploy PostgreSQL for Kubernetes installs, see Configuration storage.
Important
The Helm chart renders the config.database and config.storage sections for you from its mode and database.postgres.url values, so do not set those two sections in your values.yaml. To send access logs to a separate database on a Helm install, set config.logging.database under the chart’s top-level config field instead.
mode: database
database:
postgres:
url: "postgres://user:password@host:5432/agentgateway"
config:
logging:
database:
url: "postgres://user:password@host:5432/agentgateway_logs"Note
Access log customizations interact with the database as follows:
filter: Access log filtering via thefrontendPolicies.accessLog.filterfield applies to stdout and the database. A request that is filtered out of stdout is also excluded from the database.add: Adding custom log attributes via thefrontendPolicies.accessLog.addfield affects the access logs that are sent to stdout only. Use thefrontendPolicies.accessLog.database.addfield to add custom fields to database records.remove: Access log attributes that are defined infrontendPolicies.accessLog.removeare only removed from stdout. The database schema is fixed, so this setting has no effect on what is stored in the database.
Access log data storage
Each access log record captures the following data.
| Category | What is captured |
|---|---|
| Timing | Request start and end timestamps, duration in milliseconds |
| HTTP | Response status code, error message if any |
| Generative AI | Operation name, provider (for example openai), request model, response model, input/output/total token counts, and realized USD cost if a model cost catalog is configured |
| Identity | User and group derived from API key metadata or a JWT claim, client user agent |
| Trace context | OpenTelemetry trace ID and span ID, if tracing is enabled |
| Attributes | All custom log attributes as a JSON blob |
When a request prompt guard rejects an LLM request before the provider call, the database still stores a log record. The Logs page shows the rejection. The record includes request-side LLM metadata, but no provider response fields because the request never reaches the LLM provider.
By default, LLM prompt and completion content is not stored. To capture it, set llm: full under the frontendPolicies.accessLog.database section.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
frontendPolicies:
accessLog:
database:
llm: fullQuery the database
Use agctl for routine queries through the gateway API. You do not need database credentials on the machine running the CLI.
agctl standalone logs --limit 10
agctl standalone logs --since 1h --attributes -o json
agctl standalone analytics --by provider,model --since 24hTo inspect a stored prompt and completion, run agctl standalone logs <request-id> with an ID from the listing. Payloads are available only when capture was enabled. For filters and streaming, see View LLM request logs with agctl.
Query with a database client
Use your database client to inspect the request_logs table directly and verify that access logs were written successfully. The following examples show the most recent 10 log entries.
sqlite3 /path/to/logs.db \
"SELECT id, started_at, http_status, gen_ai_provider_name, duration_ms FROM request_logs ORDER BY started_at DESC LIMIT 10;"To include LLM prompt and completion content (if you enabled llm: full), join the request_log_payloads table.
SELECT r.id, r.started_at, r.http_status, p.request_prompt_json, p.response_completion_json
FROM request_logs r
LEFT JOIN request_log_payloads p ON r.id = p.log_id
ORDER BY r.started_at DESC
LIMIT 10;Add custom fields to database logs
Use the frontendPolicies.accessLog.database.add field to store additional access log fields that are evaluated as CEL expressions alongside each record.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
frontendPolicies:
accessLog:
database:
add:
user_id: 'request.headers["x-user-id"]'Custom fields are stored as a JSON blob in the attributes_json column of the request_logs table, not as separate columns. After sending another LLM request, inspect the new fields through the CLI, or use your database’s JSON functions below.
agctl standalone logs --attributes -o json
agctl standalone analytics --by user_id --since 1hsqlite3 /path/to/logs.db \
"SELECT id, json_extract(attributes_json, '$.user_id') AS user_id, started_at, http_status
FROM request_logs
ORDER BY started_at DESC
LIMIT 10;"Disable database logging
Agentgateway writes request logs to config.logging.database. If that field is not set, agentgateway writes request logs to config.database instead. To stop writing access logs to a database, remove both fields, and then restart agentgateway. If you keep config.database for other features, such as budgets or hybrid configuration storage, agentgateway keeps writing request logs to that database. After you remove both fields, access logs continue to go to stdout, and the database-backed UI pages and the agctl standalone logs and agctl standalone analytics commands become unavailable.