Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/log/common/log.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as nls from '../../../nls.js';
7
import { toErrorMessage } from '../../../base/common/errorMessage.js';
8
import { Emitter, Event } from '../../../base/common/event.js';
9
import { hash } from '../../../base/common/hash.js';
10
import { Disposable, IDisposable } from '../../../base/common/lifecycle.js';
11
import { ResourceMap } from '../../../base/common/map.js';
12
import { isWindows } from '../../../base/common/platform.js';
13
import { joinPath } from '../../../base/common/resources.js';
14
import { Mutable, isNumber, isString } from '../../../base/common/types.js';
15
import { URI } from '../../../base/common/uri.js';
16
import { ILocalizedString } from '../../action/common/action.js';
17
import { RawContextKey } from '../../contextkey/common/contextkey.js';
18
import { IEnvironmentService } from '../../environment/common/environment.js';
19
import { createDecorator } from '../../instantiation/common/instantiation.js';
20
21
export const ILogService = createDecorator<ILogService>('logService');
22
export const ILoggerService = createDecorator<ILoggerService>('loggerService');
23
24
function now(): string {
25
return new Date().toISOString();
26
}
27
28
export function isLogLevel(thing: unknown): thing is LogLevel {
29
return isNumber(thing);
30
}
31
32
export enum LogLevel {
33
Off,
34
Trace,
35
Debug,
36
Info,
37
Warning,
38
Error
39
}
40
41
export const DEFAULT_LOG_LEVEL: LogLevel = LogLevel.Info;
42
43
export interface ILogger extends IDisposable {
44
onDidChangeLogLevel: Event<LogLevel>;
45
getLevel(): LogLevel;
46
setLevel(level: LogLevel): void;
47
48
trace(message: string, ...args: any[]): void;
49
debug(message: string, ...args: any[]): void;
50
info(message: string, ...args: any[]): void;
51
warn(message: string, ...args: any[]): void;
52
error(message: string | Error, ...args: any[]): void;
53
54
/**
55
* An operation to flush the contents. Can be synchronous.
56
*/
57
flush(): void;
58
}
59
60
export function canLog(loggerLevel: LogLevel, messageLevel: LogLevel): boolean {
61
return loggerLevel !== LogLevel.Off && loggerLevel <= messageLevel;
62
}
63
64
export function log(logger: ILogger, level: LogLevel, message: string): void {
65
switch (level) {
66
case LogLevel.Trace: logger.trace(message); break;
67
case LogLevel.Debug: logger.debug(message); break;
68
case LogLevel.Info: logger.info(message); break;
69
case LogLevel.Warning: logger.warn(message); break;
70
case LogLevel.Error: logger.error(message); break;
71
case LogLevel.Off: /* do nothing */ break;
72
default: throw new Error(`Invalid log level ${level}`);
73
}
74
}
75
76
function format(args: any, verbose: boolean = false): string {
77
let result = '';
78
79
for (let i = 0; i < args.length; i++) {
80
let a = args[i];
81
82
if (a instanceof Error) {
83
a = toErrorMessage(a, verbose);
84
}
85
86
if (typeof a === 'object') {
87
try {
88
a = JSON.stringify(a);
89
} catch (e) { }
90
}
91
92
result += (i > 0 ? ' ' : '') + a;
93
}
94
95
return result;
96
}
97
98
export type LoggerGroup = {
99
readonly id: string;
100
readonly name: string;
101
};
102
103
export interface ILogService extends ILogger {
104
readonly _serviceBrand: undefined;
105
}
106
107
export interface ILoggerOptions {
108
109
/**
110
* Id of the logger.
111
*/
112
id?: string;
113
114
/**
115
* Name of the logger.
116
*/
117
name?: string;
118
119
/**
120
* Do not create rotating files if max size exceeds.
121
*/
122
donotRotate?: boolean;
123
124
/**
125
* Do not use formatters.
126
*/
127
donotUseFormatters?: boolean;
128
129
/**
130
* When to log. Set to `always` to log always.
131
*/
132
logLevel?: 'always' | LogLevel;
133
134
/**
135
* Whether the log should be hidden from the user.
136
*/
137
hidden?: boolean;
138
139
/**
140
* Condition which must be true to show this logger
141
*/
142
when?: string;
143
144
/**
145
* Id of the extension that created this logger.
146
*/
147
extensionId?: string;
148
149
/**
150
* Group of the logger.
151
*/
152
group?: LoggerGroup;
153
}
154
155
export interface ILoggerResource {
156
readonly resource: URI;
157
readonly id: string;
158
readonly name?: string;
159
readonly logLevel?: LogLevel;
160
readonly hidden?: boolean;
161
readonly when?: string;
162
readonly extensionId?: string;
163
readonly group?: LoggerGroup;
164
}
165
166
export type DidChangeLoggersEvent = {
167
readonly added: Iterable<ILoggerResource>;
168
readonly removed: Iterable<ILoggerResource>;
169
};
170
171
export interface ILoggerService {
172
173
readonly _serviceBrand: undefined;
174
175
/**
176
* Creates a logger for the given resource, or gets one if it already exists.
177
*
178
* This will also register the logger with the logger service.
179
*/
180
createLogger(resource: URI, options?: ILoggerOptions): ILogger;
181
182
/**
183
* Creates a logger with the given id in the logs folder, or gets one if it already exists.
184
*
185
* This will also register the logger with the logger service.
186
*/
187
createLogger(id: string, options?: Omit<ILoggerOptions, 'id'>): ILogger;
188
189
/**
190
* Gets an existing logger, if any.
191
*/
192
getLogger(resourceOrId: URI | string): ILogger | undefined;
193
194
/**
195
* An event which fires when the log level of a logger has changed
196
*/
197
readonly onDidChangeLogLevel: Event<LogLevel | [URI, LogLevel]>;
198
199
/**
200
* Set default log level.
201
*/
202
setLogLevel(level: LogLevel): void;
203
204
/**
205
* Set log level for a logger.
206
*/
207
setLogLevel(resource: URI, level: LogLevel): void;
208
209
/**
210
* Get log level for a logger or the default log level.
211
*/
212
getLogLevel(resource?: URI): LogLevel;
213
214
/**
215
* An event which fires when the visibility of a logger has changed
216
*/
217
readonly onDidChangeVisibility: Event<[URI, boolean]>;
218
219
/**
220
* Set the visibility of a logger.
221
*/
222
setVisibility(resourceOrId: URI | string, visible: boolean): void;
223
224
/**
225
* An event which fires when the logger resources are changed
226
*/
227
readonly onDidChangeLoggers: Event<DidChangeLoggersEvent>;
228
229
/**
230
* Register a logger with the logger service.
231
*
232
* Note that this will not create a logger, but only register it.
233
*
234
* Use `createLogger` to create a logger and register it.
235
*
236
* Use it when you want to register a logger that is not created by the logger service.
237
*/
238
registerLogger(resource: ILoggerResource): void;
239
240
/**
241
* Deregister the logger for the given resource.
242
*/
243
deregisterLogger(idOrResource: URI | string): void;
244
245
/**
246
* Get all registered loggers
247
*/
248
getRegisteredLoggers(): Iterable<ILoggerResource>;
249
250
/**
251
* Get the registered logger for the given resource.
252
*/
253
getRegisteredLogger(resource: URI): ILoggerResource | undefined;
254
}
255
256
export abstract class AbstractLogger extends Disposable implements ILogger {
257
258
private level: LogLevel = DEFAULT_LOG_LEVEL;
259
private readonly _onDidChangeLogLevel: Emitter<LogLevel> = this._register(new Emitter<LogLevel>());
260
get onDidChangeLogLevel(): Event<LogLevel> { return this._onDidChangeLogLevel.event; }
261
262
setLevel(level: LogLevel): void {
263
if (this.level !== level) {
264
this.level = level;
265
this._onDidChangeLogLevel.fire(this.level);
266
}
267
}
268
269
getLevel(): LogLevel {
270
return this.level;
271
}
272
273
protected checkLogLevel(level: LogLevel): boolean {
274
return canLog(this.level, level);
275
}
276
277
protected canLog(level: LogLevel): boolean {
278
if (this._store.isDisposed) {
279
return false;
280
}
281
return this.checkLogLevel(level);
282
}
283
284
abstract trace(message: string, ...args: any[]): void;
285
abstract debug(message: string, ...args: any[]): void;
286
abstract info(message: string, ...args: any[]): void;
287
abstract warn(message: string, ...args: any[]): void;
288
abstract error(message: string | Error, ...args: any[]): void;
289
abstract flush(): void;
290
}
291
292
export abstract class AbstractMessageLogger extends AbstractLogger implements ILogger {
293
294
constructor(private readonly logAlways?: boolean) {
295
super();
296
}
297
298
protected override checkLogLevel(level: LogLevel): boolean {
299
return this.logAlways || super.checkLogLevel(level);
300
}
301
302
trace(message: string, ...args: any[]): void {
303
if (this.canLog(LogLevel.Trace)) {
304
this.log(LogLevel.Trace, format([message, ...args], true));
305
}
306
}
307
308
debug(message: string, ...args: any[]): void {
309
if (this.canLog(LogLevel.Debug)) {
310
this.log(LogLevel.Debug, format([message, ...args]));
311
}
312
}
313
314
info(message: string, ...args: any[]): void {
315
if (this.canLog(LogLevel.Info)) {
316
this.log(LogLevel.Info, format([message, ...args]));
317
}
318
}
319
320
warn(message: string, ...args: any[]): void {
321
if (this.canLog(LogLevel.Warning)) {
322
this.log(LogLevel.Warning, format([message, ...args]));
323
}
324
}
325
326
error(message: string | Error, ...args: any[]): void {
327
if (this.canLog(LogLevel.Error)) {
328
if (message instanceof Error) {
329
const array = Array.prototype.slice.call(arguments) as any[];
330
array[0] = message.stack;
331
this.log(LogLevel.Error, format(array));
332
} else {
333
this.log(LogLevel.Error, format([message, ...args]));
334
}
335
}
336
}
337
338
flush(): void { }
339
340
protected abstract log(level: LogLevel, message: string): void;
341
}
342
343
344
export class ConsoleMainLogger extends AbstractLogger implements ILogger {
345
346
private useColors: boolean;
347
348
constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
349
super();
350
this.setLevel(logLevel);
351
this.useColors = !isWindows;
352
}
353
354
trace(message: string, ...args: any[]): void {
355
if (this.canLog(LogLevel.Trace)) {
356
if (this.useColors) {
357
console.log(`\x1b[90m[main ${now()}]\x1b[0m`, message, ...args);
358
} else {
359
console.log(`[main ${now()}]`, message, ...args);
360
}
361
}
362
}
363
364
debug(message: string, ...args: any[]): void {
365
if (this.canLog(LogLevel.Debug)) {
366
if (this.useColors) {
367
console.log(`\x1b[90m[main ${now()}]\x1b[0m`, message, ...args);
368
} else {
369
console.log(`[main ${now()}]`, message, ...args);
370
}
371
}
372
}
373
374
info(message: string, ...args: any[]): void {
375
if (this.canLog(LogLevel.Info)) {
376
if (this.useColors) {
377
console.log(`\x1b[90m[main ${now()}]\x1b[0m`, message, ...args);
378
} else {
379
console.log(`[main ${now()}]`, message, ...args);
380
}
381
}
382
}
383
384
warn(message: string | Error, ...args: any[]): void {
385
if (this.canLog(LogLevel.Warning)) {
386
if (this.useColors) {
387
console.warn(`\x1b[93m[main ${now()}]\x1b[0m`, message, ...args);
388
} else {
389
console.warn(`[main ${now()}]`, message, ...args);
390
}
391
}
392
}
393
394
error(message: string, ...args: any[]): void {
395
if (this.canLog(LogLevel.Error)) {
396
if (this.useColors) {
397
console.error(`\x1b[91m[main ${now()}]\x1b[0m`, message, ...args);
398
} else {
399
console.error(`[main ${now()}]`, message, ...args);
400
}
401
}
402
}
403
404
flush(): void {
405
// noop
406
}
407
408
}
409
410
export class ConsoleLogger extends AbstractLogger implements ILogger {
411
412
constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL, private readonly useColors: boolean = true) {
413
super();
414
this.setLevel(logLevel);
415
}
416
417
trace(message: string, ...args: any[]): void {
418
if (this.canLog(LogLevel.Trace)) {
419
if (this.useColors) {
420
console.log('%cTRACE', 'color: #888', message, ...args);
421
} else {
422
console.log(message, ...args);
423
}
424
}
425
}
426
427
debug(message: string, ...args: any[]): void {
428
if (this.canLog(LogLevel.Debug)) {
429
if (this.useColors) {
430
console.log('%cDEBUG', 'background: #eee; color: #888', message, ...args);
431
} else {
432
console.log(message, ...args);
433
}
434
}
435
}
436
437
info(message: string, ...args: any[]): void {
438
if (this.canLog(LogLevel.Info)) {
439
if (this.useColors) {
440
console.log('%c INFO', 'color: #33f', message, ...args);
441
} else {
442
console.log(message, ...args);
443
}
444
}
445
}
446
447
warn(message: string | Error, ...args: any[]): void {
448
if (this.canLog(LogLevel.Warning)) {
449
if (this.useColors) {
450
console.warn('%c WARN', 'color: #993', message, ...args);
451
} else {
452
console.log(message, ...args);
453
}
454
}
455
}
456
457
error(message: string, ...args: any[]): void {
458
if (this.canLog(LogLevel.Error)) {
459
if (this.useColors) {
460
console.error('%c ERR', 'color: #f33', message, ...args);
461
} else {
462
console.error(message, ...args);
463
}
464
}
465
}
466
467
468
flush(): void {
469
// noop
470
}
471
}
472
473
export class AdapterLogger extends AbstractLogger implements ILogger {
474
475
constructor(private readonly adapter: { log: (logLevel: LogLevel, args: any[]) => void }, logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
476
super();
477
this.setLevel(logLevel);
478
}
479
480
trace(message: string, ...args: any[]): void {
481
if (this.canLog(LogLevel.Trace)) {
482
this.adapter.log(LogLevel.Trace, [this.extractMessage(message), ...args]);
483
}
484
}
485
486
debug(message: string, ...args: any[]): void {
487
if (this.canLog(LogLevel.Debug)) {
488
this.adapter.log(LogLevel.Debug, [this.extractMessage(message), ...args]);
489
}
490
}
491
492
info(message: string, ...args: any[]): void {
493
if (this.canLog(LogLevel.Info)) {
494
this.adapter.log(LogLevel.Info, [this.extractMessage(message), ...args]);
495
}
496
}
497
498
warn(message: string | Error, ...args: any[]): void {
499
if (this.canLog(LogLevel.Warning)) {
500
this.adapter.log(LogLevel.Warning, [this.extractMessage(message), ...args]);
501
}
502
}
503
504
error(message: string | Error, ...args: any[]): void {
505
if (this.canLog(LogLevel.Error)) {
506
this.adapter.log(LogLevel.Error, [this.extractMessage(message), ...args]);
507
}
508
}
509
510
private extractMessage(msg: string | Error): string {
511
if (typeof msg === 'string') {
512
return msg;
513
}
514
515
return toErrorMessage(msg, this.canLog(LogLevel.Trace));
516
}
517
518
flush(): void {
519
// noop
520
}
521
}
522
523
export class MultiplexLogger extends AbstractLogger implements ILogger {
524
525
constructor(private readonly loggers: ReadonlyArray<ILogger>) {
526
super();
527
if (loggers.length) {
528
this.setLevel(loggers[0].getLevel());
529
}
530
}
531
532
override setLevel(level: LogLevel): void {
533
for (const logger of this.loggers) {
534
logger.setLevel(level);
535
}
536
super.setLevel(level);
537
}
538
539
trace(message: string, ...args: any[]): void {
540
for (const logger of this.loggers) {
541
logger.trace(message, ...args);
542
}
543
}
544
545
debug(message: string, ...args: any[]): void {
546
for (const logger of this.loggers) {
547
logger.debug(message, ...args);
548
}
549
}
550
551
info(message: string, ...args: any[]): void {
552
for (const logger of this.loggers) {
553
logger.info(message, ...args);
554
}
555
}
556
557
warn(message: string, ...args: any[]): void {
558
for (const logger of this.loggers) {
559
logger.warn(message, ...args);
560
}
561
}
562
563
error(message: string | Error, ...args: any[]): void {
564
for (const logger of this.loggers) {
565
logger.error(message, ...args);
566
}
567
}
568
569
flush(): void {
570
for (const logger of this.loggers) {
571
logger.flush();
572
}
573
}
574
575
override dispose(): void {
576
for (const logger of this.loggers) {
577
logger.dispose();
578
}
579
super.dispose();
580
}
581
}
582
583
type LoggerEntry = { logger: ILogger | undefined; info: Mutable<ILoggerResource> };
584
585
export abstract class AbstractLoggerService extends Disposable implements ILoggerService {
586
587
declare readonly _serviceBrand: undefined;
588
589
private readonly _loggers = new ResourceMap<LoggerEntry>();
590
591
private _onDidChangeLoggers = this._register(new Emitter<{ added: ILoggerResource[]; removed: ILoggerResource[] }>);
592
readonly onDidChangeLoggers = this._onDidChangeLoggers.event;
593
594
private _onDidChangeLogLevel = this._register(new Emitter<LogLevel | [URI, LogLevel]>);
595
readonly onDidChangeLogLevel = this._onDidChangeLogLevel.event;
596
597
private _onDidChangeVisibility = this._register(new Emitter<[URI, boolean]>);
598
readonly onDidChangeVisibility = this._onDidChangeVisibility.event;
599
600
constructor(
601
protected logLevel: LogLevel,
602
private readonly logsHome: URI,
603
loggerResources?: Iterable<ILoggerResource>,
604
) {
605
super();
606
if (loggerResources) {
607
for (const loggerResource of loggerResources) {
608
this._loggers.set(loggerResource.resource, { logger: undefined, info: loggerResource });
609
}
610
}
611
}
612
613
private getLoggerEntry(resourceOrId: URI | string): LoggerEntry | undefined {
614
if (isString(resourceOrId)) {
615
return [...this._loggers.values()].find(logger => logger.info.id === resourceOrId);
616
}
617
return this._loggers.get(resourceOrId);
618
}
619
620
getLogger(resourceOrId: URI | string): ILogger | undefined {
621
return this.getLoggerEntry(resourceOrId)?.logger;
622
}
623
624
createLogger(idOrResource: URI | string, options?: ILoggerOptions): ILogger {
625
const resource = this.toResource(idOrResource);
626
const id = isString(idOrResource) ? idOrResource : (options?.id ?? hash(resource.toString()).toString(16));
627
let logger = this._loggers.get(resource)?.logger;
628
const logLevel = options?.logLevel === 'always' ? LogLevel.Trace : options?.logLevel;
629
if (!logger) {
630
logger = this.doCreateLogger(resource, logLevel ?? this.getLogLevel(resource) ?? this.logLevel, { ...options, id });
631
}
632
const loggerEntry: LoggerEntry = {
633
logger,
634
info: {
635
resource,
636
id,
637
logLevel,
638
name: options?.name,
639
hidden: options?.hidden,
640
group: options?.group,
641
extensionId: options?.extensionId,
642
when: options?.when
643
}
644
};
645
this.registerLogger(loggerEntry.info);
646
// TODO: @sandy081 Remove this once registerLogger can take ILogger
647
this._loggers.set(resource, loggerEntry);
648
return logger;
649
}
650
651
protected toResource(idOrResource: string | URI): URI {
652
return isString(idOrResource) ? joinPath(this.logsHome, `${idOrResource}.log`) : idOrResource;
653
}
654
655
setLogLevel(logLevel: LogLevel): void;
656
setLogLevel(resource: URI, logLevel: LogLevel): void;
657
setLogLevel(arg1: any, arg2?: any): void {
658
if (URI.isUri(arg1)) {
659
const resource = arg1;
660
const logLevel = arg2;
661
const logger = this._loggers.get(resource);
662
if (logger && logLevel !== logger.info.logLevel) {
663
logger.info.logLevel = logLevel === this.logLevel ? undefined : logLevel;
664
logger.logger?.setLevel(logLevel);
665
this._loggers.set(logger.info.resource, logger);
666
this._onDidChangeLogLevel.fire([resource, logLevel]);
667
}
668
} else {
669
this.logLevel = arg1;
670
for (const [resource, logger] of this._loggers.entries()) {
671
if (this._loggers.get(resource)?.info.logLevel === undefined) {
672
logger.logger?.setLevel(this.logLevel);
673
}
674
}
675
this._onDidChangeLogLevel.fire(this.logLevel);
676
}
677
}
678
679
setVisibility(resourceOrId: URI | string, visibility: boolean): void {
680
const logger = this.getLoggerEntry(resourceOrId);
681
if (logger && visibility !== !logger.info.hidden) {
682
logger.info.hidden = !visibility;
683
this._loggers.set(logger.info.resource, logger);
684
this._onDidChangeVisibility.fire([logger.info.resource, visibility]);
685
}
686
}
687
688
getLogLevel(resource?: URI): LogLevel {
689
let logLevel;
690
if (resource) {
691
logLevel = this._loggers.get(resource)?.info.logLevel;
692
}
693
return logLevel ?? this.logLevel;
694
}
695
696
registerLogger(resource: ILoggerResource): void {
697
const existing = this._loggers.get(resource.resource);
698
if (existing) {
699
if (existing.info.hidden !== resource.hidden) {
700
this.setVisibility(resource.resource, !resource.hidden);
701
}
702
} else {
703
this._loggers.set(resource.resource, { info: resource, logger: undefined });
704
this._onDidChangeLoggers.fire({ added: [resource], removed: [] });
705
}
706
}
707
708
deregisterLogger(idOrResource: URI | string): void {
709
const resource = this.toResource(idOrResource);
710
const existing = this._loggers.get(resource);
711
if (existing) {
712
if (existing.logger) {
713
existing.logger.dispose();
714
}
715
this._loggers.delete(resource);
716
this._onDidChangeLoggers.fire({ added: [], removed: [existing.info] });
717
}
718
}
719
720
*getRegisteredLoggers(): Iterable<ILoggerResource> {
721
for (const entry of this._loggers.values()) {
722
yield entry.info;
723
}
724
}
725
726
getRegisteredLogger(resource: URI): ILoggerResource | undefined {
727
return this._loggers.get(resource)?.info;
728
}
729
730
override dispose(): void {
731
this._loggers.forEach(logger => logger.logger?.dispose());
732
this._loggers.clear();
733
super.dispose();
734
}
735
736
protected abstract doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger;
737
}
738
739
export class NullLogger implements ILogger {
740
readonly onDidChangeLogLevel: Event<LogLevel> = new Emitter<LogLevel>().event;
741
setLevel(level: LogLevel): void { }
742
getLevel(): LogLevel { return LogLevel.Info; }
743
trace(message: string, ...args: any[]): void { }
744
debug(message: string, ...args: any[]): void { }
745
info(message: string, ...args: any[]): void { }
746
warn(message: string, ...args: any[]): void { }
747
error(message: string | Error, ...args: any[]): void { }
748
critical(message: string | Error, ...args: any[]): void { }
749
dispose(): void { }
750
flush(): void { }
751
}
752
753
export class NullLogService extends NullLogger implements ILogService {
754
declare readonly _serviceBrand: undefined;
755
}
756
757
export class NullLoggerService extends AbstractLoggerService {
758
constructor() {
759
super(LogLevel.Off, URI.parse('log:///log'));
760
}
761
protected override doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger {
762
return new NullLogger();
763
}
764
}
765
766
export function getLogLevel(environmentService: IEnvironmentService): LogLevel {
767
if (environmentService.verbose) {
768
return LogLevel.Trace;
769
}
770
if (typeof environmentService.logLevel === 'string') {
771
const logLevel = parseLogLevel(environmentService.logLevel.toLowerCase());
772
if (logLevel !== undefined) {
773
return logLevel;
774
}
775
}
776
return DEFAULT_LOG_LEVEL;
777
}
778
779
export function LogLevelToString(logLevel: LogLevel): string {
780
switch (logLevel) {
781
case LogLevel.Trace: return 'trace';
782
case LogLevel.Debug: return 'debug';
783
case LogLevel.Info: return 'info';
784
case LogLevel.Warning: return 'warn';
785
case LogLevel.Error: return 'error';
786
case LogLevel.Off: return 'off';
787
}
788
}
789
790
export function LogLevelToLocalizedString(logLevel: LogLevel): ILocalizedString {
791
switch (logLevel) {
792
case LogLevel.Trace: return { original: 'Trace', value: nls.localize('trace', "Trace") };
793
case LogLevel.Debug: return { original: 'Debug', value: nls.localize('debug', "Debug") };
794
case LogLevel.Info: return { original: 'Info', value: nls.localize('info', "Info") };
795
case LogLevel.Warning: return { original: 'Warning', value: nls.localize('warn', "Warning") };
796
case LogLevel.Error: return { original: 'Error', value: nls.localize('error', "Error") };
797
case LogLevel.Off: return { original: 'Off', value: nls.localize('off', "Off") };
798
}
799
}
800
801
export function parseLogLevel(logLevel: string): LogLevel | undefined {
802
switch (logLevel) {
803
case 'trace':
804
return LogLevel.Trace;
805
case 'debug':
806
return LogLevel.Debug;
807
case 'info':
808
return LogLevel.Info;
809
case 'warn':
810
return LogLevel.Warning;
811
case 'error':
812
return LogLevel.Error;
813
case 'critical':
814
return LogLevel.Error;
815
case 'off':
816
return LogLevel.Off;
817
}
818
return undefined;
819
}
820
821
// Contexts
822
export const CONTEXT_LOG_LEVEL = new RawContextKey<string>('logLevel', LogLevelToString(LogLevel.Info));
823
824