feat: include VS Code-side logs in support bundle#916
Merged
Conversation
ea2913c to
4ffc75c
Compare
After the CLI generates the support bundle zip, append logs from three sources under a vscode-logs/ directory: - Remote SSH extension log (from SshProcessMonitor) - SSH proxy logs (from PathResolver.getProxyLogPath()) - Extension output channel logs (from PathResolver.getCodeLogDir()) Each source is collected independently and failures are warned and skipped. If zip manipulation fails the original file is left as-is. Writes to a `-vscode.zip` temp file first, then uses renameWithRetry to atomically replace the original. If rename fails the user still has the temp file with a descriptive name. Uses fflate (zero-dep, 8kB, tree-shakeable) to read/modify/write the zip. Bundle size impact: +753 bytes (dev), negligible in production. Closes #889
4ffc75c to
f1b1f6b
Compare
Parse the date embedded in coder-ssh-YYYYMMDD-HHMMSS-<nonce>.log filenames instead of using fs.stat. Only proxy logs are filtered; extension logs are included unconditionally.
Replace filename-based timestamp parsing with stat mtime, consistent with the cleanup logic in sshProcess.ts. The stat call is already made to skip subdirectories, so this adds zero extra cost.
- Switch fflate to async `unzip`/`zip` via `util.promisify`
- Return `Map<string, Uint8Array>` instead of `Record<>`
- Drop `zipPrefix` param; caller attaches the prefix
- Apply the 3-day mtime filter to extension logs too (was proxy-only)
- Unexport `collectLogFiles`; inline `vscodeBundlePath`
- Parallelize stat+read inside `collectDirFiles`
- Pass raw errors to `logger.warn`/`logger.error` (drop `toError().message`)
- On merge failure, clean up the `-vscode.zip` sibling via
`fs.rm({ force: true })` wrapped in try/catch so non-ENOENT errors are
surfaced rather than masked
- Reference the `-vscode.zip` path in the rename-failure warning so the
user can still find the bundle
Tests: fold collectLogFiles into appendVsCodeLogs, mtime-based
"not touched" assertions, rename-failure + extension-log-age tests,
gate chmod 0o000 to POSIX non-root, assert sibling cleanup on corrupt input.
2009205 to
5624bbf
Compare
mtojek
reviewed
Apr 23, 2026
Member
mtojek
left a comment
There was a problem hiding this comment.
Is it worth adding another zip test with 50+ files?
- Wrap appendVsCodeLogs body in a top-level try/catch so any unexpected failure cannot lose the original support bundle. - Document why LOG_MAX_AGE_MS is 3 days (not the 7-day rotation). - Strengthen unchanged-bundle assertions with Buffer.compare alongside mtime, since mtime alone can be unreliable across filesystems. - Add a stress test covering 60 files across two source directories.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
After the CLI generates the support bundle zip, this appends logs from three VS Code-side sources under a
vscode-logs/directory:SshProcessMonitor.getLogFilePath()PathResolver.getProxyLogPath(), filtered to the last 3 days by mtimePathResolver.getCodeLogDir(), filtered to the last 3 days by mtimeEach source is collected independently. If a source is unavailable or a file cannot be read, it is warned and skipped. If the zip read/merge/write fails, the original bundle is left untouched and any partial sibling is cleaned up. If the atomic rename step fails, the merged zip is left alongside the original as
<name>-vscode.zipand that path is surfaced in a warning log so the user can still find their bundle.Uses fflate (zero dependencies, 8kB minified, tree-shakeable) via its async
zip/unzipcallbacks wrapped withnode:util.promisify. Memory is bounded by on-disk rotation: VS Code rotates extension logs per session, andSshProcessMonitorcaps proxy logs at 20 files / 7 days, so the in-memory peak stays small.Files changed
package.json/pnpm-lock.yamlfflatedependencysrc/core/supportBundleLogs.tssrc/commands.tsappendVsCodeLogsafter CLI produces the bundletest/unit/core/supportBundleLogs.test.tsCloses #889