提交 9914a95d 编写于 作者: J Joao Moreno

buffer spdlog calls in main until singleton

fixes #41218
上级 e5cbf755
......@@ -37,7 +37,7 @@ import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc';
import { ipcRenderer } from 'electron';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { createSharedProcessContributions } from 'vs/code/electron-browser/sharedProcess/contrib/contributions';
import { createLogService } from 'vs/platform/log/node/spdlogService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { ILogService } from 'vs/platform/log/common/log';
export interface ISharedProcessConfiguration {
......@@ -81,7 +81,7 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I
const services = new ServiceCollection();
const environmentService = new EnvironmentService(initData.args, process.execPath);
const logService = createLogService('sharedprocess', environmentService);
const logService = createSpdLogService('sharedprocess', environmentService);
process.once('exit', () => logService.dispose());
logService.info('main', JSON.stringify(configuration));
......
......@@ -42,16 +42,16 @@ import { WorkspacesMainService } from 'vs/platform/workspaces/electron-main/work
import { IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces';
import { localize } from 'vs/nls';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { createLogService } from 'vs/platform/log/node/spdlogService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { printDiagnostics } from 'vs/code/electron-main/diagnostics';
import { BufferLogService } from 'vs/platform/log/common/bufferLog';
function createServices(args: ParsedArgs): IInstantiationService {
function createServices(args: ParsedArgs, bufferLogService: BufferLogService): IInstantiationService {
const services = new ServiceCollection();
const environmentService = new EnvironmentService(args, process.execPath);
const spdlogService = createLogService('main', environmentService);
const consoleLogService = new ConsoleLogMainService(environmentService);
const logService = new MultiplexLogService([consoleLogService, spdlogService]);
const logService = new MultiplexLogService([consoleLogService, bufferLogService]);
process.once('exit', () => logService.dispose());
......@@ -284,7 +284,12 @@ function main() {
return;
}
const instantiationService = createServices(args);
// We need to buffer the spdlog logs until we are sure
// we are the only instance running, otherwise we'll have concurrent
// log file access on Windows
// https://github.com/Microsoft/vscode/issues/41218
const bufferLogService = new BufferLogService();
const instantiationService = createServices(args, bufferLogService);
return instantiationService.invokeFunction(accessor => {
......@@ -300,7 +305,10 @@ function main() {
// Startup
return instantiationService.invokeFunction(a => createPaths(a.get(IEnvironmentService)))
.then(() => instantiationService.invokeFunction(setupIPC))
.then(mainIpcServer => instantiationService.createInstance(CodeApplication, mainIpcServer, instanceEnv).startup());
.then(mainIpcServer => {
bufferLogService.logger = createSpdLogService('main', environmentService);
return instantiationService.createInstance(CodeApplication, mainIpcServer, instanceEnv).startup();
});
}).done(null, err => instantiationService.invokeFunction(quit, err));
}
......
......@@ -35,7 +35,7 @@ import { ChoiceCliService } from 'vs/platform/message/node/messageCli';
import { getBaseLabel } from 'vs/base/common/labels';
import { IStateService } from 'vs/platform/state/common/state';
import { StateService } from 'vs/platform/state/node/stateService';
import { createLogService } from 'vs/platform/log/node/spdlogService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { ILogService } from 'vs/platform/log/common/log';
import { isPromiseCanceledError } from 'vs/base/common/errors';
......@@ -196,7 +196,7 @@ export function main(argv: ParsedArgs): TPromise<void> {
const services = new ServiceCollection();
const environmentService = new EnvironmentService(argv, process.execPath);
const logService = createLogService('cli', environmentService);
const logService = createSpdLogService('cli', environmentService);
process.once('exit', () => logService.dispose());
logService.info('main', argv);
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
interface ILog {
level: LogLevel;
args: IArguments;
}
function getLogFunction(logger: ILogService, level: LogLevel): Function {
switch (level) {
case LogLevel.Trace: return logger.trace;
case LogLevel.Debug: return logger.debug;
case LogLevel.Info: return logger.info;
case LogLevel.Warning: return logger.warn;
case LogLevel.Error: return logger.error;
case LogLevel.Critical: return logger.critical;
default: throw new Error('Invalid log level');
}
}
export class BufferLogService implements ILogService {
_serviceBrand: any;
private buffer: ILog[] = [];
private _logger: ILogService | undefined = undefined;
constructor(
private level: LogLevel = LogLevel.Error
) {
}
set logger(logger: ILogService) {
this._logger = logger;
for (const { level, args } of this.buffer) {
const fn = getLogFunction(logger, level);
fn.apply(logger, args);
}
this.buffer = [];
}
setLevel(logLevel: LogLevel): void {
this.level = logLevel;
}
getLevel(): LogLevel {
return this.level;
}
private _log(level: LogLevel, args: IArguments): void {
if (this._logger) {
const fn = getLogFunction(this._logger, level);
fn.apply(this._logger, args);
} else if (this.level < level) {
this.buffer.push({ level, args });
}
}
trace(): void {
this._log(LogLevel.Trace, arguments);
}
debug(): void {
this._log(LogLevel.Debug, arguments);
}
info(): void {
this._log(LogLevel.Info, arguments);
}
warn(): void {
this._log(LogLevel.Warning, arguments);
}
error(): void {
this._log(LogLevel.Error, arguments);
}
critical(): void {
this._log(LogLevel.Critical, arguments);
}
dispose(): void {
if (this._logger) {
this._logger.dispose();
}
}
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ import { ILogService, LogLevel, NullLogService } from 'vs/platform/log/common/lo
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { RotatingLogger, setAsyncMode } from 'spdlog';
export function createLogService(processName: string, environmentService: IEnvironmentService, logsSubfolder?: string): ILogService {
export function createSpdLogService(processName: string, environmentService: IEnvironmentService, logsSubfolder?: string): ILogService {
try {
setAsyncMode(8192, 2000);
const logsDirPath = logsSubfolder ? path.join(environmentService.logsPath, logsSubfolder) : environmentService.logsPath;
......
......@@ -11,7 +11,7 @@ import { mkdirp, dirExists } from 'vs/base/node/pfs';
import Event, { Emitter } from 'vs/base/common/event';
import { LogLevel } from 'vs/workbench/api/node/extHostTypes';
import { ILogService } from 'vs/platform/log/common/log';
import { createLogService } from 'vs/platform/log/node/spdlogService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { memoize } from 'vs/base/common/decorators';
......@@ -23,7 +23,7 @@ export class ExtHostLogService {
getExtLogger(extensionID: string): ExtHostLogger {
if (!this._loggers.has(extensionID)) {
const logService = createLogService(extensionID, this._environmentService, extensionID);
const logService = createSpdLogService(extensionID, this._environmentService, extensionID);
const logsDirPath = path.join(this._environmentService.logsPath, extensionID);
this._loggers.set(extensionID, new ExtHostLogger(logService, logsDirPath));
}
......
......@@ -40,7 +40,7 @@ import { URLChannelClient } from 'vs/platform/url/common/urlIpc';
import { IURLService } from 'vs/platform/url/common/url';
import { WorkspacesChannelClient } from 'vs/platform/workspaces/common/workspacesIpc';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { createLogService } from 'vs/platform/log/node/spdlogService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import fs = require('fs');
import { ConsoleLogService, MultiplexLogService } from 'vs/platform/log/common/log';
......@@ -73,7 +73,7 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> {
const mainServices = createMainProcessServices(mainProcessClient, configuration);
const environmentService = new EnvironmentService(configuration, configuration.execPath);
const spdlogService = createLogService(`renderer${configuration.windowId}`, environmentService);
const spdlogService = createSpdLogService(`renderer${configuration.windowId}`, environmentService);
const consoleLogService = new ConsoleLogService(environmentService);
const logService = new MultiplexLogService([consoleLogService, spdlogService]);
......
......@@ -21,7 +21,7 @@ import * as watchdog from 'native-watchdog';
import * as glob from 'vs/base/common/glob';
import { ExtensionActivatedByEvent } from 'vs/workbench/api/node/extHostExtensionActivator';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { createLogService } from 'vs/platform/log/node/spdlogService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ILogService } from 'vs/platform/log/common/log';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
......@@ -92,7 +92,7 @@ export class ExtensionHostMain {
const rpcProtocol = new RPCProtocol(protocol);
const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, initData.workspace);
const environmentService = new EnvironmentService(initData.args, initData.execPath);
this._logService = createLogService(`exthost${initData.windowId}`, environmentService);
this._logService = createSpdLogService(`exthost${initData.windowId}`, environmentService);
this.disposables.push(this._logService);
this._logService.info('extension host started');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册