Welcome to mirror list, hosted at ThFree Co, Russian Federation.

spdlogLog.ts « node « log « platform « vs « src - github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b97064e29f74a00cbb4016371123e37414b7074f (plain)
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
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { LogLevel, ILogger, AbstractMessageLogger } from 'vs/platform/log/common/log';
import * as spdlog from 'spdlog';
import { ByteSize } from 'vs/platform/files/common/files';

async function createSpdLogLogger(name: string, logfilePath: string, filesize: number, filecount: number): Promise<spdlog.RotatingLogger | null> {
	// Do not crash if spdlog cannot be loaded
	try {
		const _spdlog = await import('spdlog');
		_spdlog.setAsyncMode(8192, 500);
		return _spdlog.createRotatingLoggerAsync(name, logfilePath, filesize, filecount);
	} catch (e) {
		console.error(e);
	}
	return null;
}

export function createRotatingLogger(name: string, filename: string, filesize: number, filecount: number): spdlog.RotatingLogger {
	const _spdlog: typeof spdlog = require.__$__nodeRequire('spdlog');
	return _spdlog.createRotatingLogger(name, filename, filesize, filecount);
}

interface ILog {
	level: LogLevel;
	message: string;
}

function log(logger: spdlog.RotatingLogger, level: LogLevel, message: string): void {
	switch (level) {
		case LogLevel.Trace: logger.trace(message); break;
		case LogLevel.Debug: logger.debug(message); break;
		case LogLevel.Info: logger.info(message); break;
		case LogLevel.Warning: logger.warn(message); break;
		case LogLevel.Error: logger.error(message); break;
		case LogLevel.Critical: logger.critical(message); break;
		default: throw new Error('Invalid log level');
	}
}

export class SpdLogLogger extends AbstractMessageLogger implements ILogger {

	private buffer: ILog[] = [];
	private readonly _loggerCreationPromise: Promise<void>;
	private _logger: spdlog.RotatingLogger | undefined;

	constructor(
		private readonly name: string,
		private readonly filepath: string,
		private readonly rotating: boolean,
		level: LogLevel
	) {
		super();
		this.setLevel(level);
		this._loggerCreationPromise = this._createSpdLogLogger();
		this._register(this.onDidChangeLogLevel(level => {
			if (this._logger) {
				this._logger.setLevel(level);
			}
		}));
	}

	private _createSpdLogLogger(): Promise<void> {
		const filecount = this.rotating ? 6 : 1;
		const filesize = (30 / filecount) * ByteSize.MB;
		return createSpdLogLogger(this.name, this.filepath, filesize, filecount)
			.then(logger => {
				if (logger) {
					this._logger = logger;
					this._logger.setLevel(this.getLevel());
					for (const { level, message } of this.buffer) {
						log(this._logger, level, message);
					}
					this.buffer = [];
				}
			});
	}

	protected log(level: LogLevel, message: string): void {
		if (this._logger) {
			log(this._logger, level, message);
		} else if (this.getLevel() <= level) {
			this.buffer.push({ level, message });
		}
	}

	clearFormatters(): void {
		if (this._logger) {
			this._logger.clearFormatters();
		} else {
			this._loggerCreationPromise.then(() => this.clearFormatters());
		}
	}

	override flush(): void {
		if (this._logger) {
			this._logger.flush();
		} else {
			this._loggerCreationPromise.then(() => this.flush());
		}
	}

	override dispose(): void {
		if (this._logger) {
			this.disposeLogger();
		} else {
			this._loggerCreationPromise.then(() => this.disposeLogger());
		}
	}

	private disposeLogger(): void {
		if (this._logger) {
			this._logger.drop();
			this._logger = undefined;
		}
	}
}