diff --git a/packages/chirp/lib/src/writers/console_writer.dart b/packages/chirp/lib/src/writers/console_writer.dart index 3ed135e..3ea0d86 100644 --- a/packages/chirp/lib/src/writers/console_writer.dart +++ b/packages/chirp/lib/src/writers/console_writer.dart @@ -115,15 +115,21 @@ class PrintConsoleWriter extends ChirpWriter { /// /// Falls back to [RainbowMessageFormatter] if no [formatter] is provided. /// Use [output] to redirect logs for testing or alternative destinations. + /// Use [minLevel] to filter out logs below a certain level. PrintConsoleWriter({ ConsoleMessageFormatter? formatter, int? maxChunkLength, TerminalCapabilities? capabilities, void Function(String)? output, + ChirpLogLevel? minLevel, }) : formatter = formatter ?? RainbowMessageFormatter(), maxChunkLength = maxChunkLength ?? platformPrintMaxChunkLength, capabilities = capabilities ?? TerminalCapabilities.autoDetect(), - output = output ?? print; + output = output ?? print { + if (minLevel != null) { + setMinLogLevel(minLevel); + } + } @override bool get requiresCallerInfo => formatter.requiresCallerInfo; diff --git a/packages/chirp/lib/src/writers/developer_log_console_writer.dart b/packages/chirp/lib/src/writers/developer_log_console_writer.dart index 37cafa5..ed093df 100644 --- a/packages/chirp/lib/src/writers/developer_log_console_writer.dart +++ b/packages/chirp/lib/src/writers/developer_log_console_writer.dart @@ -53,10 +53,15 @@ class DeveloperLogConsoleWriter extends ChirpWriter { /// /// Use this for development with a debugger attached to see unlimited-length /// log output. Falls back to [RainbowMessageFormatter] if no [formatter] - /// is provided. + /// is provided. Use [minLevel] to filter out logs below a certain level. DeveloperLogConsoleWriter({ ConsoleMessageFormatter? formatter, - }) : formatter = formatter ?? RainbowMessageFormatter(); + ChirpLogLevel? minLevel, + }) : formatter = formatter ?? RainbowMessageFormatter() { + if (minLevel != null) { + setMinLogLevel(minLevel); + } + } @override bool get requiresCallerInfo => formatter.requiresCallerInfo; diff --git a/packages/chirp/lib/src/writers/file_writer.dart b/packages/chirp/lib/src/writers/file_writer.dart index 90cff9f..3063de1 100644 --- a/packages/chirp/lib/src/writers/file_writer.dart +++ b/packages/chirp/lib/src/writers/file_writer.dart @@ -397,6 +397,16 @@ class JsonFileFormatter implements FileMessageFormatter { /// ); /// ``` /// +/// ## Level Filtering +/// +/// ```dart +/// // Only write warnings and above to file +/// final writer = RotatingFileWriter( +/// baseFilePath: '/var/log/errors.log', +/// minLevel: ChirpLogLevel.warning, +/// ); +/// ``` +/// /// ## File Extensions /// /// Choose the file extension based on the formatter: @@ -465,13 +475,19 @@ class RotatingFileWriter extends ChirpWriter { /// - [rotationConfig]: Rotation settings, or `null` for no rotation /// - [encoding]: Text encoding (default: UTF-8) /// - [onError]: Handler for write failures (default: prints to stderr) + /// - [minLevel]: Minimum log level to write (default: `null` - accept all) RotatingFileWriter({ required this.baseFilePath, FileMessageFormatter? formatter, this.rotationConfig, this.encoding = utf8, this.onError, - }) : formatter = formatter ?? const SimpleFileFormatter(); + ChirpLogLevel? minLevel, + }) : formatter = formatter ?? const SimpleFileFormatter() { + if (minLevel != null) { + setMinLogLevel(minLevel); + } + } /// Opens the log file for writing. /// diff --git a/packages/chirp/test/console_writer_test.dart b/packages/chirp/test/console_writer_test.dart index 92ea52f..904e62f 100644 --- a/packages/chirp/test/console_writer_test.dart +++ b/packages/chirp/test/console_writer_test.dart @@ -794,6 +794,50 @@ void main() { expect(outputs[0].length, 1000); }); }); + + group('PrintConsoleWriter minLevel', () { + test('minLevel constructor parameter sets minLogLevel', () { + final writer = PrintConsoleWriter( + minLevel: ChirpLogLevel.warning, + ); + expect(writer.minLogLevel, ChirpLogLevel.warning); + }); + + test('minLevel null does not set minLogLevel', () { + final writer = PrintConsoleWriter(); + expect(writer.minLogLevel, isNull); + }); + + test('minLevel filters messages when used with logger', () { + final outputs = []; + final writer = PrintConsoleWriter( + formatter: _TestFormatter('test'), + output: outputs.add, + minLevel: ChirpLogLevel.warning, + ); + + final logger = ChirpLogger(name: 'Test').addWriter(writer); + + logger.info('should not appear'); + logger.warning('should appear'); + + expect(outputs.length, 1); + }); + }); + + group('DeveloperLogConsoleWriter minLevel', () { + test('minLevel constructor parameter sets minLogLevel', () { + final writer = DeveloperLogConsoleWriter( + minLevel: ChirpLogLevel.error, + ); + expect(writer.minLogLevel, ChirpLogLevel.error); + }); + + test('minLevel null does not set minLogLevel', () { + final writer = DeveloperLogConsoleWriter(); + expect(writer.minLogLevel, isNull); + }); + }); } /// Test formatter that always outputs the given text. diff --git a/packages/chirp/test/file_writer_test.dart b/packages/chirp/test/file_writer_test.dart index 115e869..b83eff5 100644 --- a/packages/chirp/test/file_writer_test.dart +++ b/packages/chirp/test/file_writer_test.dart @@ -317,6 +317,54 @@ void main() { expect(content, contains('WARNING - should appear')); expect(content, contains('ERROR - should appear')); }); + + test('minLevel constructor parameter filters messages', () async { + final tempDir = createTempDir(); + final logPath = '${tempDir.path}/app.log'; + final writer = RotatingFileWriter( + baseFilePath: logPath, + minLevel: ChirpLogLevel.warning, + ); + addTearDown(() => writer.close()); + + final logger = ChirpLogger(name: 'Test').addWriter(writer); + + logger.info('INFO - should be filtered'); + logger.debug('DEBUG - should be filtered'); + logger.warning('WARNING - should appear'); + logger.error('ERROR - should appear'); + + await writer.flush(); + + final content = File(logPath).readAsStringSync(); + expect(content, isNot(contains('should be filtered')), + reason: 'Messages below warning level should not be written'); + expect(content, contains('WARNING - should appear')); + expect(content, contains('ERROR - should appear')); + }); + + test('minLevel sets minLogLevel property', () { + final tempDir = createTempDir(); + final logPath = '${tempDir.path}/app.log'; + final writer = RotatingFileWriter( + baseFilePath: logPath, + minLevel: ChirpLogLevel.error, + ); + addTearDown(() => writer.close()); + + expect(writer.minLogLevel, ChirpLogLevel.error, + reason: 'minLevel should set the minLogLevel property'); + }); + + test('minLevel null does not set minLogLevel', () { + final tempDir = createTempDir(); + final logPath = '${tempDir.path}/app.log'; + final writer = RotatingFileWriter(baseFilePath: logPath); + addTearDown(() => writer.close()); + + expect(writer.minLogLevel, isNull, + reason: 'minLogLevel should be null by default'); + }); }); group('Size-based rotation', () {