Skip to content

Commit e1ffe98

Browse files
committed
Minor change to logger
1 parent a833b08 commit e1ffe98

File tree

5 files changed

+88
-58
lines changed

5 files changed

+88
-58
lines changed

package.json

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,17 @@
8888
"configuration": {
8989
"title": "ResX Editor",
9090
"properties": {
91-
"resx-editor.verboseLogging": {
92-
"type": "boolean",
93-
"default": false,
94-
"description": "Enable verbose logging"
91+
"resx-editor.loggingLevel": {
92+
"type": "string",
93+
"default": "error",
94+
"enum": [
95+
"off",
96+
"error",
97+
"warn",
98+
"info",
99+
"verbose"
100+
],
101+
"description": "Set the logging level"
95102
},
96103
"resx-editor.generateCode": {
97104
"type": "boolean",

src/extension.ts

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import * as vscode from 'vscode';
22
import { ResxProvider } from './resxProvider';
33
import { AppConstants } from './utilities/constants';
4+
import { Logger } from './logger';
45

5-
let outputChannel: vscode.OutputChannel;
6+
let outputChannel: vscode.LogOutputChannel;
67

78
export function activate(context: vscode.ExtensionContext) {
89

9-
outputChannel = vscode.window.createOutputChannel("ResX Editor");
10+
outputChannel = vscode.window.createOutputChannel("ResX Editor", { log: true });
1011

11-
printChannelOutput("ResX Editor extension activated.", true);
12+
Logger.instance.info("ResX Editor extension activated.");
1213

1314
let openPreviewCommand = vscode.commands.registerCommand(AppConstants.openPreviewCommand, () => {
1415

@@ -42,40 +43,4 @@ export function activate(context: vscode.ExtensionContext) {
4243

4344
}
4445

45-
export enum LogLevel {
46-
Info = 'INF',
47-
Warn = 'WRN',
48-
Error = 'ERR'
49-
}
50-
51-
/**
52-
* Prints the given content on the output channel.
53-
*
54-
* @param content The content to be printed.
55-
* @param verbose Whether this should be included only in verbose logging
56-
* @param reveal Whether the output channel should be revealed.
57-
* @param level The log level for the output.
58-
*/
59-
export const printChannelOutput = (content: string, verbose: boolean, reveal = false, level: LogLevel = LogLevel.Info): void => {
60-
try {
61-
if (!outputChannel) {
62-
return;
63-
}
64-
if (verbose && !vscode.workspace.getConfiguration("resx-editor").get("verboseLogging")) {
65-
return;
66-
}
67-
68-
const timestamp = new Date().toISOString();
69-
70-
outputChannel.appendLine(`[${timestamp}] [${level}] ${content}`);
71-
72-
if (reveal) {
73-
outputChannel.show(true);
74-
}
75-
}
76-
catch (e) {
77-
console.log(e);
78-
}
79-
};
80-
8146
export function deactivate() { }

src/logger.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as vscode from 'vscode';
2+
3+
type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'verbose';
4+
5+
export class Logger {
6+
private static _instance: Logger;
7+
private readonly channel: vscode.LogOutputChannel;
8+
private logLevel: LogLevel;
9+
10+
private constructor() {
11+
this.channel = vscode.window.createOutputChannel("ResX Editor", { log: true });
12+
this.logLevel = vscode.workspace.getConfiguration("resx-editor").get("loggingLevel", "info");
13+
14+
vscode.workspace.onDidChangeConfiguration(e => {
15+
if (e.affectsConfiguration("resx-editor.loggingLevel")) {
16+
this.logLevel = this.getConfigLevel();
17+
}
18+
});
19+
}
20+
21+
public static get instance(): Logger {
22+
if (!Logger._instance) {
23+
Logger._instance = new Logger(); }
24+
return Logger._instance;
25+
}
26+
27+
private getConfigLevel(): LogLevel {
28+
return vscode.workspace.getConfiguration("resx-editor").get<LogLevel>("loggingLevel", "info");
29+
}
30+
31+
public info(message: string) {
32+
if (this.shouldLog("info")) {this.channel.info(message);}
33+
}
34+
35+
public warn(message: string) {
36+
if (this.shouldLog("warn")) {this.channel.warn(message);}
37+
}
38+
39+
public error(message: string) {
40+
if (this.shouldLog("error")) {this.channel.error(message);}
41+
}
42+
43+
private shouldLog(level: LogLevel): boolean {
44+
// If logging is turned off, don't log anything
45+
if (this.logLevel === 'off') {
46+
return false;
47+
}
48+
49+
// If verbose mode is enabled, always log everything
50+
if (this.logLevel === 'verbose') {
51+
return level !== 'off' && level !== 'verbose';
52+
}
53+
54+
// Otherwise, honor the log level hierarchy
55+
const levels: LogLevel[] = ["off", "error", "warn", "info", "verbose"];
56+
return levels.indexOf(level) <= levels.indexOf(this.logLevel);
57+
}
58+
}

src/resxProvider.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
22
import * as resx from 'resx';
33
import * as path from 'path';
44
import { getNonce } from './utilities/getNonce';
5-
import { LogLevel, printChannelOutput } from './extension';
5+
import { Logger } from './logger';
66
import { newResourceInput } from './addNewResource';
77
import { AppConstants } from './utilities/constants';
88
import { generateAndUpdateDesignerFile } from './utilities/generateCode';
@@ -13,7 +13,7 @@ export class ResxProvider implements vscode.CustomTextEditorProvider {
1313
public static register(context: vscode.ExtensionContext): vscode.Disposable {
1414
const provider = new ResxProvider(context);
1515
const providerRegistration = vscode.window.registerCustomEditorProvider(ResxProvider.viewType, provider);
16-
printChannelOutput("ResX Editor custom editor provider registered.", true);
16+
Logger.instance.info("ResX Editor custom editor provider registered.");
1717
return providerRegistration;
1818
}
1919

@@ -41,7 +41,7 @@ export class ResxProvider implements vscode.CustomTextEditorProvider {
4141
});
4242

4343
try {
44-
printChannelOutput(document.uri.toString(), true);
44+
Logger.instance.info(document.uri.toString());
4545
if (!this.registered) {
4646
this.registered = true;
4747
let deleteCommand = vscode.commands.registerCommand(AppConstants.deleteResourceCommand, () => {
@@ -66,7 +66,7 @@ export class ResxProvider implements vscode.CustomTextEditorProvider {
6666
});
6767

6868
let openInTextEditorCommand = vscode.commands.registerCommand(AppConstants.openInTextEditorCommand, () => {
69-
printChannelOutput("openInTextEditor command called", true);
69+
Logger.instance.info("openInTextEditor command called");
7070
vscode.commands.executeCommand('workbench.action.reopenTextEditor', document?.uri);
7171
});
7272

@@ -102,14 +102,14 @@ export class ResxProvider implements vscode.CustomTextEditorProvider {
102102
this.updateTextDocument(document, e.json);
103103
return;
104104
case 'log':
105-
printChannelOutput(e.message, true);
105+
Logger.instance.info(e.message);
106106
return;
107107
case 'error':
108-
printChannelOutput(e.message, true, true, LogLevel.Error);
108+
Logger.instance.error(e.message);
109109
vscode.window.showErrorMessage(e.message);
110110
return;
111111
case 'info':
112-
printChannelOutput(e.message, true);
112+
Logger.instance.info(e.message);
113113
vscode.window.showInformationMessage(e.message);
114114
return;
115115
case 'add':
@@ -149,15 +149,15 @@ export class ResxProvider implements vscode.CustomTextEditorProvider {
149149
if (success) {
150150
const config = vscode.workspace.getConfiguration('resx-editor');
151151
const generateCode = config.get<boolean>('generateCode', true);
152-
printChannelOutput(`Successfully updated RESX${generateCode ? ' and Designer' : ''} files`, true);
152+
Logger.instance.info(`Successfully updated RESX${generateCode ? ' and Designer' : ''} files`);
153153
} else {
154-
printChannelOutput(`Failed to apply workspace edits`, true, true, LogLevel.Error);
154+
Logger.instance.error(`Failed to apply workspace edits`);
155155
vscode.window.showErrorMessage('Failed to update resource files');
156156
}
157157
return success;
158158
} catch (error) {
159159
const errorMessage = `Error updating resource files: ${error instanceof Error ? error.message : String(error)}`;
160-
printChannelOutput(errorMessage, true, true, LogLevel.Error);
160+
Logger.instance.error(errorMessage);
161161
vscode.window.showErrorMessage(errorMessage);
162162
return false;
163163
}

src/utilities/generateCode.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
22
import * as fs from 'fs';
33
import * as path from 'path';
44
import { generateDesignerCode } from './designerGenerator';
5-
import { printChannelOutput } from '../extension';
5+
import { Logger } from '../logger';
66

77
async function extractExistingNamespace(designerPath: string): Promise<string | undefined> {
88
try {
@@ -53,7 +53,7 @@ async function checkResxGeneratorType(resxPath: string): Promise<'public' | 'int
5353
}
5454
}
5555
} catch (error) {
56-
printChannelOutput(`Error reading .csproj file: ${error}`, true);
56+
Logger.instance.error(`Error reading .csproj file: ${error}`);
5757
}
5858
}
5959

@@ -84,14 +84,14 @@ export async function generateAndUpdateDesignerFile(document: vscode.TextDocumen
8484
try {
8585
await vscode.workspace.fs.stat(designerUri);
8686
// File exists, write contents directly
87-
printChannelOutput(`Updating existing Designer file at ${designerPath}`, true);
87+
Logger.instance.info(`Updating existing Designer file at ${designerPath}`);
8888
await vscode.workspace.fs.writeFile(designerUri, Buffer.from(designerCode, 'utf8'));
8989
} catch {
9090
// File doesn't exist, create it
91-
printChannelOutput(`Creating new Designer file at ${designerPath}`, true);
91+
Logger.instance.info(`Creating new Designer file at ${designerPath}`);
9292
await vscode.workspace.fs.writeFile(designerUri, Buffer.from(designerCode, 'utf8'));
9393
}
9494
} else {
95-
printChannelOutput('Code generation is disabled, skipping Designer.cs file update', true);
95+
Logger.instance.info('Code generation is disabled, skipping Designer.cs file update');
9696
}
9797
}

0 commit comments

Comments
 (0)