Query Grafana Loki from DuckDB in plain SQL, with label/time/line-filter pushdown into LogQL
Installing and Loading
INSTALL loki FROM community;
LOAD loki;
Example
-- Store the Loki endpoint and credentials once with the Secret Manager.
CREATE SECRET my_loki (
TYPE loki,
ENDPOINT 'https://logs-prod.example.net',
TOKEN 'glc_...' -- or USERNAME + PASSWORD for basic auth
);
-- Query logs in plain SQL. WHERE predicates on promoted label columns, the
-- timestamp and the log line are translated into a LogQL stream selector,
-- start/end bounds and line filters; anything else DuckDB applies as a residual.
SELECT timestamp, level, line
FROM loki(selector := '{job="api"}', labels := ['level'], secret := 'my_loki')
WHERE level = 'error'
AND timestamp >= now() - INTERVAL 2 HOUR
AND line LIKE '%timeout%';
-- Or send raw LogQL through untouched with loki_scan():
SELECT * FROM loki_scan('{job="api"} |= `timeout`', secret := 'my_loki');
About loki
loki turns a Grafana Loki instance into a first-class, queryable DuckDB data
source, so you can join your logs against Parquet, CSV, Postgres, or anything
else DuckDB reads — without ever hand-writing an HTTP request.
loki(selector := ...)— pushdown-driven. SQLWHEREfilters on promoted label columns,timestamp, andlineare translated into the LogQL stream selector,start/endtime bounds, and line filters. Untranslatable predicates are left as residuals for DuckDB to apply, so results are always correct.loki_scan(query := ...)— a raw-LogQL escape hatch for full control.loki_labels()/loki_label_values()/loki_series()— label discovery helpers so the source is explorable and autocompletes well.
Connection and auth (bearer token, basic auth, X-Scope-OrgID tenant, or arbitrary
headers) come from DuckDB's Secret Manager with per-call overrides. A
CREATE SECRET (TYPE loki, PROVIDER env) seeds the connection from the standard
logcli environment variables (LOKI_ADDR, LOKI_BEARER_TOKEN,
LOKI_USERNAME/LOKI_PASSWORD, LOKI_ORG_ID), with inline options overriding the
environment. Results page
automatically over Loki's per-request entry cap, and projection pushdown skips
materialising the columns a query doesn't select. Timestamps keep Loki's nanosecond
resolution (TIMESTAMP_NS). See the
repository for full documentation.
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| loki | table | NULL | NULL | |
| loki_label_values | table | NULL | NULL | |
| loki_labels | table | NULL | NULL | |
| loki_scan | table | NULL | NULL | |
| loki_series | table | NULL | NULL |
Overloaded Functions
This extension does not add any function overloads.
Added Types
This extension does not add any types.
Added Settings
This extension does not add any settings.