Skip to content

Log Analyzer plugin

Turn the editor into a capable log workbench: parse structured log files through editable profiles, navigate by parsed fields and timestamps, merge multiple sources onto one timeline, follow a single request across sources, and analyse rates / percentiles / top-N values — all without loading the raw text into a normal editor tab.

Where to find it

The plugin adds three entries under the File menu:

  • File ▸ Open as Log… — open a single log file in a dedicated Log View window.
  • File ▸ Open Merged Logs… — pick two or more files, give each its own profile, and see them interleaved on one timeline.
  • File ▸ Open System Log… (Windows only) — query the Windows Event Log through the same view, with filters pushed down to PowerShell's Get-WinEvent.

A Preferences ▸ Plugins ▸ Log Analyzer page lets you set the default level chips, the fallback profile for files that don't match a glob, the "warn before parsing files above N MB" threshold, the default filter mode, and the follow-tail poll interval — one knob for both the file tail timer and the system-log stream (each Windows Event Log poll spawns a PowerShell process, so heavyweight sources may want it slower).

Large files parse on a background thread with a live record counter, and the expensive aggregations (message templates, anomalies) also compute in the background — the status bar shows "Analyzing statistics in the background…" and the panels fill in when ready, so the window stays responsive throughout. On very large loads the statistics aggregate over the newest 150,000 records and the timeline samples the whole span.

Single-file Log View

Opening a log shows the dedicated Log View window. It mirrors the ergonomics of the editor's own table-based windows (like the Diff Compare window) and stays out of the editor tab strip.

Layout

  • Toolbar — level chips (TRACE…FATAL), filter mode + filter line, Next / Previous Error (F8 / Shift+F8), Go to Time (Ctrl+G).
  • Timeline strip at the top — event volume bucketed over time, coloured by level. Drag a range to filter by time; click a bar to jump the table to the first record at or after that bucket.
  • Table in the middle — Time / Level / Source / Message, virtualised so it scrolls smoothly even for hundreds of thousands of records.
  • Detail pane below the table — shows the full raw multi-line entry for the selected row.
  • Stats panel docked on the right — per-level counts, event rate, percentile picker (p50/p95/p99 over any numeric field, default bytes), HTTP status-class distribution (1xx…5xx, hidden when no status field is present), and a top-N table over any field (default url, capped at 25 rows).

Filter modes

The filter line in the toolbar accepts five different expressions; pick the mode from the combo to its left:

Mode What it matches
Plain Case-insensitive substring against the raw line.
Words Whitespace-split tokens; every token must appear somewhere in the line, in any order. phpinfo GET matches a line containing both phpinfo and GET.
Wildcard * and ? glob against the raw line, case-insensitive.
Regex Plain QRegularExpression pattern, case-insensitive by default.
Query Structured grammar with field, level, and time predicates plus AND/OR/NOT and parentheses.

Examples for Query mode:

level>=WARN
status:500 AND method:POST
message~/timeout|refused/ AND @time in [09:00..09:05]
NOT (source:nginx OR source:apache)
level>=ERROR OR (status:5\d\d AND method:POST)

The filter line debounces typing by 200 ms so the table doesn't refilter on every keystroke; pressing Enter or losing focus applies immediately, and clearing the line also applies immediately. When a Wildcard / Regex / Query expression fails to compile the line turns red and the tooltip shows the diagnostic — the proxy keeps the previous valid filter on screen so the table doesn't blank out while you type.

  • F8 / Shift+F8 — next / previous error or fatal record.
  • Ctrl+G — go to a specific time (UTC, calendar popup).
  • Click a timeline bar to jump to the first record in that bucket.

These three chords are user-remappable in the Shortcut mapper (category Log Analyzer); open Log Views apply a remap immediately and the toolbar tooltips show the current chord.

Live parse + cancel

Large files start showing records within tens of milliseconds; parsing continues in the background and the table grows as records arrive. Filtering, scrolling, and F8 work while the parse is still running. Closing the window stops the worker promptly.

Merged Log View

File ▸ Open Merged Logs… lets you investigate a problem that spans multiple sources — a client log plus a server log, an app log plus a system journal, web access plus error, etc.

The per-file profile picker

After choosing two or more files you see a small dialog with one row per file and a profile combo per row. The combo is pre-selected by matching the file name against each profile's filename globs (case-insensitive). For a typical nginx deployment, access.log auto-picks nginx — access log (default combined) and error.log auto-picks nginx — error log. Override any row manually before clicking OK.

