Database6 min

Analyze a Server Log File with SQL — No Grep, No Upload

Run SQL against a raw nginx, Apache, or JSON log file in your browser using DuckDB-WASM. Faster than grep, safer than uploading production logs.

Log parsing runs locally via Zro7 Log Analyzer using DuckDB-WASM. Production logs stay on your machine.

To analyze a server log file with SQL, open Zro7 Log Analyzer, drop the log, and query it like a table. DuckDB-WASM parses nginx / Apache / JSON-lines formats directly — SELECT status, COUNT(*) FROM logs GROUP BY status just works. Faster than a grep+awk pipeline, and vastly safer than uploading production logs to a hosted SaaS.

Why SQL beats grep for logs

  • Group and countGROUP BY status vs. awk '{print $9}' | sort | uniq -c.
  • Time bucketingdate_trunc('minute', ts) is one line vs. a shell nightmare.
  • Joins — cross a log with a users CSV to find which accounts hit that 500.
  • Window functions — request rate per IP over a 60-second sliding window in one query.
  • Ad-hoc filtersWHERE path LIKE '/api/%' AND status >= 500.

Common analyses

  1. Top offending URLs: SELECT path, COUNT(*) c FROM logs WHERE status >= 500 GROUP BY path ORDER BY c DESC LIMIT 20;
  2. Traffic by minute: SELECT date_trunc('minute', ts) m, COUNT(*) FROM logs GROUP BY m ORDER BY m;
  3. p95 latency by endpoint: SELECT path, quantile_cont(latency_ms, 0.95) FROM logs GROUP BY path ORDER BY 2 DESC;
  4. Suspicious IPs: SELECT ip, COUNT(*) FROM logs WHERE status = 401 GROUP BY ip HAVING COUNT(*) > 100;

Why not ship logs to Datadog / Splunk?

Hosted log SaaS costs scale with ingestion volume, and every log line — including customer emails, tokens, and stack traces — ends up on someone else's disk. For quick incident triage or a monthly report, a local DuckDB query on a downloaded log slice is instant, free, and audit-clean. Ship to Datadog for continuous prod monitoring; use Zro7 for ad-hoc digs.

Steps

  1. Open Log Analyzer.
  2. Drop nginx, Apache combined, or JSON-lines log files (gzip OK).
  3. Zro7 infers columns (ip, ts, method, path, status, size, user_agent, latency_ms).
  4. Run SQL. Export the result as CSV for your report.

Frequently asked questions

Compressed logs?

Yes — .gz is supported directly; DuckDB decompresses on the fly.

Multi-file query?

Yes — drop a whole folder of daily rotations and query them as one table with <code>read_csv_auto('logs/*.log')</code>.

Custom log format?

Point-and-click parsing today; regex-based custom parsing coming. As a workaround, drop into <a href="/sql-playground">SQL Playground</a> and split with <code>string_split</code>.

How big a log can it handle?

Multi-GB rotations are fine — DuckDB scans columnar-fashion without loading everything into RAM.

Any upload?

None. Log lines never leave your browser.

Related posts

← Back to blog