logq

A local-first, single-binary log explorer.
Point it at a folder of JSONL, CSV, or Parquet files and get SQL, histograms, charts, and live tail in seconds.
v0.1.4 · DuckDB-powered · MIT/Apache-2.0

The problem

When production breaks, your options are: ssh + tail + jq (slow, error-prone), ship logs to a SaaS (expensive, slow to set up), or stand up Loki or Elastic (ops-heavy overkill). There's no good middle option for "I have a folder of JSONL files, I want to explore them right now, locally, with real query power."

30-second demo

$ logq ./var/log
> Scanning ./var/log... found 14 files (3.2 GB)
> Detected: jsonl (12 files), gz-jsonl (2 files)
> Inferred timestamp column: "ts"
> Inferred level column: "level"
> http://localhost:7777

Browser opens. You see a timestamp histogram, a facet panel (auto-detected low-cardinality fields like level, service, host), a results table, and a SQL editor pre-filled with a sensible default.

The five-property bar

PropertyWhy it matters
Local-firstNo SaaS, no account, runs fully offline / air-gapped.
File-nativeQueries .jsonl, .csv, and .parquet directly. No ingestion.
JSON-log-awareAuto-infers schema, nested fields, timestamps, levels.
SQL-poweredFull DuckDB SQL: joins, window functions, aggregations.
Real web UIBrowser, not TUI. Shareable URLs, charts, faceted search.

No existing tool combines all five. DuckDB UI isn't log-shaped. Tailpipe requires ingestion. lnav is terminal-only. Logdy has no SQL.

Quickstart

# Homebrew
brew install alldoq/tap/logq
logq ./var/log

# Docker
docker run --rm -p 7777:7777 -v "$PWD/logs:/data" ghcr.io/alldoq/logq:latest

# From source
git clone https://github.com/alldoq/logq.git
cd logq
cargo build --release
./target/release/logq ./sample-data

Features

JSONL, CSV, Parquet

All UNION'd by name into one logs view via DuckDB read_json_auto, read_csv_auto, and read_parquet. Gzip and zstd handled.

Cross-file joins

SELECT * FROM logs WHERE service='api' AND request_id IN (SELECT request_id FROM logs WHERE service='nginx' AND status>=500). No pipeline.

Live tail

Toggle button streams newly appended lines over WebSocket, with optional --remote user@host:/path over SSH.

Charts

Switch any GROUP BY result between table, bar, and line views. Column headers open a top-25 value modal.

JSON cell expand

Click a nested cell to open a pretty-printed JSON modal with the full structure. No truncation.

Export

CSV and Parquet download buttons run a COPY (...) TO over the current query. Round-trip cleanly into another logq.

Saved queries

Persist named queries to .logq/queries.yml in the directory. Git-friendly, shareable.

Schema overrides

Drop a .logq/schema.yml to coerce columns to TIMESTAMP, BIGINT, DOUBLE, etc., with optional strptime format.

HTTP API + token

Versioned /api/v1/*, optional bearer-token auth via --token or LOGQ_TOKEN. Health endpoint for monitoring.

CLI mode

logq /dir query "SELECT ..." for one-shot queries. Output as JSON, NDJSON, CSV, or TSV. No web server needed.

Shareable URLs

Every query state is encoded in the URL hash. Copy-link button copies to clipboard; teammates open the same view.

Single binary

Bundles DuckDB and the web UI. No daemons, no dependencies, no system DuckDB needed. About 34 MB.

stdin + remote sources

kubectl logs ... | logq -, or point at an https:// or s3:// URL. DuckDB httpfs is loaded on demand.

nginx, apache, syslog

Plain-text access logs and syslog (RFC3164 + RFC5424) are detected at scan time and exposed as structured columns: remote_addr, method, path, status, host, app.

Time-range brush

Click-drag on the histogram to scope every query to a window. Pairs naturally with the level facet for incident triage.

Tabs + history

Multi-tab editor with persistent state. The last 100 queries surface in a one-click history panel.

API at a glance

curl -s localhost:7777/api/health
curl -s localhost:7777/api/v1/meta
curl -s -X POST localhost:7777/api/v1/query \
  -H 'Content-Type: application/json' \
  -d '{"sql":"SELECT level, COUNT(*) FROM logs GROUP BY 1"}'

# Auth (when --token is set)
curl -H "Authorization: Bearer $LOGQ_TOKEN" localhost:7777/api/v1/meta

Status

v0.1.2 covers the v0.1 MVP plus most v0.5/v1.0 items: live tail, remote tail over SSH, schema overrides, CSV/Parquet ingest, charts, exports, Docker image, Homebrew tap, versioned HTTP API. Performance hardening for 100 GB+ datasets and a daemon/alert mode are still ahead.