Add ExtHostLogService with logger and lazily created log folder per extension

This commit is contained in:
Rob Lourens
2017-12-12 19:07:41 -08:00
parent 4d42f3d7af
commit daa3a0ec2e
8 changed files with 156 additions and 7 deletions

View File

@@ -59,6 +59,8 @@ import { toGlobPattern, toLanguageSelector } from 'vs/workbench/api/node/extHost
import { ExtensionActivatedByAPI } from 'vs/workbench/api/node/extHostExtensionActivator';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { ILogService } from 'vs/platform/log/common/log';
import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
export interface IExtensionApiFactory {
(extension: IExtensionDescription): typeof vscode;
@@ -83,7 +85,8 @@ export function createApiFactory(
extHostWorkspace: ExtHostWorkspace,
extHostConfiguration: ExtHostConfiguration,
extensionService: ExtHostExtensionService,
logService: ILogService
logService: ILogService,
environmentService: IEnvironmentService
): IExtensionApiFactory {
// Addressable instances
@@ -121,6 +124,7 @@ export function createApiFactory(
const extHostProgress = new ExtHostProgress(threadService.get(MainContext.MainThreadProgress));
const extHostOutputService = new ExtHostOutputService(threadService);
const extHostLanguages = new ExtHostLanguages(threadService);
const extHostLogService = new ExtHostLogService(environmentService);
// Register API-ish commands
ExtHostApiCommands.register(extHostCommands);
@@ -202,6 +206,7 @@ export function createApiFactory(
get language() { return Platform.language; },
get appName() { return product.nameLong; },
get appRoot() { return initData.environment.appRoot; },
get logger() { return extHostLogService.getExtLogger(extension.id); },
});
// namespace: extensions
@@ -570,6 +575,7 @@ export function createApiFactory(
Hover: extHostTypes.Hover,
IndentAction: languageConfiguration.IndentAction,
Location: extHostTypes.Location,
LogLevel: extHostTypes.LogLevel,
MarkdownString: extHostTypes.MarkdownString,
OverviewRulerLane: EditorCommon.OverviewRulerLane,
ParameterInformation: extHostTypes.ParameterInformation,

View File

@@ -33,7 +33,7 @@ import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs
import { IPickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
import { EndOfLine, TextEditorLineNumbersStyle } from 'vs/workbench/api/node/extHostTypes';
import { EndOfLine, TextEditorLineNumbersStyle, LogLevel } from 'vs/workbench/api/node/extHostTypes';
import { TaskSet } from 'vs/workbench/parts/tasks/common/tasks';
@@ -673,6 +673,10 @@ export interface ExtHostWindowShape {
$onDidChangeWindowFocus(value: boolean): void;
}
export interface ExtHostLogServiceShape {
$acceptLogLevelChanged(logLevel: LogLevel): void;
}
// --- proxy identifiers
export const MainContext = {
@@ -723,6 +727,7 @@ export const ExtHostContext = {
ExtHostLanguageFeatures: createExtId<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures'),
ExtHostQuickOpen: createExtId<ExtHostQuickOpenShape>('ExtHostQuickOpen'),
ExtHostExtensionService: createExtId<ExtHostExtensionServiceShape>('ExtHostExtensionService'),
// ExtHostLogService: createExtId<ExtHostLogServiceShape>('ExtHostLogService'),
ExtHostTerminalService: createExtId<ExtHostTerminalServiceShape>('ExtHostTerminalService'),
ExtHostSCM: createExtId<ExtHostSCMShape>('ExtHostSCM'),
ExtHostTask: createExtId<ExtHostTaskShape>('ExtHostTask'),

View File

@@ -21,6 +21,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
import { TernarySearchTree } from 'vs/base/common/map';
import { Barrier } from 'vs/base/common/async';
import { ILogService } from 'vs/platform/log/common/log';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
class ExtensionMemento implements IExtensionMemento {
@@ -127,7 +128,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
threadService: ExtHostThreadService,
extHostWorkspace: ExtHostWorkspace,
extHostConfiguration: ExtHostConfiguration,
logService: ILogService
logService: ILogService,
environmentService: IEnvironmentService
) {
this._barrier = new Barrier();
this._registry = new ExtensionDescriptionRegistry(initData.extensions);
@@ -140,7 +142,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
this._activator = null;
// initialize API first (i.e. do not release barrier until the API is initialized)
const apiFactory = createApiFactory(initData, threadService, extHostWorkspace, extHostConfiguration, this, logService);
const apiFactory = createApiFactory(initData, threadService, extHostWorkspace, extHostConfiguration, this, logService, environmentService);
initializeExtensionApi(this, apiFactory).then(() => {

View File

@@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------------------------
* 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 * as path from 'path';
import * as vscode from 'vscode';
import { TPromise } from 'vs/base/common/winjs.base';
import { mkdirp, dirExists } from 'vs/base/node/pfs';
import Event, { Emitter } from 'vs/base/common/event';
import { ExtHostLogServiceShape } from './extHost.protocol';
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 { IEnvironmentService } from 'vs/platform/environment/common/environment';
export class ExtHostLogService implements ExtHostLogServiceShape {
private _loggers: Map<string, ExtHostLogger> = new Map();
private _onDidChangeLogLevel: Emitter<LogLevel>;
get onDidChangeLogLevel(): Event<LogLevel> { return this._onDidChangeLogLevel.event; }
constructor(private _environmentService: IEnvironmentService) {
this._onDidChangeLogLevel = new Emitter<LogLevel>();
}
$acceptLogLevelChanged(logLevel: LogLevel): void {
this._onDidChangeLogLevel.fire(logLevel);
}
getExtLogger(extensionID: string): ExtHostLogger {
if (!this._loggers.has(extensionID)) {
const logService = createLogService(extensionID, this._environmentService, extensionID);
const logsDirPath = path.join(this._environmentService.logsPath, extensionID);
this._loggers.set(extensionID, new ExtHostLogger(this, logService, logsDirPath));
}
return this._loggers.get(extensionID);
}
}
export class ExtHostLogger implements vscode.ILogger {
private _currentLevel: LogLevel;
get onDidChangeLogLevel(): Event<LogLevel> { return this._extHostLogService.onDidChangeLogLevel; }
constructor(
private readonly _extHostLogService: ExtHostLogService,
private readonly _logService: ILogService,
private readonly _logDirectory: string
) {
this._extHostLogService.onDidChangeLogLevel(logLevel => this._currentLevel = logLevel);
}
getLogDirectory(): TPromise<string> {
return dirExists(this._logDirectory).then(exists => {
if (exists) {
return TPromise.wrap(null);
} else {
return mkdirp(this._logDirectory);
}
}).then(() => {
return this._logDirectory;
});
}
getLevel(): vscode.LogLevel {
return this._currentLevel;
}
trace(message: string, ...args: any[]): void {
return this._logService.trace(message, ...args);
}
debug(message: string, ...args: any[]): void {
return this._logService.debug(message, ...args);
}
info(message: string, ...args: any[]): void {
return this._logService.info(message, ...args);
}
warn(message: string, ...args: any[]): void {
return this._logService.warn(message, ...args);
}
error(message: string | Error, ...args: any[]): void {
return this._logService.error(message, ...args);
}
critical(message: string | Error, ...args: any[]): void {
return this._logService.critical(message, ...args);
}
}

View File

@@ -1531,3 +1531,13 @@ export class FunctionBreakpoint extends Breakpoint {
this.functionName = functionName;
}
}
export enum LogLevel {
Trace = 1,
Debug = 2,
Info = 3,
Warning = 4,
Error = 5,
Critical = 6,
Off = 7
}