Expand description
Tag-filtered development logging (Trace env var). Must be declared before WindServiceHandlers so the dev_log! macro is available.
§DevLog - Tag-filtered development logging
Controlled by Trace environment variable.
The same tags work in both Mountain (Rust) and Wind/Sky (TypeScript).
§Usage
Trace=vfs,ipc ./Mountain # only VFS + IPC
Trace=all ./Mountain # everything
Trace=short ./Mountain # everything, compressed + deduped
Trace=terminal,exthost ./Mountain # terminal + extension host
./Mountain # nothing (only normal log!() output)§Short Mode
Trace=short enables all tags but compresses output:
- Long app-data paths aliased to
$APP - Consecutive duplicate messages counted (
(x14)suffix) - Rust log targets compressed (
D::Binary::Main::Entry→Entry)
§File sink
When Record=1 (or, in debug builds, Trace is set),
every emitted line is mirrored to:
~/Library/Application Support/<bundle>/logs/<YYYYMMDDTHHMMSS>/Mountain.dev.logThe timestamp directory follows Tauri’s tauri-plugin-log format, so
the dev log sits next to the plugin’s own log file for the same boot
(one directory per process start). Use Record=0 to force-
disable even in debug. File writes are flushed per line so tail -f
shows live output.
§Tags (38 granular tags across all Elements)
| Tag | Scope |
|---|---|
vfs | File stat, read, write, readdir, mkdir, delete, copy |
ipc | IPC routing: invoke dispatch, channel calls |
config | Configuration get/set, env paths, workbench config |
lifecycle | Startup, shutdown, phases, window events |
storage | Storage get/set/delete, items, optimize |
folder | Folder picker, workspace navigation |
exthost | Extension host: create, start, kill, exit info |
extensions | Extension scanning, activation, management |
terminal | Terminal/PTY: create, sendText, profiles, shell |
search | Search: findFiles, findInFiles |
themes | Theme: list, get active, set |
window | Window: focus, maximize, minimize, fullscreen |
nativehost | OS integration: process, devtools, shell |
clipboard | Clipboard: read/write text, buffer, image |
commands | Command registry: execute, getAll |
model | Text model: open, close, get, updateContent |
output | Output channels: create, append, show |
notification | Notifications: show, progress |
progress | Progress: begin, end, report |
quickinput | Quick input: showQuickPick, showInputBox |
workingcopy | Working copy: dirty state |
workspaces | Workspace: folders, recent, enter |
keybinding | Keybindings: add, remove, lookup |
label | Label service: getBase, getUri |
history | Navigation history: push, goBack, goForward |
decorations | Decorations: get, set, clear |
textfile | Text file operations: read, write, save |
update | Update service: check, download, apply |
encryption | Encryption: encrypt, decrypt |
menubar | Menubar updates |
url | URL handler: registerExternalUriOpener |
grpc | gRPC/Vine: server, client, connections |
cocoon | Cocoon sidecar: spawn, health, handshake |
bootstrap | Effect-TS bootstrap stages |
preload | Preload: globals, polyfills, ipcRenderer |
§Batch 1 diagnostic tags (Row 1-3 fix surfaces)
Narrow tags added to isolate the architectural gaps surfaced by the
analysis table. Enable selectively with e.g.
Trace=notif-drop,git,tree-view to filter to just the
subsystem under investigation.
| Tag | Scope |
|---|---|
notif-drop | Notifications that hit the _ => {} default arm (dropped silently) |
provider-register | Accepted register_*_provider notifications + handle + extension id |
channel-stub | Wind/Output TauriMainProcessService.call stub-hit vs route vs miss |
git | localGit channel, GitExec RPC, SCM provider group updates |
tree-view | tree.register, GetTreeChildren, sky://tree-view/create emit |
§Batch 2 diagnostic tags
| Tag | Scope |
|---|---|
sky-emit | Mountain → Wind/Sky sky:// emits: channel, payload bytes, ok/fail |
config-prime | Configuration cache: manifest pre-populate, subtree synthesise |
ext-activate | Per-extension activate: start, outcome (ok/fail/skip), duration |
breaker | Cocoon MountainClientService circuit-breaker state transitions |
cel-dispatch | SkyBridge cel:* CustomEvent dispatch + consumer-present flag |
§Batch 3 diagnostic tags
Added 2026-04-23 late after Batches 3-6 wired notification handlers,
git channel, tree-view dataProvider forwarding, and medium stub
backfill. These tags catch the subsystems the new traffic passes
through so regressions surface as silent tag counts going to zero
(or, for tauri-invoke, per-invoke latency spikes).
| Tag | Scope |
|---|---|
ext-scan | Extension scanner decisions: is-builtin vs user, skip reasons, counts |
scheme-assets | vscode-file:// / vscode-resource:// request routing, MIME, bytes |
preload-shim | Wind Preload.ts globals wiring, VS Code ipcRenderer polyfill install |
tauri-invoke | Per-invoke method + duration (augments ipc’s paired invoke/done lines) |
bootstrap-stage | Cocoon Effect/Bootstrap.ts stage timings (start/ok/fail per phase) |
§Batch 4 diagnostic tags
Added 2026-04-24 alongside the workspace.fs tier-split refactor.
Cocoon’s WorkspaceNamespace/FileSystemRoute.ts now chooses between
Tier A (node:fs/promises in-process) and Tier C (Mountain FileSystem.*
gRPC) per URI scheme + custom-provider claim. The tag surfaces every
decision so empirical workload profiling confirms the split is paying
off - grep 'route=native' / grep 'route=mountain' buckets per run.
Emitted from Cocoon stdout, picked up by Mountain’s [DEV:COCOON]
stdout tail with the standard [DEV:FS-ROUTE] prefix.
| Tag | Scope |
|---|---|
fs-route | workspace.fs.* + openTextDocument native-vs-mountain routing |
cmd-route | commands.executeCommand local-vs-mountain routing |
dual-track | Mountain-first / Node-fallback progressive Rust migration dispatches |
§dual-track tag usage pattern
Every Cocoon shim that wraps TryMountainThenNode logs one of four
decisions per dispatch:
route=mountainMountain handled it (Rust code path served the call)route=node-fallbackBuild-time manifest says no Mountain handler (or runtime confirmed “Unknown method: X”); Cocoon’s Node / stock-VS-Code implementation served itroute=unavailableTier-4: no tier covers the method. Extension receives typedNotImplementedError; build surfaces this as a feature-gaproute=errorTier failed unexpectedly; error propagated
Grep the stream to see which vscode.* methods Mountain doesn’t yet
cover - that set IS the Rust migration TODO list. A method moves from
node-fallback to mountain automatically the moment Mountain lands
its Rust handler AND the manifest is regenerated. route=unavailable
rows are the apologise-to-user list.
A single [DEV:DUAL-TRACK] manifest mountain=N stockLift=M bespoke=K
line prints at Cocoon boot with the build-time tier coverage
generated by Maintain/Script/GenerateRouteManifest.sh.
Structs§
Constants§
- BENIGN_
ENOENT_ 🔒SUBSTRINGS - SHORT_
MODE_ 🔒MUTED_ TAGS - Tags explicitly muted by
shortmode. These are the per-call firehose tags (receive / dispatch / verify / forward banners) that add no diagnostic signal beyond the aggregate IPC round-trip timing already present in theipc/grpcsummary lines. Listing them here keepsshortusable as a “quiet but informative” default - the failure path for each of these still logs a specific error tag (grpcfor gRPC errors,ipcfor IPC failures, etc.).
Statics§
- APP_
DATA_ 🔒PREFIX - DEBUG_
ONCE_ 🔒KEYS - DEDUP
- ENABLED_
TAGS 🔒 - LOG_
FILE 🔒 - OTLP_
AVAILABLE 🔒 - OTLP_
TRACE_ 🔒ID - SHORT_
MODE 🔒
Functions§
- Alias
Path - Replace the long app-data path with
$APPin a string. - AppData
Prefix - Get the app-data path prefix for aliasing (cached).
- Binary
Signature 🔒 - Produce an identity signature for THIS running binary derived from
CARGO_PKG_NAME(which Maintain sets to the long PascalCase product name beforecargo build). Each profile produces a distinct signature - Debug
Once - Emit the line exactly once per process, keyed on the supplied key. Later calls with the same key are silently dropped. The file sink still captures the very first occurrence so the probe is documented.
- Debug
Once 🔒Keys - Detect
AppData 🔒Prefix - EmitOTLP
Span - Emit an OTLP span to the local collector (Jaeger at 127.0.0.1:4318). Fire-and-forget on a background thread. Stops trying after first failure.
- Enabled
Tags 🔒 - File
Sink 🔒Enabled - Decide whether the file sink should be active. Returns the final flag once per process; subsequent calls are cached.
- Flush
Dedup - Flush the dedup buffer - prints the pending count if > 1.
- Format
Timestamp 🔒 - GetTrace
Id 🔒 - Init
Eager - Force the file sink to initialize before any
dev_log!has run. - Init
File 🔒Sink - Initialise the file sink on first call. Silently falls through to a disabled sink if the directory or file can’t be created - the caller must never panic because of a log-file failure.
- IsBenign
Enoent - Return true when the given path is a known-optional probe whose absence
is never an error condition. Used to downgrade
stat ENOENTspam. - IsEnabled
- Check if a tag is enabled.
- IsShort
- Whether
Trace=shortis active. - NowNano
- Resolve
LogDirectory 🔒 - Resolve the log directory for this session:
~/Library/Application Support/
/logs/ / - Session
Timestamp - Session timestamp in local time, cached once per process. MUST match
whatever
WindServiceHandlers.rs::"nativeHost:getEnvironmentPaths"builds, because VS Code’s file service writeswindow1/output/*.loginto the directory that handler returns - if DevLog and VS Code use different timezones,Mountain.dev.logand thewindow1/subtree land in two sibling directories 2-3 hours apart, which makes every post-mortem investigation start with “which folder has the real log?”. Pickingchrono::Local::now()matches the VS Code convention (Tauri’s tauri-plugin-log also writes local-timeYYYYMMDDTHHMMSS). - Split
Pascal 🔒Case Into Words - Split a PascalCase / UPPERCASE string into lowercase component words,
matching the tokenisation Maintain’s
Build/Process.rsapplies when it stamps the Tauriidentifier. Example:ElectronProfile→["electron", "profile"];22NodeVersion→["22", "node", "version"]. Empty segments are filtered out. - Write
ToFile - Append a single formatted line to the session’s log file if the file sink is active. Swallows every error - dev_log must never crash.
- rand_
u64 🔒