/
logger.ts
125 lines (107 loc) · 3.76 KB
/
logger.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* Copyright (c) 2019, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { format } from 'util';
import * as vscode from 'vscode';
/** A wrapper around an OutputChannel that will optionally prefix each line of output. */
export class PrefixingOutputChannel implements vscode.OutputChannel {
constructor(public readonly output?: vscode.OutputChannel, public readonly prefix?: string) {}
protected addPrefix(mesg: string): string {
return this.prefix ? `[${this.prefix}] ${mesg}` : mesg;
}
get name() {
return this.output?.name ?? this.prefix ?? '';
}
public append(value: string): void {
// TODO: handle embedded newlines to add prefix
this.output?.append(value);
}
public appendLine(value: string): void {
this.output?.appendLine(this.addPrefix(value));
}
public clear(): void {
this.output?.clear();
}
public replace(value: string): void {
this.output?.replace(value);
}
public show(preserveFocus?: boolean | undefined): void;
public show(column?: vscode.ViewColumn | undefined, preserveFocus?: boolean | undefined): void;
public show(column?: any, preserveFocus?: any) {
this.output?.show(preserveFocus);
}
public hide(): void {
this.output?.hide();
}
public dispose(): void {
// ignore this call -- the output channel might be shared elsewhere, and the creator of the channel should
// handle dispose()'ing it
}
}
export type LoggerOptions = {
prefix?: string;
toConsole?: boolean;
};
/** A proxy for multi-plexing log output to the console and to a vscode.OutputChannel.
* This also supports prefixing output lines.
*/
export class Logger extends PrefixingOutputChannel {
public readonly toConsole: boolean | undefined;
// Note: most creators of Loggers should use this method to avoid double-wrapping.
// Generally, only the top-level Logger created index.ts should use the constructor directly
public static from(output?: vscode.OutputChannel, options?: LoggerOptions): Logger {
if (output && output instanceof Logger) {
return output;
} else {
return new Logger(output, options);
}
}
// Note: only the top-level Logger created in index.ts should really set toConsole true and have the default
// ADX output channel
constructor(public readonly output?: vscode.OutputChannel, { prefix, toConsole = false }: LoggerOptions = {}) {
super(output, prefix);
this.toConsole = toConsole;
}
public append(value: string): void {
super.append(value);
// TODO: buffer up append()'s and console.log() at newlines
}
public appendLine(value: string): void {
super.appendLine(value);
if (this.toConsole) {
console.log(this.addPrefix(value));
}
}
public log(message?: any, ...optionalParams: any[]): void {
if (this.toConsole || this.output) {
// format style log()
if (typeof message === 'string') {
message = this.addPrefix(message);
if (this.toConsole) {
console.log(message, ...optionalParams);
}
if (this.output) {
this.output.appendLine(format(message, ...optionalParams));
}
} else {
// object style log()
if (this.toConsole) {
if (this.prefix) {
console.log(this.prefix, message, ...optionalParams);
} else {
console.log(message, ...optionalParams);
}
}
if (this.output) {
this.output.appendLine(
this.prefix ? format(this.prefix, message, ...optionalParams) : format(message, ...optionalParams)
);
}
}
}
}
// TODO: add warn/error/debug/info methods to match console
}