Skip to content

Commit 8d21d95

Browse files
Add configurable logging levels to control debug message visibility (#3)
* Initial plan * Implement logging level options functionality Co-authored-by: HeyItsGilbert <615265+HeyItsGilbert@users.noreply.github.com> * Add Unreleased section to changelog with logging levels feature Co-authored-by: HeyItsGilbert <615265+HeyItsGilbert@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: HeyItsGilbert <615265+HeyItsGilbert@users.noreply.github.com>
1 parent 2a8d4f9 commit 8d21d95

6 files changed

Lines changed: 125 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ in this file.
66
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
77
to structure this file.
88

9+
## [Unreleased]
10+
11+
### Added
12+
- Configurable logging levels to control debug message visibility
13+
- New `powershellLocalization.logLevel` setting with four hierarchical levels:
14+
- `error` - Only error messages
15+
- `warn` - Error and warning messages
16+
- `info` - Error, warning, and info messages (default)
17+
- `debug` - All messages including debug output
18+
- Smart log filtering that respects the configured log level
19+
- Debug messages are now filtered out by default, providing cleaner output
20+
921
## [0.1.0] Initial Release
1022

1123
- Foundational script `LocalizationParser` looks for `psm1` that container

package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@
6767
"**/.git/**"
6868
],
6969
"description": "Configure glob patterns for excluding directories and files from PowerShell module scanning."
70+
},
71+
"powershellLocalization.logLevel": {
72+
"type": "string",
73+
"enum": [
74+
"error",
75+
"warn",
76+
"info",
77+
"debug"
78+
],
79+
"default": "info",
80+
"description": "Set the logging level for the PowerShell Localization extension. Debug logs are only shown when set to 'debug'."
7081
}
7182
}
7283
}

src/configuration.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as vscode from 'vscode';
2-
import { ExtensionConfig } from './types';
2+
import { ExtensionConfig, LogLevel } from './types';
33
import { CONFIGURATION_BASENAME } from './utils';
44

55
/**
@@ -20,7 +20,8 @@ export class ConfigurationManager {
2020
'**/out/**',
2121
'**/dist/**',
2222
'**/.git/**'
23-
])
23+
]),
24+
logLevel: config.get<LogLevel>('logLevel', 'info')
2425
};
2526
}
2627

@@ -45,6 +46,13 @@ export class ConfigurationManager {
4546
return this.getConfiguration().searchExclude;
4647
}
4748

49+
/**
50+
* Gets the current log level
51+
*/
52+
public static getLogLevel(): LogLevel {
53+
return this.getConfiguration().logLevel;
54+
}
55+
4856
/**
4957
* Registers configuration change listener
5058
*/

src/logger.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
import * as vscode from 'vscode';
22
import { EXTENSION_NAME, Utils } from './utils';
3+
import { LogLevel } from './types';
4+
import { ConfigurationManager } from './configuration';
35

46
/**
57
* Logging utility for the PowerShell Localization extension
68
*/
79
export class Logger {
810
private static instance: Logger;
911
private outputChannel: vscode.OutputChannel;
12+
private static readonly LOG_LEVELS: Record<LogLevel, number> = {
13+
error: 0,
14+
warn: 1,
15+
info: 2,
16+
debug: 3
17+
};
1018

1119
private constructor() {
1220
this.outputChannel = vscode.window.createOutputChannel(EXTENSION_NAME);
@@ -22,36 +30,52 @@ export class Logger {
2230
return Logger.instance;
2331
}
2432

33+
/**
34+
* Checks if a message should be logged based on the current log level
35+
*/
36+
private shouldLog(messageLevel: LogLevel): boolean {
37+
const currentLevel = ConfigurationManager.getLogLevel();
38+
return Logger.LOG_LEVELS[messageLevel] <= Logger.LOG_LEVELS[currentLevel];
39+
}
40+
2541
/**
2642
* Logs an informational message
2743
*/
2844
public info(message: string): void {
29-
this.outputChannel.appendLine(`[INFO] ${Utils.formatTimestamp()}: ${message}`);
45+
if (this.shouldLog('info')) {
46+
this.outputChannel.appendLine(`[INFO] ${Utils.formatTimestamp()}: ${message}`);
47+
}
3048
}
3149

3250
/**
3351
* Logs an error message
3452
*/
3553
public error(message: string, error?: Error): void {
36-
const errorMessage = error ? `${message}: ${error.message}` : message;
37-
this.outputChannel.appendLine(`[ERROR] ${Utils.formatTimestamp()}: ${errorMessage}`);
38-
if (error?.stack) {
39-
this.outputChannel.appendLine(`Stack trace: ${error.stack}`);
54+
if (this.shouldLog('error')) {
55+
const errorMessage = error ? `${message}: ${error.message}` : message;
56+
this.outputChannel.appendLine(`[ERROR] ${Utils.formatTimestamp()}: ${errorMessage}`);
57+
if (error?.stack) {
58+
this.outputChannel.appendLine(`Stack trace: ${error.stack}`);
59+
}
4060
}
4161
}
4262

4363
/**
4464
* Logs a warning message
4565
*/
4666
public warn(message: string): void {
47-
this.outputChannel.appendLine(`[WARN] ${Utils.formatTimestamp()}: ${message}`);
67+
if (this.shouldLog('warn')) {
68+
this.outputChannel.appendLine(`[WARN] ${Utils.formatTimestamp()}: ${message}`);
69+
}
4870
}
4971

5072
/**
5173
* Logs a debug message
5274
*/
5375
public debug(message: string): void {
54-
this.outputChannel.appendLine(`[DEBUG] ${Utils.formatTimestamp()}: ${message}`);
76+
if (this.shouldLog('debug')) {
77+
this.outputChannel.appendLine(`[DEBUG] ${Utils.formatTimestamp()}: ${message}`);
78+
}
5579
}
5680

5781
/**

src/test/extension.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ Write-Host $LocalizedData.Key2
231231
});
232232
});
233233

234+
test('Should have log level configuration', () => {
235+
const config = vscode.workspace.getConfiguration('powershellLocalization');
236+
237+
// Test that the log level configuration exists
238+
const logLevel = config.get('logLevel');
239+
assert.strictEqual(typeof logLevel, 'string', 'logLevel should be a string');
240+
241+
// Check that it's one of the valid values
242+
const validLevels = ['error', 'warn', 'info', 'debug'];
243+
assert.ok(validLevels.includes(logLevel as string), 'logLevel should be one of the valid values');
244+
245+
// Check default value
246+
assert.strictEqual(logLevel, 'info', 'Default log level should be info');
247+
});
248+
234249
test('Should respect configuration changes', async () => {
235250
const config = vscode.workspace.getConfiguration('powershellLocalization');
236251
const originalValue = config.get('enableInlineValues');
@@ -430,4 +445,47 @@ function Test-Function {
430445
'No paths should be excluded when patterns array is empty');
431446
});
432447
});
448+
449+
suite('Logger Functionality', () => {
450+
test('Should respect log level configuration for debug messages', () => {
451+
// This test verifies the logger respects the log level setting
452+
// Since we can't easily mock the configuration in this test environment,
453+
// we'll test the log level logic conceptually
454+
455+
const logLevels = ['error', 'warn', 'info', 'debug'];
456+
const logLevelPriorities = { error: 0, warn: 1, info: 2, debug: 3 };
457+
458+
// Test that debug messages should be filtered when log level is info
459+
const currentLevel = 'info';
460+
const debugLevel = 'debug';
461+
462+
const shouldShowDebug = logLevelPriorities[debugLevel] <= logLevelPriorities[currentLevel];
463+
assert.strictEqual(shouldShowDebug, false, 'Debug messages should not show when log level is info');
464+
465+
// Test that info messages should show when log level is info
466+
const infoLevel = 'info';
467+
const shouldShowInfo = logLevelPriorities[infoLevel] <= logLevelPriorities[currentLevel];
468+
assert.strictEqual(shouldShowInfo, true, 'Info messages should show when log level is info');
469+
470+
// Test that error messages always show
471+
const errorLevel = 'error';
472+
const shouldShowError = logLevelPriorities[errorLevel] <= logLevelPriorities[currentLevel];
473+
assert.strictEqual(shouldShowError, true, 'Error messages should always show');
474+
});
475+
476+
test('Should have valid log level hierarchy', () => {
477+
const logLevels = ['error', 'warn', 'info', 'debug'];
478+
const logLevelPriorities = { error: 0, warn: 1, info: 2, debug: 3 };
479+
480+
// Verify hierarchy is correct (lower numbers = higher priority)
481+
assert.ok(logLevelPriorities.error < logLevelPriorities.warn, 'Error should have higher priority than warn');
482+
assert.ok(logLevelPriorities.warn < logLevelPriorities.info, 'Warn should have higher priority than info');
483+
assert.ok(logLevelPriorities.info < logLevelPriorities.debug, 'Info should have higher priority than debug');
484+
485+
// Verify all levels are represented
486+
logLevels.forEach(level => {
487+
assert.ok(level in logLevelPriorities, `Log level ${level} should be in priorities`);
488+
});
489+
});
490+
});
433491
});

src/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ export interface ExtensionConfig {
1717
enableInlineValues: boolean;
1818
enableDecorations: boolean;
1919
searchExclude: string[];
20+
logLevel: LogLevel;
2021
}
22+
23+
export type LogLevel = 'error' | 'warn' | 'info' | 'debug';

0 commit comments

Comments
 (0)