Content-Length: 27093 | pFad | http://github.com/coder/vscode-coder/pull/553.diff
thub.com
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8725a127..80371d86 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@
and configFile are provided.
- Add `coder.disableUpdateNotifications` setting to disable workspace template
update notifications.
+- Coder output panel enhancements: All log entries now include timestamps, and you
+ can filter messages by log level in the panel.
## [v1.9.2](https://github.com/coder/vscode-coder/releases/tag/v1.9.2) 2025-06-25
diff --git a/src/api.ts b/src/api.ts
index 22de2618..96b49673 100644
--- a/src/api.ts
+++ b/src/api.ts
@@ -105,7 +105,7 @@ export function makeCoderSdk(
restClient.getAxiosInstance().interceptors.response.use(
(r) => r,
async (err) => {
- throw await CertificateError.maybeWrap(err, baseUrl, storage);
+ throw await CertificateError.maybeWrap(err, baseUrl, storage.output);
},
);
diff --git a/src/commands.ts b/src/commands.ts
index d6734376..4373228c 100644
--- a/src/commands.ts
+++ b/src/commands.ts
@@ -245,8 +245,9 @@ export class Commands {
} catch (err) {
const message = getErrorMessage(err, "no response from the server");
if (isAutologin) {
- this.storage.writeToCoderOutputChannel(
- `Failed to log in to Coder server: ${message}`,
+ this.storage.output.warn(
+ "Failed to log in to Coder server:",
+ message,
);
} else {
this.vscodeProposed.window.showErrorMessage(
diff --git a/src/error.test.ts b/src/error.test.ts
index 3c4a50c3..4bbb9395 100644
--- a/src/error.test.ts
+++ b/src/error.test.ts
@@ -4,6 +4,7 @@ import https from "https";
import * as path from "path";
import { afterAll, beforeAll, it, expect, vi } from "vitest";
import { CertificateError, X509_ERR, X509_ERR_CODE } from "./error";
+import { Logger } from "./logger";
// Before each test we make a request to sanity check that we really get the
// error we are expecting, then we run it through CertificateError.
@@ -23,10 +24,16 @@ beforeAll(() => {
});
});
-const logger = {
- writeToCoderOutputChannel(message: string) {
- throw new Error(message);
- },
+const throwingLog = (message: string) => {
+ throw new Error(message);
+};
+
+const logger: Logger = {
+ trace: throwingLog,
+ debug: throwingLog,
+ info: throwingLog,
+ warn: throwingLog,
+ error: throwingLog,
};
const disposers: (() => void)[] = [];
diff --git a/src/error.ts b/src/error.ts
index 53cc3389..5fa07294 100644
--- a/src/error.ts
+++ b/src/error.ts
@@ -3,6 +3,7 @@ import { isApiError, isApiErrorResponse } from "coder/site/src/api/errors";
import * as forge from "node-forge";
import * as tls from "tls";
import * as vscode from "vscode";
+import { Logger } from "./logger";
// X509_ERR_CODE represents error codes as returned from BoringSSL/OpenSSL.
export enum X509_ERR_CODE {
@@ -21,10 +22,6 @@ export enum X509_ERR {
UNTRUSTED_CHAIN = "Your Coder deployment's certificate chain does not appear to be trusted by this system. The root of the certificate chain must be added to this system's trust store. ",
}
-export interface Logger {
- writeToCoderOutputChannel(message: string): void;
-}
-
interface KeyUsage {
keyCertSign: boolean;
}
@@ -59,9 +56,7 @@ export class CertificateError extends Error {
await CertificateError.determineVerifyErrorCause(address);
return new CertificateError(err.message, cause);
} catch (error) {
- logger.writeToCoderOutputChannel(
- `Failed to parse certificate from ${address}: ${error}`,
- );
+ logger.warn(`Failed to parse certificate from ${address}`, error);
break;
}
case X509_ERR_CODE.DEPTH_ZERO_SELF_SIGNED_CERT:
diff --git a/src/extension.ts b/src/extension.ts
index 05eb7319..96f110c5 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -47,7 +47,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
);
}
- const output = vscode.window.createOutputChannel("Coder");
+ const output = vscode.window.createOutputChannel("Coder", { log: true });
const storage = new Storage(
output,
ctx.globalState,
@@ -317,7 +317,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
}
} catch (ex) {
if (ex instanceof CertificateError) {
- storage.writeToCoderOutputChannel(ex.x509Err || ex.message);
+ storage.output.warn(ex.x509Err || ex.message);
await ex.showModal("Failed to open workspace");
} else if (isAxiosError(ex)) {
const msg = getErrorMessage(ex, "None");
@@ -326,7 +326,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
const method = ex.config?.method?.toUpperCase() || "request";
const status = ex.response?.status || "None";
const message = `API ${method} to '${urlString}' failed.\nStatus code: ${status}\nMessage: ${msg}\nDetail: ${detail}`;
- storage.writeToCoderOutputChannel(message);
+ storage.output.warn(message);
await vscodeProposed.window.showErrorMessage(
"Failed to open workspace",
{
@@ -337,7 +337,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
);
} else {
const message = errToStr(ex, "No error message was provided");
- storage.writeToCoderOutputChannel(message);
+ storage.output.warn(message);
await vscodeProposed.window.showErrorMessage(
"Failed to open workspace",
{
@@ -356,14 +356,12 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
// See if the plugin client is authenticated.
const baseUrl = restClient.getAxiosInstance().defaults.baseURL;
if (baseUrl) {
- storage.writeToCoderOutputChannel(
- `Logged in to ${baseUrl}; checking credentials`,
- );
+ storage.output.info(`Logged in to ${baseUrl}; checking credentials`);
restClient
.getAuthenticatedUser()
.then(async (user) => {
if (user && user.roles) {
- storage.writeToCoderOutputChannel("Credentials are valid");
+ storage.output.info("Credentials are valid");
vscode.commands.executeCommand(
"setContext",
"coder.authenticated",
@@ -381,17 +379,13 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
myWorkspacesProvider.fetchAndRefresh();
allWorkspacesProvider.fetchAndRefresh();
} else {
- storage.writeToCoderOutputChannel(
- `No error, but got unexpected response: ${user}`,
- );
+ storage.output.warn("No error, but got unexpected response", user);
}
})
.catch((error) => {
// This should be a failure to make the request, like the header command
// errored.
- storage.writeToCoderOutputChannel(
- `Failed to check user authentication: ${error.message}`,
- );
+ storage.output.warn("Failed to check user authentication", error);
vscode.window.showErrorMessage(
`Failed to check user authentication: ${error.message}`,
);
@@ -400,7 +394,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
vscode.commands.executeCommand("setContext", "coder.loaded", true);
});
} else {
- storage.writeToCoderOutputChannel("Not currently logged in");
+ storage.output.info("Not currently logged in");
vscode.commands.executeCommand("setContext", "coder.loaded", true);
// Handle autologin, if not already logged in.
diff --git a/src/headers.test.ts b/src/headers.test.ts
index 5cf333f5..669a8d74 100644
--- a/src/headers.test.ts
+++ b/src/headers.test.ts
@@ -2,11 +2,14 @@ import * as os from "os";
import { it, expect, describe, beforeEach, afterEach, vi } from "vitest";
import { WorkspaceConfiguration } from "vscode";
import { getHeaderCommand, getHeaders } from "./headers";
-
-const logger = {
- writeToCoderOutputChannel() {
- // no-op
- },
+import { Logger } from "./logger";
+
+const logger: Logger = {
+ trace: () => {},
+ debug: () => {},
+ info: () => {},
+ warn: () => {},
+ error: () => {},
};
it("should return no headers", async () => {
diff --git a/src/headers.ts b/src/headers.ts
index 4d4b5f44..e61bfa81 100644
--- a/src/headers.ts
+++ b/src/headers.ts
@@ -2,12 +2,9 @@ import * as cp from "child_process";
import * as os from "os";
import * as util from "util";
import type { WorkspaceConfiguration } from "vscode";
+import { Logger } from "./logger";
import { escapeCommandArg } from "./util";
-export interface Logger {
- writeToCoderOutputChannel(message: string): void;
-}
-
interface ExecException {
code?: number;
stderr?: string;
@@ -78,11 +75,9 @@ export async function getHeaders(
});
} catch (error) {
if (isExecException(error)) {
- logger.writeToCoderOutputChannel(
- `Header command exited unexpectedly with code ${error.code}`,
- );
- logger.writeToCoderOutputChannel(`stdout: ${error.stdout}`);
- logger.writeToCoderOutputChannel(`stderr: ${error.stderr}`);
+ logger.warn("Header command exited unexpectedly with code", error.code);
+ logger.warn("stdout:", error.stdout);
+ logger.warn("stderr:", error.stderr);
throw new Error(
`Header command exited unexpectedly with code ${error.code}`,
);
diff --git a/src/inbox.ts b/src/inbox.ts
index 709dfbd8..0ec79720 100644
--- a/src/inbox.ts
+++ b/src/inbox.ts
@@ -63,7 +63,7 @@ export class Inbox implements vscode.Disposable {
});
this.#socket.on("open", () => {
- this.#storage.writeToCoderOutputChannel("Listening to Coder Inbox");
+ this.#storage.output.info("Listening to Coder Inbox");
});
this.#socket.on("error", (error) => {
@@ -86,9 +86,7 @@ export class Inbox implements vscode.Disposable {
dispose() {
if (!this.#disposed) {
- this.#storage.writeToCoderOutputChannel(
- "No longer listening to Coder Inbox",
- );
+ this.#storage.output.info("No longer listening to Coder Inbox");
this.#socket.close();
this.#disposed = true;
}
@@ -99,6 +97,6 @@ export class Inbox implements vscode.Disposable {
error,
"Got empty error while monitoring Coder Inbox",
);
- this.#storage.writeToCoderOutputChannel(message);
+ this.#storage.output.error(message);
}
}
diff --git a/src/logger.ts b/src/logger.ts
new file mode 100644
index 00000000..30bf0ec6
--- /dev/null
+++ b/src/logger.ts
@@ -0,0 +1,7 @@
+export interface Logger {
+ trace(message: string, ...args: unknown[]): void;
+ debug(message: string, ...args: unknown[]): void;
+ info(message: string, ...args: unknown[]): void;
+ warn(message: string, ...args: unknown[]): void;
+ error(message: string, ...args: unknown[]): void;
+}
diff --git a/src/remote.ts b/src/remote.ts
index 6397ba08..2d80a55b 100644
--- a/src/remote.ts
+++ b/src/remote.ts
@@ -117,9 +117,7 @@ export class Remote {
case "starting":
case "stopping":
writeEmitter = initWriteEmitterAndTerminal();
- this.storage.writeToCoderOutputChannel(
- `Waiting for ${workspaceName}...`,
- );
+ this.storage.output.info(`Waiting for ${workspaceName}...`);
workspace = await waitForBuild(
restClient,
writeEmitter,
@@ -131,9 +129,7 @@ export class Remote {
return undefined;
}
writeEmitter = initWriteEmitterAndTerminal();
- this.storage.writeToCoderOutputChannel(
- `Starting ${workspaceName}...`,
- );
+ this.storage.output.info(`Starting ${workspaceName}...`);
workspace = await startWorkspaceIfStoppedOrFailed(
restClient,
globalConfigDir,
@@ -150,9 +146,7 @@ export class Remote {
return undefined;
}
writeEmitter = initWriteEmitterAndTerminal();
- this.storage.writeToCoderOutputChannel(
- `Starting ${workspaceName}...`,
- );
+ this.storage.output.info(`Starting ${workspaceName}...`);
workspace = await startWorkspaceIfStoppedOrFailed(
restClient,
globalConfigDir,
@@ -175,8 +169,9 @@ export class Remote {
);
}
}
- this.storage.writeToCoderOutputChannel(
- `${workspaceName} status is now ${workspace.latest_build.status}`,
+ this.storage.output.info(
+ `${workspaceName} status is now`,
+ workspace.latest_build.status,
);
}
return workspace;
@@ -243,12 +238,8 @@ export class Remote {
return;
}
- this.storage.writeToCoderOutputChannel(
- `Using deployment URL: ${baseUrlRaw}`,
- );
- this.storage.writeToCoderOutputChannel(
- `Using deployment label: ${parts.label || "n/a"}`,
- );
+ this.storage.output.info("Using deployment URL", baseUrlRaw);
+ this.storage.output.info("Using deployment label", parts.label || "n/a");
// We could use the plugin client, but it is possible for the user to log
// out or log into a different deployment while still connected, which would
@@ -314,15 +305,14 @@ export class Remote {
// Next is to find the workspace from the URI scheme provided.
let workspace: Workspace;
try {
- this.storage.writeToCoderOutputChannel(
- `Looking for workspace ${workspaceName}...`,
- );
+ this.storage.output.info(`Looking for workspace ${workspaceName}...`);
workspace = await workspaceRestClient.getWorkspaceByOwnerAndName(
parts.username,
parts.workspace,
);
- this.storage.writeToCoderOutputChannel(
- `Found workspace ${workspaceName} with status ${workspace.latest_build.status}`,
+ this.storage.output.info(
+ `Found workspace ${workspaceName} with status`,
+ workspace.latest_build.status,
);
this.commands.workspace = workspace;
} catch (error) {
@@ -404,9 +394,7 @@ export class Remote {
this.commands.workspace = workspace;
// Pick an agent.
- this.storage.writeToCoderOutputChannel(
- `Finding agent for ${workspaceName}...`,
- );
+ this.storage.output.info(`Finding agent for ${workspaceName}...`);
const gotAgent = await this.commands.maybeAskAgent(workspace, parts.agent);
if (!gotAgent) {
// User declined to pick an agent.
@@ -414,12 +402,13 @@ export class Remote {
return;
}
let agent = gotAgent; // Reassign so it cannot be undefined in callbacks.
- this.storage.writeToCoderOutputChannel(
- `Found agent ${agent.name} with status ${agent.status}`,
+ this.storage.output.info(
+ `Found agent ${agent.name} with status`,
+ agent.status,
);
// Do some janky setting manipulation.
- this.storage.writeToCoderOutputChannel("Modifying settings...");
+ this.storage.output.info("Modifying settings...");
const remotePlatforms = this.vscodeProposed.workspace
.getConfiguration()
.get>("remote.SSH.remotePlatform", {});
@@ -491,9 +480,7 @@ export class Remote {
// write here is not necessarily catastrophic since the user will be
// asked for the platform and the default timeout might be sufficient.
mungedPlatforms = mungedConnTimeout = false;
- this.storage.writeToCoderOutputChannel(
- `Failed to configure settings: ${ex}`,
- );
+ this.storage.output.warn("Failed to configure settings", ex);
}
}
@@ -521,9 +508,7 @@ export class Remote {
// Wait for the agent to connect.
if (agent.status === "connecting") {
- this.storage.writeToCoderOutputChannel(
- `Waiting for ${workspaceName}/${agent.name}...`,
- );
+ this.storage.output.info(`Waiting for ${workspaceName}/${agent.name}...`);
await vscode.window.withProgress(
{
title: "Waiting for the agent to connect...",
@@ -552,8 +537,9 @@ export class Remote {
});
},
);
- this.storage.writeToCoderOutputChannel(
- `Agent ${agent.name} status is now ${agent.status}`,
+ this.storage.output.info(
+ `Agent ${agent.name} status is now`,
+ agent.status,
);
}
@@ -584,7 +570,7 @@ export class Remote {
// If we didn't write to the SSH config file, connecting would fail with
// "Host not found".
try {
- this.storage.writeToCoderOutputChannel("Updating SSH config...");
+ this.storage.output.info("Updating SSH config...");
await this.updateSSHConfig(
workspaceRestClient,
parts.label,
@@ -594,9 +580,7 @@ export class Remote {
featureSet,
);
} catch (error) {
- this.storage.writeToCoderOutputChannel(
- `Failed to configure SSH: ${error}`,
- );
+ this.storage.output.warn("Failed to configure SSH", error);
throw error;
}
@@ -636,7 +620,7 @@ export class Remote {
}),
);
- this.storage.writeToCoderOutputChannel("Remote setup complete");
+ this.storage.output.info("Remote setup complete");
// Returning the URL and token allows the plugin to authenticate its own
// client, for example to display the list of workspaces belonging to this
@@ -677,8 +661,9 @@ export class Remote {
return "";
}
await fs.mkdir(logDir, { recursive: true });
- this.storage.writeToCoderOutputChannel(
- `SSH proxy diagnostics are being written to ${logDir}`,
+ this.storage.output.info(
+ "SSH proxy diagnostics are being written to",
+ logDir,
);
return ` --log-dir ${escapeCommandArg(logDir)}`;
}
diff --git a/src/storage.ts b/src/storage.ts
index 8453bc5d..206dbce3 100644
--- a/src/storage.ts
+++ b/src/storage.ts
@@ -14,7 +14,7 @@ const MAX_URLS = 10;
export class Storage {
constructor(
- private readonly output: vscode.OutputChannel,
+ public readonly output: vscode.LogOutputChannel,
private readonly memento: vscode.Memento,
private readonly secrets: vscode.SecretStorage,
private readonly globalStorageUri: vscode.Uri,
@@ -129,57 +129,50 @@ export class Storage {
const enableDownloads =
vscode.workspace.getConfiguration().get("coder.enableDownloads") !==
false;
- this.output.appendLine(
- `Downloads are ${enableDownloads ? "enabled" : "disabled"}`,
- );
+ this.output.info("Downloads are", enableDownloads ? "enabled" : "disabled");
// Get the build info to compare with the existing binary version, if any,
// and to log for debugging.
const buildInfo = await restClient.getBuildInfo();
- this.output.appendLine(`Got server version: ${buildInfo.version}`);
+ this.output.info("Got server version", buildInfo.version);
// Check if there is an existing binary and whether it looks valid. If it
// is valid and matches the server, or if it does not match the server but
// downloads are disabled, we can return early.
const binPath = path.join(this.getBinaryCachePath(label), cli.name());
- this.output.appendLine(`Using binary path: ${binPath}`);
+ this.output.info("Using binary path", binPath);
const stat = await cli.stat(binPath);
if (stat === undefined) {
- this.output.appendLine("No existing binary found, starting download");
+ this.output.info("No existing binary found, starting download");
} else {
- this.output.appendLine(
- `Existing binary size is ${prettyBytes(stat.size)}`,
- );
+ this.output.info("Existing binary size is", prettyBytes(stat.size));
try {
const version = await cli.version(binPath);
- this.output.appendLine(`Existing binary version is ${version}`);
+ this.output.info("Existing binary version is", version);
// If we have the right version we can avoid the request entirely.
if (version === buildInfo.version) {
- this.output.appendLine(
+ this.output.info(
"Using existing binary since it matches the server version",
);
return binPath;
} else if (!enableDownloads) {
- this.output.appendLine(
+ this.output.info(
"Using existing binary even though it does not match the server version because downloads are disabled",
);
return binPath;
}
- this.output.appendLine(
+ this.output.info(
"Downloading since existing binary does not match the server version",
);
} catch (error) {
- this.output.appendLine(
- `Unable to get version of existing binary: ${error}`,
+ this.output.warn(
+ `Unable to get version of existing binary: ${error}. Downloading new binary instead`,
);
- this.output.appendLine("Downloading new binary instead");
}
}
if (!enableDownloads) {
- this.output.appendLine(
- "Unable to download CLI because downloads are disabled",
- );
+ this.output.warn("Unable to download CLI because downloads are disabled");
throw new Error("Unable to download CLI because downloads are disabled");
}
@@ -187,9 +180,9 @@ export class Storage {
const removed = await cli.rmOld(binPath);
removed.forEach(({ fileName, error }) => {
if (error) {
- this.output.appendLine(`Failed to remove ${fileName}: ${error}`);
+ this.output.warn("Failed to remove", fileName, error);
} else {
- this.output.appendLine(`Removed ${fileName}`);
+ this.output.info("Removed", fileName);
}
});
@@ -202,12 +195,12 @@ export class Storage {
configSource && String(configSource).trim().length > 0
? String(configSource)
: "/bin/" + binName;
- this.output.appendLine(`Downloading binary from: ${binSource}`);
+ this.output.info("Downloading binary from", binSource);
// Ideally we already caught that this was the right version and returned
// early, but just in case set the ETag.
const etag = stat !== undefined ? await cli.eTag(binPath) : "";
- this.output.appendLine(`Using ETag: ${etag}`);
+ this.output.info("Using ETag", etag);
// Make the download request.
const controller = new AbortController();
@@ -223,20 +216,19 @@ export class Storage {
// Ignore all errors so we can catch a 404!
validateStatus: () => true,
});
- this.output.appendLine(`Got status code ${resp.status}`);
+ this.output.info("Got status code", resp.status);
switch (resp.status) {
case 200: {
const rawContentLength = resp.headers["content-length"];
const contentLength = Number.parseInt(rawContentLength);
if (Number.isNaN(contentLength)) {
- this.output.appendLine(
- `Got invalid or missing content length: ${rawContentLength}`,
+ this.output.warn(
+ "Got invalid or missing content length",
+ rawContentLength,
);
} else {
- this.output.appendLine(
- `Got content length: ${prettyBytes(contentLength)}`,
- );
+ this.output.info("Got content length", prettyBytes(contentLength));
}
// Download to a temporary file.
@@ -317,12 +309,13 @@ export class Storage {
// False means the user canceled, although in practice it appears we
// would not get this far because VS Code already throws on cancelation.
if (!completed) {
- this.output.appendLine("User aborted download");
+ this.output.warn("User aborted download");
throw new Error("User aborted download");
}
- this.output.appendLine(
- `Downloaded ${prettyBytes(written)} to ${path.basename(tempFile)}`,
+ this.output.info(
+ `Downloaded ${prettyBytes(written)} to`,
+ path.basename(tempFile),
);
// Move the old binary to a backup location first, just in case. And,
@@ -331,35 +324,33 @@ export class Storage {
if (stat !== undefined) {
const oldBinPath =
binPath + ".old-" + Math.random().toString(36).substring(8);
- this.output.appendLine(
- `Moving existing binary to ${path.basename(oldBinPath)}`,
+ this.output.info(
+ "Moving existing binary to",
+ path.basename(oldBinPath),
);
await fs.rename(binPath, oldBinPath);
}
// Then move the temporary binary into the right place.
- this.output.appendLine(
- `Moving downloaded file to ${path.basename(binPath)}`,
- );
+ this.output.info("Moving downloaded file to", path.basename(binPath));
await fs.mkdir(path.dirname(binPath), { recursive: true });
await fs.rename(tempFile, binPath);
// For debugging, to see if the binary only partially downloaded.
const newStat = await cli.stat(binPath);
- this.output.appendLine(
- `Downloaded binary size is ${prettyBytes(newStat?.size || 0)}`,
+ this.output.info(
+ "Downloaded binary size is",
+ prettyBytes(newStat?.size || 0),
);
// Make sure we can execute this new binary.
const version = await cli.version(binPath);
- this.output.appendLine(`Downloaded binary version is ${version}`);
+ this.output.info("Downloaded binary version is", version);
return binPath;
}
case 304: {
- this.output.appendLine(
- "Using existing binary since server returned a 304",
- );
+ this.output.info("Using existing binary since server returned a 304");
return binPath;
}
case 404: {
@@ -507,14 +498,6 @@ export class Storage {
: path.join(this.globalStorageUri.fsPath, "url");
}
- public writeToCoderOutputChannel(message: string) {
- this.output.appendLine(`[${new Date().toISOString()}] ${message}`);
- // We don't want to focus on the output here, because the
- // Coder server is designed to restart gracefully for users
- // because of P2P connections, and we don't want to draw
- // attention to it.
- }
-
/**
* Configure the CLI for the deployment with the provided label.
*
@@ -614,7 +597,7 @@ export class Storage {
return getHeaders(
url,
getHeaderCommand(vscode.workspace.getConfiguration()),
- this,
+ this.output,
);
}
}
diff --git a/src/workspaceMonitor.ts b/src/workspaceMonitor.ts
index 189d444a..d1eaf704 100644
--- a/src/workspaceMonitor.ts
+++ b/src/workspaceMonitor.ts
@@ -42,7 +42,7 @@ export class WorkspaceMonitor implements vscode.Disposable {
this.name = `${workspace.owner_name}/${workspace.name}`;
const url = this.restClient.getAxiosInstance().defaults.baseURL;
const watchUrl = new URL(`${url}/api/v2/workspaces/${workspace.id}/watch`);
- this.storage.writeToCoderOutputChannel(`Monitoring ${this.name}...`);
+ this.storage.output.info(`Monitoring ${this.name}...`);
const eventSource = new EventSource(watchUrl.toString(), {
fetch: createStreamingFetchAdapter(this.restClient.getAxiosInstance()),
@@ -85,7 +85,7 @@ export class WorkspaceMonitor implements vscode.Disposable {
*/
dispose() {
if (!this.disposed) {
- this.storage.writeToCoderOutputChannel(`Unmonitoring ${this.name}...`);
+ this.storage.output.info(`Unmonitoring ${this.name}...`);
this.statusBarItem.dispose();
this.eventSource.close();
this.disposed = true;
@@ -211,7 +211,7 @@ export class WorkspaceMonitor implements vscode.Disposable {
error,
"Got empty error while monitoring workspace",
);
- this.storage.writeToCoderOutputChannel(message);
+ this.storage.output.error(message);
}
private updateContext(workspace: Workspace) {
diff --git a/src/workspacesProvider.ts b/src/workspacesProvider.ts
index a77b31ad..64b74e7d 100644
--- a/src/workspacesProvider.ts
+++ b/src/workspacesProvider.ts
@@ -96,7 +96,7 @@ export class WorkspaceProvider
*/
private async fetch(): Promise {
if (vscode.env.logLevel <= vscode.LogLevel.Debug) {
- this.storage.writeToCoderOutputChannel(
+ this.storage.output.info(
`Fetching workspaces: ${this.getWorkspacesQuery || "no filter"}...`,
);
}
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/coder/vscode-coder/pull/553.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy