Serilog Debug
Readable Serilog logs inside VS Code. Supports both the JSON emitted by the common .NET logging configuration and the standard text console format: the message comes first, while request IDs, properties and exceptions stay available in the detail panel.
Install
- In VS Code, open Extensions.
- Select … → Install from VSIX… and choose
serilog-debug-0.2.3.vsix; reload VS Code when prompted. If you installed the earlier local-tools.serilog-lens build, uninstall it first to avoid running both copies.
- Open the Command Palette and run Serilog Debug: Try Demo Logs for a tour using fictional data.
- Run a .NET service with F5. The Serilog Debug panel opens when the first JSON or recognized Serilog text event arrives.
The display name is Serilog Debug and the extension identifier is SeriDebugger.serilog-lens. The package publisher matches the SeriDebugger Marketplace publisher. This is a different extension identity from the earlier local-tools.serilog-lens build; configuration keys remain serilogLens.*.
Read the event, then follow the request
- Compact one-line rows show the time, a severity color indicator and a readable message preview. At the top of the list, Load older events adds earlier retained matches in batches of up to 250 without changing your filters. Select a row to read the complete event; its level and format appear beside Event Details.
- Consecutive repeated events share one row with a severity-colored circle showing the total number of loaded occurrences. The same counter appears beside Event Details, where you can move between occurrences to inspect their individual timestamps, properties and original output. Opening a repeated row starts with its latest loaded occurrence.
- Numbers inside the repetition circles are bold, keeping their compact size. The editable occurrence number uses the normal text weight and size, centered and without native spinner arrows. Use the previous/next buttons or type an occurrence number and press Enter.
- Repetition compares the complete message before masking or shortening, along with its level, source, service, environment, format, exception and whether it has a timestamp. Different timestamps and request properties can belong to the same group; each occurrence keeps its own data. Events separated by a different event stay separate, even when a filter hides that intervening event. Counts and exports continue to include the original events, not just the grouped rows.
- Rows have no visible borders and use a compact height of 26px. Plain-text events without a timestamp use 23px rows and start at the indicator guide without a time column or severity gutter. Text and repetition counters retain their readable size; selection uses a background tint. The complete text stays available in Event Details.
- Color accents for severity, complete HTTP/HTTPS URLs, absolute and relative paths, email addresses, single-quoted text, dotted .NET type/member names, numbers, dates and times (including AM/PM) in messages. Highlighting is visual only: it never changes the log text, opens a URL or runs its contents.
- Embedded JSON such as
Response: {"count":12,"items":[1,2]} appears as inline code in the row, with a distinct background and syntax colors for keys, values, braces and punctuation. The row stays on one line; Event Details shows the indented payload and its fields. Works in text messages and inside a JSON event's RenderedMessage.
- Event Details includes a separate Payload fields section with readable key/value rows and grouped nested data, alongside the formatted JSON.
- Copy icons in each payload header and beside its fields copy the complete formatted JSON or the full field value, including values shortened on screen. Objects and arrays copy as formatted JSON; strings copy without extra quotes. Copy follows the current Show/Hide values state, so hidden credentials stay
[hidden] until explicitly revealed. A check mark confirms a successful clipboard write.
- Inconsolata is bundled for the viewer, with a slightly fuller regular weight of 450. It works offline and does not change VS Code's editor font settings.
- Recognizable token values and very long uninterrupted values are compact by default, with explicit Show/Hide controls in Event Details. This also applies to a repeated token printed after
Token acquired outside the JSON. Row previews are bounded; the complete record stays available in details and export.
- A single compact toolbar puts search on the left and level, service, environment and source filters on the right. In narrow panels, the Filters button opens these same controls without adding another toolbar row. Long source names stay inside their control; hover to read the full selection.
- The first available source is selected initially. You can then choose All sources or another source; incoming logs do not override your choice. Resetting the filters also keeps All sources selected.
- Show source / Hide source toggles an optional column with abbreviated source names and full-name tooltips. It starts off when the view loads. This button sits beside Show JSON only and Charts at the right of the stream header.
- Show JSON only keeps messages containing a complete JSON object or array. A Serilog JSON envelope alone does not qualify: a plain rendered message such as
Request completed with 200 in 420 ms is excluded. This filter applies to all retained matches, including older history, charts and exports. Reset filters turns it off.
- JSON details omit a standalone
Received message: label above the payload. Other prose, original messages, search content and exported data remain intact.
- Charts opens lightweight SVG charts over the stream: event volume, errors, warnings and observed durations. Click a bar or drag a continuous time range to filter original events; Charts closes and keeps a removable filter. Reopening preserves the selected range. The time-mode selector supports dated and time-only logs separately.
- Event, warning and error counts sit in the footer. Warning/error counts remain clickable shortcuts; the memory status and any dropped-event notices stay available below the log stream.
- Click an event to see its exception, properties and original JSON or text output.
- In Event Details, click a TraceId or CorrelationId to focus on that request across retained events.
- The level filter includes a severity-colored dot beside each event type. Clear logs is the icon immediately to the right of the matching-event count.
- The ⋯ menu at the right end of the toolbar contains Pause/Resume capture, Open log and Export. The arrow beside the capture indicator toggles following the latest event; its tooltip and pressed state show whether following is active.
- Following latest starts enabled. Opening an event's details, loading the font or resizing the panel keeps it enabled. Deliberately scrolling back or switching it off pauses following. Scrolling back down to the newest event automatically resumes following; you can also use the arrow button. Capture continues independently.
- Open a UTF-8 JSON Lines log file, including the final line without a newline.
- Export all matching retained events to a JSONL file you choose. Export includes the complete original data, including any sensitive fields.
- Serilog text prefixes such as
[12:57:48 DBG] become a separate time and severity, leaving a clean message. Other plain text and malformed JSON remain visible as Text. Repeated messages are grouped for display only; the stored events are never deduplicated.
- Keyboard:
/ focuses search; Enter inspects an event; Escape closes an open toolbar popover first, or the inspector when no popover is open. Arrow keys navigate the action menu. Use Clear focus to leave a request timeline.
Search and filters live inside the viewer. VS Code's public view/title contribution supports command actions, not custom inline search/select widgets; the built-in Debug Console's title controls are part of VS Code itself. The viewer uses a compact toolbar without depending on internal APIs.
Supported event shape
{"Timestamp":"2026-11-02T12:00:00Z","Level":"Information","MessageTemplate":"Return {Count} items for order {OrderId}.","RenderedMessage":"Return 12 items for order DEMO-104.","TraceId":"demo-trace-104","SpanId":"demo-span-1","Properties":{"Count":12,"OrderId":"DEMO-104","Application":"Demo Orders API","Environment":"local","CorrelationId":"demo-request-104","RequestPath":"/api/orders/DEMO-104/items"}}
Also accepts flattened properties and Serilog compact/CLEF fields (@t, @l, @m, @mt, @x, @tr, @sp). RenderedMessage takes precedence. If only a MessageTemplate is present, basic placeholders are substituted; .NET-specific formatting/alignment is deliberately left in the template rather than guessed. Use a formatter that includes RenderedMessage for exact rendering.
Text console example:
[12:00:00 DBG] /events/stream returned 302 after 25ms
Recognizes a leading [HH:mm:ss LEVEL] prefix, optionally with 1–7 fractional second digits after a dot. The clock fields must be valid. Standard level names and abbreviations are accepted, including VRB, DBG, INF, WRN, ERR and FTL. Time-only values remain time-only: no calendar date, service or environment is inferred. One space or tab after the closing bracket is removed; further message indentation is preserved. Custom prefixes and continuation lines remain Text. Exported text events include their parsed timestamp/level/message and the complete OriginalOutput in JSONL.
Embedded payload example:
[13:07:13 DBG] Response: {"access_token":"fictional-value","expires_in":3600,"active":true,"user":{"name":"Demo","roles":["reader"]}}
The message label and payload are displayed separately. Objects and arrays are formatted only when they parse as complete JSON; malformed or truncated fragments remain text. Surrounding message text is preserved. Recognized credential fields such as access_token, refresh_token, password and client_secret are hidden in formatted payloads until you choose to reveal them. Recognizable token values in surrounding text are also hidden, without decoding or validating them; other very long values get a compact display with expansion controls. This is a display convenience, not log sanitization: the original event remains in memory and exports retain original values. Other fields and arbitrary text may still contain sensitive data.
JSON embedded in a multiline RenderedMessage is supported. Separate physical text log lines are still separate events; the viewer does not guess which subsequent lines belong to a previous message.
Debugging configuration
By default, captures debug types coreclr, clr and dotnet. The debugger must emit stdout, stderr or console output events through VS Code's Debug Adapter Protocol. For other adapters, add their type to Serilog Debug: Debug Types, or use * to opt into all adapters.
This extension does not alter Serilog, CloudWatch, your launch profile, or your chosen .NET environment. It can read local output even if your application labels events as staging. It does not subscribe to an ordinary integrated terminal, Docker logs or CloudWatch. If your debugger sends output only to a terminal, configure that debugger to emit Debug Console output, or open a captured log file.
| Setting |
Default |
Meaning |
serilogLens.captureDebugOutput |
true |
Capture supported debug output. |
serilogLens.debugTypes |
coreclr, clr, dotnet |
Adapter types; changes apply to new sessions. |
serilogLens.autoReveal |
true |
Reveal once when the first JSON or recognized Serilog text event arrives in a session. |
serilogLens.maxEvents |
2000 |
Retain 100–10,000 events, also subject to the memory budget. |
Limits and privacy
- No outbound HTTP/network client, telemetry, AI service, shell/task execution, remotely loaded fonts, CDN or runtime third-party packages. Inconsolata is a bundled font asset under the SIL Open Font License; see
media/fonts/OFL.txt.
- Copy writes text to the system clipboard only when you press a copy button; the extension never reads the clipboard. Copy requests are limited to 1,048,576 UTF-16 code units. Larger payloads remain available through export.
- Logs remain in memory in the VS Code extension host/webview. No log history or filters are persisted by this extension. Files are written only through explicit export.
- With Remote SSH, WSL or containers, the workspace extension runs on that remote extension host; VS Code carries data to its local UI. “In VS Code” does not mean the data never crosses your configured remote connection.
- Only trusted workspaces are supported. Extensions still run with VS Code's permissions; this design does not create an OS sandbox or an independent security certification. See SECURITY.md.
- At most 2,000 events by default and a 16 MiB serialized-event retention budget. This is not a total process-memory guarantee; parsing, UI and message transfer also use memory. Old events are evicted with a visible count.
- Individual lines exceeding 262,144 UTF-16 code units are skipped with a visible count. Full original logs remain in the Debug Console/file.
- The timeline initially shows the latest 250 matches. Load older events makes every earlier retained match available without narrowing your filters. Loaded rows stay available when new logs arrive, until the normal memory limit evicts them. Search, counts and export always include all retained matches, including ones not yet loaded into the timeline.
- File imports are snapshots, up to 20 MiB, one JSON object or text log event per line. Pretty-printed multi-line JSON arrays and live file tailing are not supported in this initial version.
- Pausing capture deliberately skips new debug output; it is not replayed on resume. Clearing also discards any partially received line and cancels an active import.
Build and verify
Requires Node.js 22.17+ and npm. Runtime uses only VS Code and Node built-ins. Tailwind CSS, daisyUI and Microsoft's VSCE are build tools, locked in package-lock.json.
npm ci --ignore-scripts
npm test
npm run build
npm run package
The VSIX is written to artifacts/serilog-debug-0.2.3.vsix. Rebuild it from these sources for an internal review. Neither packaging nor the scripts publish anything to a Marketplace.
For native integration checks, run npm run test:host. The official @vscode/test-electron tool downloads a separate stable VS Code test runtime into this project's cache. Set VSCODE_EXECUTABLE to use an existing executable instead. The runner uses a separate workspace/profile/extensions directory inside this project and a synthetic debug adapter. It does not need your service or credentials. A temporary VS Code test window may appear.
For manual browser testing, run npm run preview and open http://127.0.0.1:4173. Demo logs load automatically. Open log, filters, details, copying and export work locally. Imported files are limited to 20 MiB; the preview retains the latest 10,000 lines. Debug session capture requires VS Code. Stop the server with Ctrl+C; use the PORT environment variable to choose another port.
Filters stay in the top toolbar at every width, using the compact filter menu on narrow windows. Show source / Hide source, Show JSON only and Charts are buttons at the right of the stream header. The source column and JSON-only filter start off after reload. Run node scripts/preview-controls-smoke.js with the preview running and Playwright configured to verify filtering, export and detail behavior.
The expanded demo has three sources, long source names, repetition groups of 2/5/12 with individual occurrence context, plain text, Serilog text, JSON/CLEF, nested payloads, masked fictional credentials, exceptions, trace journeys and syntax-highlighting examples. Both VS Code and the preview add 260 older startup records to exercise Load older events. The first source contains the main showcase; select All sources to compare sources. Run node scripts/preview-layout-smoke.js with the preview running and Playwright configured to check the responsive layout, column toggle and demo interactions.
The Charts toggle beside the matching count shows event volume, error rate (Error + Fatal), warnings and observed duration distribution. Charts follow the current filters and include all retained matching occurrences, including older unloaded events. Missing timestamps are reported; duration metrics require explicit elapsed/duration evidence. Custom SVG charts use no additional libraries, limit timeline rendering to 48 intervals, and only calculate while visible. The extension and browser preview use the same packaged UI assets. To verify them, run node --test test/preview-charts-data.test.js and, with the preview running and Playwright configured, node scripts/preview-charts-smoke.js.
Charts float above the stream without moving it. Click a time interval or duration bar (or use Enter/Space) to show its original events in the list and export. The panel closes automatically so the filtered logs are visible, while the removable filter chip stays beside Charts. Reopening Charts preserves the selection and the full overview; click the same selection again or its filter chip to clear it. Changing search/toolbar filters or resetting filters clears chart selection. The duration summary reads 95% of durations ≤: at least 95% of the measured values are at or below the displayed time (the 95th percentile), not the average.
Drag across the timeline in either direction to select a continuous time range. Filtering uses exact event timestamps, independently of the 48 plotted intervals; the selected range is shown while dragging and restored when Charts is reopened. Escape cancels a drag. An empty range shows no matching logs and retains the removable filter.
Dated timestamps are compared internally as instants; the axis uses the first dated log's timezone offset rather than forcing UTC. Original log timestamps remain unchanged. Mixed logs offer Dated and Time only views so clock-only events remain accessible without assigning them a calendar date. Events without a valid timestamp remain in the list and summary counts but cannot be positioned on the timeline. Run node scripts/preview-chart-range-smoke.js to verify drag selection and mixed timestamp modes in the browser.
For automated visual/browser checks, provide PLAYWRIGHT_MODULE with the path to an installed Playwright module and run node scripts/ui-smoke.js.
To work on the extension, open this folder in VS Code, build the CSS, then use the Run Serilog Debug F5 launch configuration.