Replace logging framework with a simple wrapper around VS Code's new LogOutputChannel

This commit is contained in:
Jason Fields 2022-12-27 22:43:33 -05:00
parent e3aae8af39
commit f122b747a0
14 changed files with 48 additions and 366 deletions

View File

@ -8,6 +8,7 @@
### Changed
- Logging is now done to a `LogOutputChannel`. It can be accessed in the `Output` panel and configured using `workbench.action.setLogLevel` ([@J-Fields](https://github.com/J-Fields)).
- Scope for settings under `vim.autoSwitchInputMethod.*` is now `machine` ([@Quanuanc](https://github.com/Quanuanc)).
### Fixed

View File

@ -75,8 +75,6 @@ export async function getAndUpdateModeHandler(
async function loadConfiguration() {
const validatorResults = await configuration.load();
Logger.configChanged(configuration);
const logger = Logger.get('Configuration');
logger.debug(`${validatorResults.numErrors} errors found with vim configuration`);

View File

@ -24,7 +24,7 @@
"url": "https://github.com/VSCodeVim/Vim/issues"
},
"engines": {
"vscode": "^1.67.0"
"vscode": "^1.74.0"
},
"categories": [
"Other",
@ -448,35 +448,6 @@
"title": "Vim",
"type": "object",
"properties": {
"vim.debug.silent": {
"type": "boolean",
"description": "If true, all logs are suppressed.",
"default": false
},
"vim.debug.loggingLevelForAlert": {
"type": "string",
"description": "Maximum level of messages to present as VS Code information window.",
"default": "error",
"enum": [
"error",
"warn",
"info",
"verbose",
"debug"
]
},
"vim.debug.loggingLevelForConsole": {
"type": "string",
"description": "Maximum level of messages to log to console. Logs are visible in developer tools.",
"default": "error",
"enum": [
"error",
"warn",
"info",
"verbose",
"debug"
]
},
"vim.normalModeKeyBindings": {
"type": "array",
"markdownDescription": "Remapped keys in Normal mode. Allows mapping to Vim commands or VS Code actions. See [README](https://github.com/VSCodeVim/Vim/#key-remapping) for details.",
@ -1182,10 +1153,7 @@
"queue": "^6.0.2",
"source-map-support": "0.5.21",
"untildify": "4.0.0",
"util": "0.12.5",
"winston": "3.8.2",
"winston-console-for-electron": "0.0.6",
"winston-transport": "4.5.0"
"util": "0.12.5"
},
"devDependencies": {
"@types/diff": "5.0.2",
@ -1197,7 +1165,7 @@
"@types/parsimmon": "1.10.6",
"@types/sinon": "10.0.13",
"@types/source-map-support": "0.5.6",
"@types/vscode": "1.67.0",
"@types/vscode": "1.74.0",
"@vscode/test-electron": "2.2.1",
"circular-dependency-plugin": "^5.2.2",
"clean-webpack-plugin": "4.0.0",

View File

@ -12,7 +12,6 @@ import {
IKeyRemapping,
IModeSpecificStrings,
IAutoSwitchInputMethod,
IDebugConfiguration,
IHighlightedYankConfiguration,
ICamelCaseMotionConfiguration,
ITargetsConfiguration,
@ -312,12 +311,6 @@ class Configuration implements IConfiguration {
replace: '#000000',
};
debug: IDebugConfiguration = {
silent: false,
loggingLevelForAlert: 'error',
loggingLevelForConsole: 'error',
};
searchHighlightColor = '';
searchHighlightTextColor = '';

View File

@ -33,24 +33,6 @@ export interface IAutoSwitchInputMethod {
obtainIMCmd: string;
}
export interface IDebugConfiguration {
/**
* Boolean indicating whether all logs should be suppressed
* This value overrides both `loggingLevelForAlert` and `loggingLevelForConsole`
*/
silent: boolean;
/**
* Maximum level of messages to show as VS Code information message
*/
loggingLevelForAlert: 'error' | 'warn' | 'info' | 'verbose' | 'debug';
/**
* Maximum level of messages to log to console.
*/
loggingLevelForConsole: 'error' | 'warn' | 'info' | 'verbose' | 'debug';
}
export interface IHighlightedYankConfiguration {
/**
* Boolean indicating whether yank highlighting should be enabled.
@ -269,11 +251,6 @@ export interface IConfiguration {
*/
statusBarColors: IModeSpecificStrings<string | string[]>;
/**
* Extension debugging settings
*/
debug: IDebugConfiguration;
/**
* Color of search highlights.
*/

View File

@ -545,11 +545,11 @@ export class Remapper implements IRemapper {
for (let sliceLength = startingSliceLength; sliceLength >= range[0]; sliceLength--) {
const keySlice = inputtedKeys.slice(-sliceLength).join('');
this.logger.verbose(`key=${inputtedKeys}. keySlice=${keySlice}.`);
this.logger.debug(`key=${inputtedKeys}. keySlice=${keySlice}.`);
if (userDefinedRemappings.has(keySlice)) {
const precedingKeys = inputtedString.slice(0, inputtedString.length - keySlice.length);
if (precedingKeys.length > 0 && !/^[0-9]+$/.test(precedingKeys)) {
this.logger.verbose(
this.logger.debug(
`key sequences need to match precisely. precedingKeys=${precedingKeys}.`
);
break;

View File

@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { ILogger } from '../common/logger';
import { Logger } from '../../util/logger';
export class HistoryBase {
private readonly context: vscode.ExtensionContext;
@ -14,7 +14,7 @@ export class HistoryBase {
context: vscode.ExtensionContext,
historyFileName: string,
extensionStoragePath: string,
logger: ILogger
logger: Logger
) {
this.context = context;
this.historyFileName = historyFileName;

View File

@ -1,65 +0,0 @@
import { IConfiguration } from '../../configuration/iconfiguration';
import { ILogger } from 'src/platform/common/logger';
/**
* Displays VSCode message to user
*/
export class VsCodeMessage implements ILogger {
actionMessages = ['Dismiss', 'Suppress Errors'];
private prefix: string;
configuration?: IConfiguration;
constructor(prefix: string) {
this.prefix = prefix;
}
error(errorMessage: string): void {
this.log({ level: 'error', message: errorMessage });
}
debug(debugMessage: string): void {
this.log({ level: 'debug', message: debugMessage });
}
warn(warnMessage: string): void {
this.log({ level: 'warn', message: warnMessage });
}
verbose(verboseMessage: string): void {
this.log({ level: 'verbose', message: verboseMessage });
}
private async log(info: { level: string; message: string }) {
if (this.configuration && this.configuration.debug.silent) {
return;
}
let showMessage: (message: string, ...items: string[]) => void;
switch (info.level) {
case 'error':
showMessage = console.error;
break;
case 'warn':
showMessage = console.warn;
break;
case 'info':
case 'verbose':
case 'debug':
showMessage = console.log;
break;
default:
throw Error(`Unsupported log level ${info.level}`);
}
showMessage(`${this.prefix}: ${info.message}`, ...this.actionMessages);
}
public configChanged(configuration: IConfiguration): void {
this.configuration = configuration;
}
}
export class LoggerImpl {
static get(prefix: string): ILogger {
return new VsCodeMessage(prefix);
}
}

View File

@ -1,9 +0,0 @@
import { IConfiguration } from 'src/configuration/iconfiguration';
export interface ILogger {
error(errorMessage: string): void;
debug(debugMessage: string): void;
warn(warnMessage: string): void;
verbose(verboseMessage: string): void;
configChanged(configuration: IConfiguration): void;
}

View File

@ -1,12 +1,12 @@
import * as vscode from 'vscode';
import * as path from 'path';
import { readFileAsync, mkdirAsync, writeFileAsync, unlinkSync } from 'platform/fs';
import { ILogger } from '../common/logger';
import { Globals } from '../../globals';
import { Logger } from '../../util/logger';
export class HistoryBase {
private readonly extensionStoragePath: string;
private readonly logger: ILogger;
private readonly logger: Logger;
private readonly historyFileName: string;
private history: string[] = [];
@ -18,7 +18,7 @@ export class HistoryBase {
context: vscode.ExtensionContext,
historyFileName: string,
extensionStoragePath: string,
logger: ILogger
logger: Logger
) {
this.historyFileName = historyFileName;
this.extensionStoragePath = extensionStoragePath;

View File

@ -1,112 +0,0 @@
import * as TransportStream from 'winston-transport';
import * as vscode from 'vscode';
import * as winston from 'winston';
import { ConsoleForElectron } from 'winston-console-for-electron';
import { IConfiguration } from '../../configuration/iconfiguration';
import { ILogger } from '../common/logger';
interface VsCodeMessageOptions extends TransportStream.TransportStreamOptions {
prefix?: string;
}
/**
* Implementation of Winston transport
* Displays VSCode message to user
*/
class VsCodeMessage extends TransportStream {
prefix?: string;
configuration?: IConfiguration;
actionMessages = ['Dismiss', 'Suppress Errors'];
constructor(options: VsCodeMessageOptions) {
super(options);
this.prefix = options.prefix;
}
public override async log(info: { level: string; message: string }, callback: () => void) {
if (this.configuration && this.configuration.debug.silent) {
return;
}
let showMessage: (message: string, ...items: string[]) => Thenable<string | undefined>;
switch (info.level) {
case 'error':
showMessage = vscode.window.showErrorMessage;
break;
case 'warn':
showMessage = vscode.window.showWarningMessage;
break;
case 'info':
case 'verbose':
case 'debug':
showMessage = vscode.window.showInformationMessage;
break;
default:
throw Error(`Unsupported log level ${info.level}`);
}
const message = `${this.prefix}: ${info.message}`;
const selectedAction = await showMessage(message, ...this.actionMessages);
if (selectedAction === 'Suppress Errors' && this.configuration) {
vscode.window.showInformationMessage(
'Ignorance is bliss; temporarily suppressing log messages. For more permanence, please configure `vim.debug.silent`.'
);
this.configuration.debug.silent = true;
}
if (callback) {
callback();
}
}
}
class NodeLogger implements ILogger {
private logger: winston.Logger;
constructor(prefix: string) {
this.logger = winston.createLogger({
format: winston.format.simple(),
level: 'debug', // filtering will be done at the transport level
transports: [
new ConsoleForElectron({
level: 'error',
silent: false,
prefix,
}),
new VsCodeMessage({
level: 'error',
prefix,
}),
],
});
}
public error(errorMessage: string): void {
this.logger.error(errorMessage);
}
public debug(debugMessage: string): void {
this.logger.debug(debugMessage);
}
public warn(warnMessage: string): void {
this.logger.warn(warnMessage);
}
public verbose(verboseMessage: string): void {
this.logger.verbose(verboseMessage);
}
public configChanged(configuration: IConfiguration) {
this.logger.transports[0].level = configuration.debug.loggingLevelForConsole;
this.logger.transports[0].silent = configuration.debug.silent;
this.logger.transports[1].level = configuration.debug.loggingLevelForAlert;
(this.logger.transports[1] as VsCodeMessage).configuration = configuration;
}
}
export class LoggerImpl {
static get(prefix: string): ILogger {
return new NodeLogger(prefix);
}
}

View File

@ -1,28 +1,42 @@
import { ILogger } from 'src/platform/common/logger';
import { LoggerImpl } from 'platform/loggerImpl';
import { IConfiguration } from 'src/configuration/iconfiguration';
import { LogOutputChannel, window } from 'vscode';
export class Logger {
private static readonly cache = new Map<string, ILogger>();
private static configuration: IConfiguration | undefined = undefined;
private static output: LogOutputChannel | undefined;
private static readonly cache = new Map<string, Logger>();
static get(prefix: string): Logger {
if (!this.output) {
this.output = window.createOutputChannel('Vim', { log: true });
}
static get(prefix: string): ILogger {
let logger = Logger.cache.get(prefix);
if (logger === undefined) {
logger = LoggerImpl.get(prefix);
if (Logger.configuration) {
logger.configChanged(Logger.configuration);
}
logger = new Logger(prefix);
Logger.cache.set(prefix, logger);
}
return logger;
}
static configChanged(configuration: IConfiguration) {
Logger.configuration = configuration;
for (const logger of this.cache.values()) {
logger.configChanged(configuration);
}
private scope: string;
private constructor(scope: string) {
this.scope = scope;
}
error(msg: string): void {
Logger.output?.error(`[${this.scope}] ${msg}`);
}
warn(msg: string): void {
Logger.output?.warn(`[${this.scope}] ${msg}`);
}
info(msg: string): void {
Logger.output?.info(`[${this.scope}] ${msg}`);
}
debug(msg: string): void {
Logger.output?.debug(`[${this.scope}] ${msg}`);
}
trace(msg: string): void {
Logger.output?.trace(`[${this.scope}] ${msg}`);
}
}

View File

@ -2,7 +2,6 @@ import * as vscode from 'vscode';
import {
IConfiguration,
IDebugConfiguration,
IHighlightedYankConfiguration,
IKeyRemapping,
IModeSpecificStrings,
@ -76,11 +75,6 @@ export class Configuration implements IConfiguration {
visualblock: '#A3BE8C',
replace: '#D08770',
};
debug: IDebugConfiguration = {
silent: false,
loggingLevelForAlert: 'error',
loggingLevelForConsole: 'warn',
};
searchHighlightColor = 'rgba(150, 150, 255, 0.3)';
searchHighlightTextColor = '';
searchMatchColor = 'rgba(255, 150, 150, 0.3)';

View File

@ -3,7 +3,7 @@
"@babel/code-frame@^7.0.0":
version "7.11.3"
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
dependencies:
@ -44,11 +44,6 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@dabh/diagnostics@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31"
@ -305,10 +300,10 @@
dependencies:
source-map "^0.6.0"
"@types/vscode@1.67.0":
version "1.67.0"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.67.0.tgz#8eaba41d1591aa02f5d960b7dfae3b16e066f08c"
integrity sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==
"@types/vscode@1.74.0":
version "1.74.0"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.74.0.tgz#4adc21b4e7f527b893de3418c21a91f1e503bdcd"
integrity sha512-LyeCIU3jb9d38w0MXFwta9r0Jx23ugujkAxdwLTNCyspdZTKUc43t7ppPbCiPoQ/Ivd/pnDFZrb4hWd45wrsgA==
"@vscode/test-electron@2.2.1":
version "2.2.1"
@ -756,7 +751,7 @@ async-settle@^1.0.0:
dependencies:
async-done "^1.2.2"
async@^3.1.0, async@^3.2.3:
async@^3.1.0:
version "3.2.3"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
@ -1284,7 +1279,7 @@ colorette@^2.0.14:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
colors@1.4.0, colors@^1.2.1:
colors@^1.2.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
@ -3364,28 +3359,6 @@ logform@^2.2.0:
ms "^2.1.1"
triple-beam "^1.3.0"
logform@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.2.tgz#68babe6a74ab09a1fd15a9b1e6cbc7713d41cb5b"
integrity sha512-V6JiPThZzTsbVRspNO6TmHkR99oqYTs8fivMBYQkjZj6rxW92KxtDCPE6IkAk1DNBnYKNkjm4jYBm6JDUcyhOA==
dependencies:
colors "1.4.0"
fecha "^4.2.0"
ms "^2.1.1"
safe-stable-stringify "^1.1.0"
triple-beam "^1.3.0"
logform@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.0.tgz#131651715a17d50f09c2a2c1a524ff1a4164bcfe"
integrity sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==
dependencies:
"@colors/colors" "1.5.0"
fecha "^4.2.0"
ms "^2.1.1"
safe-stable-stringify "^2.3.1"
triple-beam "^1.3.0"
loud-rejection@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
@ -4336,7 +4309,7 @@ read@^1.0.7:
dependencies:
mute-stream "~0.0.4"
"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@ -4561,16 +4534,6 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
safe-stable-stringify@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a"
integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==
safe-stable-stringify@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73"
integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==
sax@>=0.6.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@ -5718,29 +5681,6 @@ wildcard@^2.0.0:
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
winston-console-for-electron@0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/winston-console-for-electron/-/winston-console-for-electron-0.0.6.tgz#c6a56e5cfa9b5fe3d0903743ab7734ccadd1c4df"
integrity sha512-4oc83FpZ04CC+Rne1ljh6ysl/fzUbE7fmIacjgh+1CDU3xBCpgqfNYRrcw6rL0yTOCJ8e4Fk2CYnOgBhWao1iA==
dependencies:
winston-transport "4.1.0"
winston-transport@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.1.0.tgz#4eedb6e3ad79bdd8a682e380abebd7b80951e797"
integrity sha512-rNMfXfGfTyiOrAJ9KLLy0nlow98NyD0oNCOSnP3jnNVHoKsJGLDsa8BaOH+ftKDR5pZKJMBhbQNEft7Vr+dJLw==
dependencies:
triple-beam "^1.2.0"
winston-transport@4.5.0, winston-transport@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa"
integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==
dependencies:
logform "^2.3.2"
readable-stream "^3.6.0"
triple-beam "^1.3.0"
winston-transport@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59"
@ -5764,23 +5704,6 @@ winston@3.3.3:
triple-beam "^1.3.0"
winston-transport "^4.4.0"
winston@3.8.2:
version "3.8.2"
resolved "https://registry.yarnpkg.com/winston/-/winston-3.8.2.tgz#56e16b34022eb4cff2638196d9646d7430fdad50"
integrity sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==
dependencies:
"@colors/colors" "1.5.0"
"@dabh/diagnostics" "^2.0.2"
async "^3.2.3"
is-stream "^2.0.0"
logform "^2.4.0"
one-time "^1.0.0"
readable-stream "^3.4.0"
safe-stable-stringify "^2.3.1"
stack-trace "0.0.x"
triple-beam "^1.3.0"
winston-transport "^4.5.0"
workerpool@6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"