DuckVizBeta
Product

Log Analysis

Parse and analyze log files with local-first format detection backed by a 47-format catalog.

DuckViz can ingest and analyze log files — syslog, Apache/Nginx access logs, Windows Event XML, JSON logs, and custom app formats. Detection is local-first: the browser tries to match your file against a 47-format catalog before the AI is ever called.

When the catalog hits, no data leaves the browser at all. When it misses, the AI sees a 10-line sample, proposes a regex + columns, and the result is auto-saved to your account so the same format becomes a local-only match next time.

The detection funnel

Catalog lookup (local)

DuckViz ships a curated catalog of 47 known log formats — syslog RFC 3164 / 5424, Apache CLF/Combined, Nginx default, Windows Event XML (Sysmon, Security, PowerShell), systemd journal, Cloudflare access logs, AWS CloudTrail, and more. The browser matches an incoming file against this catalog with regex + column sniffing.

If a format matches, parsing runs immediately with no server call.

AI detection (fallback)

If no catalog entry matches, DuckViz sends a 10-line sample to the AI for detection. It returns the format type (delimited / regex / JSON / XML), a human-readable name, and the regex + columns needed to split each line.

This is the only case where log content leaves the browser. Samples are used for the single detection call and are not retained.

Auto-save as a custom format

AI-detected formats are saved to your account automatically. Next time you drop a similar file, the catalog lookup picks it up locally — zero credits, zero server contact.

Manage saved formats at /settings/log-formats (see Custom Log Formats).

Parse locally

Once a format is chosen, DuckViz parses the file off the main thread (so the UI stays responsive) and loads the typed rows into a DuckDB table named after your file.

What data is sent to the server

Only when the local catalog misses: up to 10 sample lines reach DuckViz for the single detection call. Once detection completes, all parsing and querying happens locally. A saved custom format means zero future server contact for that shape.

Supported format families

FamilyExtensionsExamples
Syslog.log, .syslogRFC 3164, RFC 5424, journald
Apache/Nginx.log, .access, .clfCLF, Combined, Nginx default
Windows Event.evtx (XML export), .xmlSysmon, Security, PowerShell, DNS Server
JSON.json, .jsonl, .ndjsonCloudflare, AWS CloudTrail, structured app logs
Delimited.log, .tsvTab / pipe / custom delimiter
Regex customanyAnything you save in /settings/log-formats

Full list: Supported Formats.

Parsed vs. unparsed rows

Real log files contain rotation headers, multi-line stack traces, and stray lines that don't match the primary pattern. DuckViz splits the output into:

  • Parsed rows — fields extracted cleanly, loaded into the DuckDB table.
  • Unparsed rows — raw text that didn't match. These surface in a separate Unparsed tab.

Re-parse the leftovers

Select rows in the Unparsed tab → Generate Pattern & Ingest. The selection is treated as a fresh sample: the detection funnel runs again, and successfully parsed rows are appended to the same table — column additions are safe.

This handles mixed-format files (e.g. a gateway log with both Apache and Nginx lines) without forcing you to pre-split them.

Log-specific widgets

When DuckViz detects a log-family domain (Network & Firewall, Application Logs, Auth/Access), chart suggestions are tuned:

  • Timeline / area — events over time
  • Error distribution — by log level (ERROR / WARN / INFO)
  • Top sources — most active hosts, IPs, or services
  • Calendar heatmaps — activity by hour × day

If DuckViz also knows your log format, format-specific columns (like sourcetype, event_id, x_forwarded_for) flow into the suggestions automatically.

Inspecting the raw line

Every parsed log row keeps the original line alongside the extracted columns, so you can drop into SQL and check exactly what was on disk:

SELECT _raw FROM t_app_log WHERE level = 'ERROR' LIMIT 5;

The raw line is hidden from chart suggestions so it never ends up driving an axis. Full details: the _raw column.

See also