Layout

  • Toolbar — per-source visibility checkboxes (each label in the source's lane colour), level chips, filter line with mode combo, trace controls (combo + Follow / Clear), Sequence diagram toggle, Side-by-side toggle.
  • Timeline strip at the top — stacked per-source histogram with one lane per source, so you can see correlated bursts visually.
  • Trace banner above the table — amber strip shown only when a trace filter is active: Following <field> = <value> — N rows across all sources.
  • Stacked main area — three pages switchable from the toolbar:
    • Table (default): one row per merged record with Time / Src / Level / Logger / Message columns; the Src column foreground is the source's lane colour so you can scan source identity at a glance.
    • Sequence diagram — see Follow trace.
    • Side-by-side panes — see Side-by-side.
  • Detail pane below the table.

Filters that compose

In the merge view the filter pipeline runs in this order, all composing on top of each other:

  1. Source visibility — per-source toolbar checkboxes.
  2. Level chips — TRACE…FATAL.
  3. Follow trace — see below.
  4. Text filter — Plain / Words / Wildcard / Regex / Query (same modes and behaviour as the single-file view, applied to the merged stream).

That means you can do, for example, level>=ERROR AND status:500 across both nginx access and error logs in one expression, and follow a single client through both — the trace filter narrows the set further without breaking the level / source / text filters.

Follow trace

  1. Pick a correlation key in the toolbar's Trace: combo. It's seeded with the conventional set (trace_id / request_id / session_id / correlation_id / span_id / xRequestId) and any distinct field name actually present in the loaded records. Type a custom name if needed.
  2. Select a row in the table.
  3. Click Follow trace — or right-click the row and pick Follow trace: \<field>=\<value> for any conventional key the record carries (a one-shot path that doesn't need the combo step).

The table immediately filters to just the records sharing that key's value across all sources. Click Clear trace to remove the filter.

Sequence diagram

Once a trace filter is active and exactly 2–4 sources are visible, the toolbar's Sequence diagram toggle becomes available. It switches the main area to a fixed-lane diagram:

  • Each visible source is a vertical lane labelled at the top with a coloured swatch.
  • One row per record, time flowing top-to-bottom. The actual timestamp is on the left so you don't lose precision; rows are rank-based (fixed height) rather than time-proportional, because a real-world trace has bursts plus long pauses and a time-proportional axis would waste most of the screen on the pauses.
  • A coloured dot on the owning source's lane, plus a subtle grey arrow between consecutive records on different lanes — so you can literally see the trace bouncing between systems.
  • Level chip and message text on the right.

Click any row in the diagram to scroll the underlying table to that record. Toggle the action off to go back to the table.

For >4 sources the diagram is disabled and the table view stays.

Side-by-side panes

When exactly two sources are visible, the toolbar's Side-by-side toggle becomes available. It splits the main area into two table panes — one source each — with scroll positions linked by timestamp: scroll either pane, and the other tracks to the nearest record at or after that time. Drift between server clocks shows up naturally as the panes pulling apart.

The Sequence diagram and Side-by-side toggles are mutually exclusive (turning one on snaps the other off); both reset to the table view when the active source count moves outside their supported range.

Native system logs (Windows)

File ▸ Open System Log… queries the Windows Event Log without needing a file on disk. The dialog asks for a channel (Application / System / Security / a custom name), an optional minimum level, and a record cap. The plugin shells out to PowerShell's Get-WinEvent | ConvertTo-Json -Compress with the filter pushed down, then parses the NDJSON output through the bundled windows-event-log profile.

The action is only registered when the host actually has a working Windows Event Log source — it is genuinely absent on Linux and macOS rather than greyed.

macOS unified log and Linux journald sources are planned and slot in behind the same internal interface, with no UI changes when they land.

Profiles

The engine has no built-in special-cased parsers. Every supported format — Apache, nginx, syslog, JSON Lines, logfmt, CSV, Windows Event Log — is a LogProfile JSON file shipped in the application's log-profiles/ directory. User profiles live in the user config directory's log-profiles/ folder and override bundled ones by id.

Each profile describes:

  • line modelregex, json, logfmt, csv or delimited.
  • timestamp — which field, accepted strftime-style formats, source timezone, epoch units.
  • level — which field plus a mapping of raw tokens to the canonical Trace / Debug / Info / Warn / Error / Fatal enum.
  • continuation — how following lines glue to the current record (Java stack traces become one entry, not 30).
  • derived fields — extra fields computed by a sub-pattern over an existing field. The bundled apache + nginx profiles use this to expose a uniform client_ip field so the merge view's Follow trace can correlate web access and error events for the same client across both sources.
  • rotation — the glob to discover this source's rotated siblings, the ordering rule (numeric-suffix, embedded-date, first-record-time, mtime), plus optional transparent decompression of .gz and .zip segments.

A profile editor with field grabber, grok-style aliases and a live timestamp tester is planned in a follow-up.

Themes

Per-level colours come from the theme — the plugin registers a palette category per canonical level, the Theme Editor surfaces them, and any theme can override them. Switching themes updates the level column, the timeline strip, the stats panel and the sequence diagram in lockstep.

See also

  • Compare / diff — the Diff Compare window that the Log Analyzer's windows are modelled after.
  • Logging & diagnostics — the editor's own log file (separate from the Log Analyzer's view of arbitrary log formats).