aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
authorVeetaha <[email protected]>2020-07-05 15:42:52 +0100
committerVeetaha <[email protected]>2020-07-05 15:50:29 +0100
commit3602f07bbee5b13dcd799cbc79381e9428808048 (patch)
tree6ab6a643f8ae0d4486b4078c757f8a31a93d0111 /editors
parent8b0983e89ad9a28b142eccf3755a8c9aaeb37852 (diff)
Improve client logging (use output channel and more log levels)
Diffstat (limited to 'editors')
-rw-r--r--editors/code/src/config.ts8
-rw-r--r--editors/code/src/main.ts6
-rw-r--r--editors/code/src/persistent_state.ts2
-rw-r--r--editors/code/src/util.ts51
4 files changed, 49 insertions, 18 deletions
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 23975c726..033b04b60 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -39,10 +39,10 @@ export class Config {
39 39
40 private refreshLogging() { 40 private refreshLogging() {
41 log.setEnabled(this.traceExtension); 41 log.setEnabled(this.traceExtension);
42 log.debug( 42 log.info("Extension version:", this.package.version);
43 "Extension version:", this.package.version, 43
44 "using configuration:", this.cfg 44 const cfg = Object.entries(this.cfg).filter(([_, val]) => !(val instanceof Function));
45 ); 45 log.info("Using configuration", Object.fromEntries(cfg));
46 } 46 }
47 47
48 private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) { 48 private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) {
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index a1521a93b..5877be8b2 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -59,8 +59,8 @@ async function tryActivate(context: vscode.ExtensionContext) {
59 message += "you should close them and reload this window to retry. "; 59 message += "you should close them and reload this window to retry. ";
60 } 60 }
61 61
62 message += 'Open "Help > Toggle Developer Tools > Console" to see the logs '; 62 message += 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). ';
63 message += '(enable verbose logs with "rust-analyzer.trace.extension")'; 63 message += 'To enable verbose logs use { "rust-analyzer.trace.extension": true }';
64 64
65 log.error("Bootstrap error", err); 65 log.error("Bootstrap error", err);
66 throw new Error(message); 66 throw new Error(message);
@@ -214,7 +214,7 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise<
214 ); 214 );
215 } 215 }
216 216
217 log.debug("Using server binary at", path); 217 log.info("Using server binary at", path);
218 218
219 if (!isValidExecutable(path)) { 219 if (!isValidExecutable(path)) {
220 throw new Error(`Failed to execute ${path} --version`); 220 throw new Error(`Failed to execute ${path} --version`);
diff --git a/editors/code/src/persistent_state.ts b/editors/code/src/persistent_state.ts
index 138d11b89..5705eed81 100644
--- a/editors/code/src/persistent_state.ts
+++ b/editors/code/src/persistent_state.ts
@@ -4,7 +4,7 @@ import { log } from './util';
4export class PersistentState { 4export class PersistentState {
5 constructor(private readonly globalState: vscode.Memento) { 5 constructor(private readonly globalState: vscode.Memento) {
6 const { lastCheck, releaseId, serverVersion } = this; 6 const { lastCheck, releaseId, serverVersion } = this;
7 log.debug("PersistentState: ", { lastCheck, releaseId, serverVersion }); 7 log.info("PersistentState:", { lastCheck, releaseId, serverVersion });
8 } 8 }
9 9
10 /** 10 /**
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index fec4c3295..78fe6f5da 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,7 +1,9 @@
1import * as lc from "vscode-languageclient"; 1import * as lc from "vscode-languageclient";
2import * as fs from "fs";
2import * as vscode from "vscode"; 3import * as vscode from "vscode";
3import { strict as nativeAssert } from "assert"; 4import { strict as nativeAssert } from "assert";
4import { spawnSync } from "child_process"; 5import { spawnSync } from "child_process";
6import { inspect } from "util";
5 7
6export function assert(condition: boolean, explanation: string): asserts condition { 8export function assert(condition: boolean, explanation: string): asserts condition {
7 try { 9 try {
@@ -14,21 +16,46 @@ export function assert(condition: boolean, explanation: string): asserts conditi
14 16
15export const log = new class { 17export const log = new class {
16 private enabled = true; 18 private enabled = true;
19 private readonly output = vscode.window.createOutputChannel("Rust Analyzer Client");
17 20
18 setEnabled(yes: boolean): void { 21 setEnabled(yes: boolean): void {
19 log.enabled = yes; 22 log.enabled = yes;
20 } 23 }
21 24
22 debug(message?: any, ...optionalParams: any[]): void { 25 // Hint: the type [T, ...T[]] means a non-empty array
26 debug(...msg: [unknown, ...unknown[]]): void {
23 if (!log.enabled) return; 27 if (!log.enabled) return;
24 // eslint-disable-next-line no-console 28 log.write("DEBUG", ...msg);
25 console.log(message, ...optionalParams); 29 log.output.toString();
26 } 30 }
27 31
28 error(message?: any, ...optionalParams: any[]): void { 32 info(...msg: [unknown, ...unknown[]]): void {
33 log.write("INFO", ...msg);
34 }
35
36 warn(...msg: [unknown, ...unknown[]]): void {
37 debugger;
38 log.write("WARN", ...msg);
39 }
40
41 error(...msg: [unknown, ...unknown[]]): void {
29 debugger; 42 debugger;
30 // eslint-disable-next-line no-console 43 log.write("ERROR", ...msg);
31 console.error(message, ...optionalParams); 44 log.output.show(true);
45 }
46
47 private write(label: string, ...messageParts: unknown[]): void {
48 const message = messageParts.map(log.stringify).join(" ");
49 const dateTime = new Date().toLocaleString();
50 log.output.appendLine(`${label} [${dateTime}]: ${message}`);
51 }
52
53 private stringify(val: unknown): string {
54 if (typeof val === "string") return val;
55 return inspect(val, {
56 colors: false,
57 depth: 6, // heuristic
58 });
32 } 59 }
33}; 60};
34 61
@@ -46,7 +73,7 @@ export async function sendRequestWithRetry<TParam, TRet>(
46 ); 73 );
47 } catch (error) { 74 } catch (error) {
48 if (delay === null) { 75 if (delay === null) {
49 log.error("LSP request timed out", { method: reqType.method, param, error }); 76 log.warn("LSP request timed out", { method: reqType.method, param, error });
50 throw error; 77 throw error;
51 } 78 }
52 79
@@ -55,7 +82,7 @@ export async function sendRequestWithRetry<TParam, TRet>(
55 } 82 }
56 83
57 if (error.code !== lc.ErrorCodes.ContentModified) { 84 if (error.code !== lc.ErrorCodes.ContentModified) {
58 log.error("LSP request failed", { method: reqType.method, param, error }); 85 log.warn("LSP request failed", { method: reqType.method, param, error });
59 throw error; 86 throw error;
60 } 87 }
61 88
@@ -87,11 +114,15 @@ export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
87export function isValidExecutable(path: string): boolean { 114export function isValidExecutable(path: string): boolean {
88 log.debug("Checking availability of a binary at", path); 115 log.debug("Checking availability of a binary at", path);
89 116
117 if (!fs.existsSync(path)) return false;
118
90 const res = spawnSync(path, ["--version"], { encoding: 'utf8' }); 119 const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
91 120
92 log.debug(res, "--version output:", res.output); 121 const isSuccess = res.status === 0;
122 const printOutput = isSuccess ? log.debug : log.warn;
123 printOutput(path, "--version:", res);
93 124
94 return res.status === 0; 125 return isSuccess;
95} 126}
96 127
97/** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */ 128/** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */