Query OpenTelemetry-shaped logs, traces, and metrics stored in DuckLake.
canardstack is an experimental query server for observability data stored in DuckLake. It exposes bounded Prometheus, Loki, and Tempo-compatible HTTP APIs for Grafana-style clients.
Write telemetry with duckdb-otlp in a DuckDB process, then point canardstack at the resulting DuckLake catalog for query serving in Grafana.
cargo install --locked canardstack
CANARDSTACK_DUCKLAKE_ATTACH_URI=ducklake:/path/to/catalog.ducklake \
CANARDSTACK_DUCKLAKE_DATA_PATH=/path/to/ducklake-data \
canardstack serveThe HTTP server listens on 127.0.0.1:9090 by default. Use --listen or
CANARDSTACK_BIND to change it.
canardstack serve --listen 127.0.0.1:4320
canardstack healthcheck --endpoint http://127.0.0.1:4320/healthzFor an end-to-end getting example with real metrics, logs and traces: read (this tutorial that uses the OpenTelemetry Demo app)[https://smithclay.github.io/canardstack/tutorials/local-observability-stack/].
Use the duckdb-otlp duckdb extension for ingestion, documented here.
The default Compose stack runs the full query-only architecture:
docker compose upIt starts a DuckDB Quack catalog, the published duckdb-otlp ingest image,
canardstack, and Grafana. The OTLP/HTTP ingest endpoint is on localhost:4318,
canardstack is on localhost:9090, and Grafana is on localhost:3000.
To run the stack against a locally built canardstack image:
docker compose -f compose.yaml -f compose.build.yaml up --buildRun a Compose-local logs ingest benchmark:
scripts/bench-compose-logs.py --targets 10000 --duration 60 --flushThe benchmark reports accepted log datapoints/second, accepted 202
responses/second, and average Docker CPU percentage for ingest, catalog, and
canardstack containers.
canardstack serves:
- Prometheus-compatible query and discovery routes under
/api/v1/... - Loki-compatible routes under
/loki/api/v1/... - Tempo-compatible search and trace routes under
/api/... - Operational endpoints at
/healthz,/metrics, and/api/admin/health/...
Set CANARDSTACK_API_KEY for query routes and
CANARDSTACK_ADMIN_API_KEY for admin health routes.
This project is experimental. The compatibility APIs are intentionally bounded: there is no arbitrary SQL endpoint, no full PromQL/LogQL/TraceQL implementation, and query paths are constrained by time range, row limit, timeout, memory limit, and admission caps.
