Configure logging
This guide sets log levels for DIAL components and ships their logs off the container with the Vector sidecar in the Helm chart. It is for DevOps engineers operating DIAL who need logs for debugging or aggregation. For the conceptual model, see Observability.
Prerequisites
- A running DIAL deployment
- For log shipping: DIAL deployed with the
dial-coreHelm chart - A log aggregator if you want to forward logs beyond standard output
Two ways to collect logs
DIAL components support two independent ways to collect logs, and most components support both at once:
- Stdout collection — every component writes logs to standard output by default. A log collector (fluentbit, Grafana Alloy, or similar) tails the container's stdout stream. This requires no component-side configuration, but the log format varies by component, so verify it before writing parsing rules.
- OTEL logs via a collector — almost all DIAL components, including DIAL Core, can additionally export structured logs over OTLP to an OpenTelemetry collector. Set
OTEL_LOGS_EXPORTER=otlpand pointOTEL_EXPORTER_OTLP_LOGS_ENDPOINTat your collector. As with tracing, the collector accepts gRPC on port4317or HTTP on port4318— setOTEL_EXPORTER_OTLP_PROTOCOLto match (see Choose an OTLP transport). OTLP logs follow the OpenTelemetry logs data model.
Set log levels per component
Each component reads its own log-level variables. Supported levels run from least to most verbose: ERROR, WARN, INFO, DEBUG, TRACE.
| Component | Log level | OTLP log export |
|---|---|---|
| DIAL Core | AIDIAL_LOG_LEVEL, AIDIAL_LOG_FILE (log file location) | OTEL_LOGS_EXPORTER=otlp |
| DIAL Chat | OTEL_LOG_LEVEL | OTEL_LOGS_EXPORTER, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_TIMEOUT |
| DIAL Model Provider | LOG_LEVEL, one level for every adapter it runs | OTEL_LOGS_EXPORTER=otlp |
| Bedrock Adapter, Vertex AI Adapter | LOG_LEVEL and AIDIAL_LOG_LEVEL | OTEL_LOGS_EXPORTER=otlp |
| OpenAI Adapter, DIAL-to-DIAL Adapter | LOG_LEVEL | OTEL_LOGS_EXPORTER=otlp |
For example, raise DIAL Core to debug logging:
AIDIAL_LOG_LEVEL=DEBUG
DIAL Core can additionally export logs over OTLP:
OTEL_LOGS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://<YOUR_COLLECTOR_HOST>:4317
DIAL Chat exports logs over OTLP the same way. Point it at your collector with OTEL_EXPORTER_OTLP_LOGS_ENDPOINT and disable the SDK entirely with OTEL_SDK_DISABLED=true when needed.
Where DIAL Core writes logs
DIAL Core writes log files to the directory set by LOG_DIR, which defaults to /app/log. Containers also stream logs to standard output and standard error, so kubectl logs and docker logs work without extra configuration.
The on-disk log format of DIAL Core (structured JSON versus plain text) is not documented in the source repositories. Verify the format your version produces before writing parsing rules in a downstream aggregator.
Ship logs with the Vector sidecar
The dial-core Helm chart includes an optional Vector sidecar that tails Core's log files. Enable it under the logger key:
logger:
enabled: true
image:
repository: timberio/vector
By default the sidecar tails /app/log/*.log and prints to standard output:
logger:
config:
sources:
core_logs:
type: file
include: [/app/log/*.log]
sinks:
console:
inputs: [core_logs]
type: console
target: stdout
encoding:
codec: text
Forward logs to an aggregator
To send logs somewhere other than standard output, override logger.config with a Vector sink for your aggregator. Vector supports sinks for Elasticsearch, Loki, HTTP endpoints, and many others. Keep the core_logs source and replace or add to the sinks block.
Send usage logs to blob storage
DIAL Analytics ingests usage logs from Azure Blob Storage or AWS S3. The dial-core chart ships no blob sink: the default console sink above writes to standard output only, so add a Vector azure_blob or aws_s3 sink that reads core_logs.
The object layout is the contract between the sink and DIAL Analytics. By default, Analytics looks for gzip-compressed log files in the container or bucket BLOB_BUCKET, under a date path with a date prefix in each file name:
| Part | Analytics setting | Default |
|---|---|---|
| Container or bucket | BLOB_BUCKET | logs |
| Base path | SYNC_PATH_PREFIX | logs |
| Date directory | SYNC_DATE_PATH_PATTERN | yyyy/MM/dd |
| File name prefix, followed by an epoch | SYNC_FILE_NAME_PREFIX_PATTERN | 'date='yyyy-MM-dd |
Warning
A sink that writes a different layout does not cause an error: Analytics silently finds no files. Set the three
SYNC_*variables to describe the layout exactly; see Log blob layout.
Result
Components log at the level you set, DIAL Core's logs are tailed by Vector, and — once you override the sink — forwarded to your aggregator or to the blob store that DIAL Analytics reads.
Further reading
- Tracing (OpenTelemetry) — correlate logs with traces using
OTEL_PYTHON_LOG_CORRELATION - DIAL Analytics configuration — blob source, ingestion schedules, and verification
- Alerting — alert on error-rate signals
- Grafana + Prometheus — complete the default observability stack