Skip to content

Commit a518cce

Browse files
committed
feat: fall back to extension storage for proxy log directory
When coder.proxyLogDirectory is not configured, use the extension's global storage log path instead of discarding logs. This makes troubleshooting easier without requiring manual configuration.
1 parent 5fc228c commit a518cce

File tree

4 files changed

+45
-55
lines changed

4 files changed

+45
-55
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
"default": ""
103103
},
104104
"coder.proxyLogDirectory": {
105-
"markdownDescription": "If set, the Coder CLI will output extra SSH information into this directory, which can be helpful for debugging connectivity issues.",
105+
"markdownDescription": "Directory where the Coder CLI outputs SSH connection logs for debugging. When not configured, logs are stored in the extension's global storage directory.",
106106
"type": "string",
107107
"default": ""
108108
},

src/commands.ts

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -150,51 +150,33 @@ export class Commands {
150150
return this.openFile(this.workspaceLogPath);
151151
}
152152

153-
const logDir = vscode.workspace
154-
.getConfiguration()
155-
.get<string>("coder.proxyLogDirectory");
156-
if (logDir) {
157-
try {
158-
const files = await fs.readdir(logDir);
159-
// Sort explicitly since fs.readdir order is platform-dependent
160-
const logFiles = files
161-
.filter((f) => f.endsWith(".log"))
162-
.sort((a, b) => a.localeCompare(b))
163-
.reverse();
164-
165-
if (logFiles.length === 0) {
166-
vscode.window.showInformationMessage(
167-
"No log files found in the configured log directory.",
168-
);
169-
return;
170-
}
153+
const logDir = this.pathResolver.getProxyLogPath();
154+
try {
155+
const files = await fs.readdir(logDir);
156+
// Sort explicitly since fs.readdir order is platform-dependent
157+
const logFiles = files
158+
.filter((f) => f.endsWith(".log"))
159+
.sort((a, b) => a.localeCompare(b))
160+
.reverse();
161+
162+
if (logFiles.length === 0) {
163+
vscode.window.showInformationMessage(
164+
"No log files found in the log directory.",
165+
);
166+
return;
167+
}
171168

172-
const selected = await vscode.window.showQuickPick(logFiles, {
173-
title: "Select a log file to view",
174-
});
169+
const selected = await vscode.window.showQuickPick(logFiles, {
170+
title: "Select a log file to view",
171+
});
175172

176-
if (selected) {
177-
await this.openFile(path.join(logDir, selected));
178-
}
179-
} catch (error) {
180-
vscode.window.showErrorMessage(
181-
`Failed to read log directory: ${error instanceof Error ? error.message : String(error)}`,
182-
);
173+
if (selected) {
174+
await this.openFile(path.join(logDir, selected));
183175
}
184-
} else {
185-
vscode.window
186-
.showInformationMessage(
187-
"No logs available. Make sure to set coder.proxyLogDirectory to get logs.",
188-
"Open Settings",
189-
)
190-
.then((action) => {
191-
if (action === "Open Settings") {
192-
vscode.commands.executeCommand(
193-
"workbench.action.openSettings",
194-
"coder.proxyLogDirectory",
195-
);
196-
}
197-
});
176+
} catch (error) {
177+
vscode.window.showErrorMessage(
178+
`Failed to read log directory: ${error instanceof Error ? error.message : String(error)}`,
179+
);
198180
}
199181
}
200182

src/core/pathResolver.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as path from "node:path";
22
import * as vscode from "vscode";
33

4+
import { expandPath } from "../util";
5+
46
export class PathResolver {
57
constructor(
68
private readonly basePath: string,
@@ -51,16 +53,28 @@ export class PathResolver {
5153
}
5254

5355
/**
54-
* Return the path where log data from the connection is stored.
56+
* Return the default path where log data from the connection is stored.
5557
*
5658
* The CLI will write files here named after the process PID.
57-
*
58-
* Note: This directory is not currently used.
5959
*/
6060
public getLogPath(): string {
6161
return path.join(this.basePath, "log");
6262
}
6363

64+
/**
65+
* Return the proxy log directory from user settings, falling back to the
66+
* default log path in extension storage.
67+
*/
68+
public getProxyLogPath(): string {
69+
const configured = expandPath(
70+
String(
71+
vscode.workspace.getConfiguration().get("coder.proxyLogDirectory") ??
72+
"",
73+
).trim(),
74+
);
75+
return configured || this.getLogPath();
76+
}
77+
6478
/**
6579
* Get the path to the user's settings.json file.
6680
*

src/remote/remote.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import { OAuthSessionManager } from "../oauth/sessionManager";
4646
import {
4747
AuthorityPrefix,
4848
escapeCommandArg,
49-
expandPath,
5049
parseRemoteAuthority,
5150
} from "../util";
5251
import { vscodeProposed } from "../vscodeProposed";
@@ -717,21 +716,16 @@ export class Remote {
717716

718717
/**
719718
* Return the --log-dir argument value for the ProxyCommand. It may be an
720-
* empty string if the setting is not set or the cli does not support it.
719+
* empty string if the CLI does not support it. Falls back to extension
720+
* storage when the user setting is not configured.
721721
*
722722
* Value defined in the "coder.sshFlags" setting is not considered.
723723
*/
724724
private getLogDir(featureSet: FeatureSet): string {
725725
if (!featureSet.proxyLogDirectory) {
726726
return "";
727727
}
728-
// If the proxyLogDirectory is not set in the extension settings we don't send one.
729-
return expandPath(
730-
String(
731-
vscode.workspace.getConfiguration().get("coder.proxyLogDirectory") ??
732-
"",
733-
).trim(),
734-
);
728+
return this.pathResolver.getProxyLogPath();
735729
}
736730

737731
/**

0 commit comments

Comments
 (0)