diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
index eabf7a8..1c6dd4c 100644
--- a/.github/workflows/dart.yml
+++ b/.github/workflows/dart.yml
@@ -1,26 +1,46 @@
-name: Dart CI
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# See documentation here:
+# https://github.com/dart-lang/setup-dart/blob/main/README.md
+
+name: Dart
on:
push:
- branches: [ master ]
+ branches: [ "master" ]
pull_request:
- branches: [ master ]
+ branches: [ "master" ]
jobs:
build:
-
runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [ stable, 2.17.0 ]
+ steps:
+ - uses: actions/checkout@v3
- container:
- image: google/dart:2.12
+ - uses: dart-lang/setup-dart@v1
+ with:
+ sdk: ${{ matrix.sdk }}
- steps:
- - uses: actions/checkout@v2
- - name: Install dependencies
- run: pub get
- - name: Format code
- run: dartfmt -n --set-exit-if-changed .
- - name: Static analyze project
- run: dartanalyzer --fatal-infos --fatal-warnings .
- - name: Run tests
- run: pub run test
+ - name: Install dependencies
+ run: dart pub get
+
+ # Uncomment this step to verify the use of 'dart format' on each commit.
+ - name: Verify formatting
+ run: dart format --output=none --set-exit-if-changed .
+
+ # Consider passing '--fatal-infos' for slightly stricter analysis.
+ - name: Analyze project source
+ run: dart analyze --fatal-infos
+
+ # Your project will need to have tests in test/ and a dependency on
+ # package:test for this step to succeed. Note that Flutter projects will
+ # want to change this to 'flutter test'.
+ - name: Run tests
+ run: dart test
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b2c590a..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: dart
-dart:
- - stable
-
-dart_task:
- - dartfmt
- - dartanalyzer: --fatal-warnings .
- - test
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1e6c33c..1e8deb5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,36 @@
+## 1.3.0
+
+- Fixed stackTrace count when using `stackTraceBeginIndex`.
+ Addresses [#114](https://github.com/simc/logger/issues/114).
+- Added proper FileOutput stub. Addresses [#94](https://github.com/simc/logger/issues/94).
+- Added `isClosed`. Addresses [#130](https://github.com/simc/logger/issues/130).
+- Added `time` to LogEvent.
+- Added `error` handling to LogfmtPrinter.
+
+## 1.2.2
+
+- Fixed conditional LogOutput export. Credits to
+ @ChristopheOosterlynck [#4](https://github.com/Bungeefan/logger/pull/4).
+
+## 1.2.1
+
+- Reverted `${this}` interpolation and added linter
+ ignore. [#1](https://github.com/Bungeefan/logger/issues/1)
+
+## 1.2.0
+
+- Added origin LogEvent to OutputEvent. Addresses [#133](https://github.com/simc/logger/pull/133).
+- Re-added LogListener and OutputListener (Should restore compatibility with logger_flutter).
+- Replaced pedantic with lints.
+
## 1.1.0
+
- Enhance boxing control with PrettyPrinter. Credits to @timmaffett
- Add trailing new line to FileOutput. Credits to @narumishi
- Add functions as a log message. Credits to @smotastic
## 1.0.0
+
- Stable nullsafety
## 1.0.0-nullsafety.0
@@ -22,7 +49,7 @@
## 0.9.2
- Add `PrefixPrinter`. Credits to @tkutcher.
- Add `HybridPrinter`. Credits to @tkutcher.
-
+
## 0.9.1
- Fix logging output for Flutter Web. Credits to @nateshmbhat and @Cocotus.
@@ -45,7 +72,7 @@
- Fix SimplePrinter showTime #12
- Remove buffer field
- Update library structure (thanks @marcgraub!)
-
+
## 0.7.0+1
- Added `ProductionFilter`, `FileOutput`, `MemoryOutput`, `SimplePrinter`
- Breaking: Changed `LogFilter`, `LogPrinter` and `LogOutput`
diff --git a/LICENSE b/LICENSE
index 4827a51..8b0e45c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,7 @@
MIT License
Copyright (c) 2019 Simon Leier
+Copyright (c) 2023 Severin Hamader
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index b4357ad..ba68428 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
# Logger
[![pub package](https://img.shields.io/pub/v/logger.svg?logo=dart&logoColor=00b9fc)](https://pub.dartlang.org/packages/logger)
-[![CI](https://img.shields.io/github/workflow/status/leisim/logger/Dart%20CI/master?logo=github-actions&logoColor=white)](https://github.com/leisim/logger/actions)
-[![Last Commits](https://img.shields.io/github/last-commit/leisim/logger?logo=git&logoColor=white)](https://github.com/leisim/logger/commits/master)
-[![Pull Requests](https://img.shields.io/github/issues-pr/leisim/logger?logo=github&logoColor=white)](https://github.com/leisim/logger/pulls)
-[![Code size](https://img.shields.io/github/languages/code-size/leisim/logger?logo=github&logoColor=white)](https://github.com/leisim/logger)
-[![License](https://img.shields.io/github/license/leisim/logger?logo=open-source-initiative&logoColor=green)](https://github.com/leisim/logger/blob/master/LICENSE)
+[![CI](https://img.shields.io/github/actions/workflow/status/Bungeefan/logger/dart.yml?branch=master&logo=github-actions&logoColor=white)](https://github.com/Bungeefan/logger/actions)
+[![Last Commits](https://img.shields.io/github/last-commit/Bungeefan/logger?logo=git&logoColor=white)](https://github.com/Bungeefan/logger/commits/master)
+[![Pull Requests](https://img.shields.io/github/issues-pr/Bungeefan/logger?logo=github&logoColor=white)](https://github.com/Bungeefan/logger/pulls)
+[![Code size](https://img.shields.io/github/languages/code-size/Bungeefan/logger?logo=github&logoColor=white)](https://github.com/Bungeefan/logger)
+[![License](https://img.shields.io/github/license/Bungeefan/logger?logo=open-source-initiative&logoColor=green)](https://github.com/Bungeefan/logger/blob/master/LICENSE)
NOTICE: This repo is NOT LONGER leading! The new repo is here: https://github.com/Bungeefan/logger
@@ -16,13 +16,15 @@ Inspired by [logger](https://github.com/orhanobut/logger) for Android.
**Show some ❤️ and star the repo to support the project**
### Resources:
+
- [Documentation](https://pub.dev/documentation/logger/latest/logger/logger-library.html)
- [Pub Package](https://pub.dev/packages/logger)
-- [GitHub Repository](https://github.com/leisim/logger)
+- [GitHub Repository](https://github.com/Bungeefan/logger)
## Getting Started
Just create an instance of `Logger` and start logging:
+
```dart
var logger = Logger();
@@ -33,7 +35,7 @@ Instead of a string message, you can also pass other objects like `List`, `Map`
## Output
-![](https://raw.githubusercontent.com/leisim/logger/master/art/screenshot.png)
+![](https://raw.githubusercontent.com/Bungeefan/logger/master/art/screenshot.png)
# Documentation
@@ -80,32 +82,35 @@ If you use the `PrettyPrinter`, there are more options:
```dart
var logger = Logger(
printer: PrettyPrinter(
- methodCount: 2, // number of method calls to be displayed
- errorMethodCount: 8, // number of method calls if stacktrace is provided
- lineLength: 120, // width of the output
- colors: true, // Colorful log messages
- printEmojis: true, // Print an emoji for each log message
- printTime: false // Should each log print contain a timestamp
+ methodCount: 2, // Number of method calls to be displayed
+ errorMethodCount: 8, // Number of method calls if stacktrace is provided
+ lineLength: 120, // Width of the output
+ colors: true, // Colorful log messages
+ printEmojis: true, // Print an emoji for each log message
+ printTime: false // Should each log print contain a timestamp
),
);
```
### Auto detecting
-With the `io` package you can auto detect the `lineLength` and `colors` arguments.
-Assuming you have imported the `io` package with `import 'dart:io' as io;` you
-can auto detect `colors` with `io.stdout.supportsAnsiEscapes` and `lineLength`
+With the `io` package you can auto detect the `lineLength` and `colors` arguments.
+Assuming you have imported the `io` package with `import 'dart:io' as io;` you
+can auto detect `colors` with `io.stdout.supportsAnsiEscapes` and `lineLength`
with `io.stdout.terminalColumns`.
-You should probably do this unless there's a good reason you don't want to
+You should probably do this unless there's a good reason you don't want to
import `io`, for example when using this library on the web.
## LogFilter
The `LogFilter` decides which log events should be shown and which don't.
-The default implementation (`DevelopmentFilter`) shows all logs with `level >= Logger.level` while in debug mode. In release mode all logs are omitted.
+The default implementation (`DevelopmentFilter`) shows all logs with `level >= Logger.level` while
+in debug mode.
+In release mode all logs are omitted.
You can create your own `LogFilter` like this:
+
```dart
class MyFilter extends LogFilter {
@override
@@ -114,8 +119,8 @@ class MyFilter extends LogFilter {
}
}
```
-This will show all logs even in release mode. (**NOT** a good idea)
+This will show all logs even in release mode. (**NOT** a good idea)
## LogPrinter
@@ -123,6 +128,7 @@ The `LogPrinter` creates and formats the output, which is then sent to the `LogO
You can implement your own `LogPrinter`. This gives you maximum flexibility.
A very basic printer could look like this:
+
```dart
class MyPrinter extends LogPrinter {
@override
@@ -132,22 +138,26 @@ class MyPrinter extends LogPrinter {
}
```
-If you created a cool `LogPrinter` which might be helpful to others, feel free to open a pull request. :)
+If you created a cool `LogPrinter` which might be helpful to others, feel free to open a pull
+request.
+:)
### Colors
-Please note that all IDEs (VSCode, XCode, Android Studio, IntelliJ) do not
-support ANSI escape sequences in their terminal outputs. These escape sequences
-are used to color output. If using such an IDE do not configure colored output.
+Please note that in some cases ANSI escape sequences do not work under macOS.
+These escape sequences are used to colorize the output.
+This seems to be related to a Flutter bug that affects iOS builds:
+https://github.com/flutter/flutter/issues/64491
-However, if you are using a JetBrains IDE (Android Studio, IntelliJ, etc.)
-you can make use of the [Grep Console Plugin](https://plugins.jetbrains.com/plugin/7125-grep-console)
-and the [`PrefixPrinter`](/lib/src/printers/prefix_printer.dart)
-decorator to achieved colored logs for any logger:
+However, if you are using a JetBrains IDE (Android Studio, IntelliJ, etc.)
+you can make use of
+the [Grep Console Plugin](https://plugins.jetbrains.com/plugin/7125-grep-console)
+and the [`PrefixPrinter`](/lib/src/printers/prefix_printer.dart)
+decorator to achieve colored logs for any logger:
```dart
var logger = Logger(
- printer: PrefixPrinter(PrettyPrinter(colors: false))
+ printer: PrefixPrinter(PrettyPrinter(colors: false))
);
```
@@ -167,33 +177,15 @@ class ConsoleOutput extends LogOutput {
}
```
-Possible future `LogOutput`s could send to a file, firebase or to Logcat. Feel free to open pull requests.
-
+Possible future `LogOutput`s could send to a file, firebase or to Logcat. Feel free to open pull
+requests.
## logger_flutter extension
-The [logger_flutter](https://pub.dev/packages/logger_flutter) package is an extension for logger. You can add it to any Flutter app. Just shake the phone to show the console.
+The [logger_flutter](https://pub.dev/packages/logger_flutter) package is an extension for logger.
+You can add it to any Flutter app.
+Just shake the phone to show the console.
+# Acknowledgments
-## MIT License
-```
-Copyright (c) 2019 Simon Leier
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-```
+This package was originally created by [Simon Choi](https://github.com/simc).
diff --git a/analysis_options.yaml b/analysis_options.yaml
index d4fcc1a..12e713a 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1 +1,4 @@
-include: package:pedantic/analysis_options.yaml
\ No newline at end of file
+include: package:lints/recommended.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/lib/logger.dart b/lib/logger.dart
index c5f3951..b3fba84 100644
--- a/lib/logger.dart
+++ b/lib/logger.dart
@@ -2,25 +2,20 @@
library logger;
export 'src/ansi_color.dart';
-
export 'src/filters/development_filter.dart';
export 'src/filters/production_filter.dart';
-
+export 'src/log_filter.dart';
+export 'src/log_output.dart';
+export 'src/log_printer.dart';
+export 'src/logger.dart';
export 'src/outputs/console_output.dart';
-export 'src/outputs/stream_output.dart';
+export 'src/outputs/file_output_stub.dart'
+ if (dart.library.io) 'src/outputs/file_output.dart';
export 'src/outputs/memory_output.dart';
export 'src/outputs/multi_output.dart';
-
-export 'src/printers/pretty_printer.dart';
-export 'src/printers/logfmt_printer.dart';
-export 'src/printers/simple_printer.dart';
+export 'src/outputs/stream_output.dart';
export 'src/printers/hybrid_printer.dart';
+export 'src/printers/logfmt_printer.dart';
export 'src/printers/prefix_printer.dart';
-
-export 'src/log_output.dart'
- if (dart.library.io) 'src/outputs/file_output.dart';
-
-export 'src/log_filter.dart';
-export 'src/log_output.dart';
-export 'src/log_printer.dart';
-export 'src/logger.dart';
+export 'src/printers/pretty_printer.dart';
+export 'src/printers/simple_printer.dart';
diff --git a/lib/src/ansi_color.dart b/lib/src/ansi_color.dart
index a6e0f06..22ea7f5 100644
--- a/lib/src/ansi_color.dart
+++ b/lib/src/ansi_color.dart
@@ -36,6 +36,7 @@ class AnsiColor {
String call(String msg) {
if (color) {
+ // ignore: unnecessary_brace_in_string_interps
return '${this}$msg$ansiDefault';
} else {
return msg;
diff --git a/lib/src/filters/development_filter.dart b/lib/src/filters/development_filter.dart
index a60f9b2..821c15f 100644
--- a/lib/src/filters/development_filter.dart
+++ b/lib/src/filters/development_filter.dart
@@ -1,5 +1,5 @@
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_filter.dart';
+import 'package:logger/src/logger.dart';
/// Prints all logs with `level >= Logger.level` while in development mode (eg
/// when `assert`s are evaluated, Flutter calls this debug mode).
diff --git a/lib/src/filters/production_filter.dart b/lib/src/filters/production_filter.dart
index 891ece1..d6ceac0 100644
--- a/lib/src/filters/production_filter.dart
+++ b/lib/src/filters/production_filter.dart
@@ -1,5 +1,5 @@
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_filter.dart';
+import 'package:logger/src/logger.dart';
/// Prints all logs with `level >= Logger.level` even in production.
class ProductionFilter extends LogFilter {
diff --git a/lib/src/log_filter.dart b/lib/src/log_filter.dart
index e512376..8fa2d03 100644
--- a/lib/src/log_filter.dart
+++ b/lib/src/log_filter.dart
@@ -6,6 +6,7 @@ import 'package:logger/src/logger.dart';
/// Every implementation should consider [Logger.level].
abstract class LogFilter {
Level? level;
+
void init() {}
/// Is called every time a new log message is sent and decides if
diff --git a/lib/src/log_printer.dart b/lib/src/log_printer.dart
index d0cb53a..a40125c 100644
--- a/lib/src/log_printer.dart
+++ b/lib/src/log_printer.dart
@@ -3,7 +3,7 @@ import 'package:logger/src/logger.dart';
/// An abstract handler of log events.
///
/// A log printer creates and formats the output, which is then sent to
-/// [LogOutput]. Every implementation has to use the [LogPrinter.println]
+/// [LogOutput]. Every implementation has to use the [LogPrinter.log]
/// method to send the output.
///
/// You can implement a `LogPrinter` from scratch or extend [PrettyPrinter].
diff --git a/lib/src/logger.dart b/lib/src/logger.dart
index 9378662..5fc69ca 100644
--- a/lib/src/logger.dart
+++ b/lib/src/logger.dart
@@ -1,9 +1,9 @@
import 'package:logger/src/filters/development_filter.dart';
-import 'package:logger/src/printers/pretty_printer.dart';
-import 'package:logger/src/outputs/console_output.dart';
import 'package:logger/src/log_filter.dart';
-import 'package:logger/src/log_printer.dart';
import 'package:logger/src/log_output.dart';
+import 'package:logger/src/log_printer.dart';
+import 'package:logger/src/outputs/console_output.dart';
+import 'package:logger/src/printers/pretty_printer.dart';
/// [Level]s to control logging output. Logging can be enabled to include all
/// levels above certain [Level].
@@ -23,20 +23,24 @@ class LogEvent {
final dynamic error;
final StackTrace? stackTrace;
- LogEvent(this.level, this.message, this.error, this.stackTrace);
+ /// Time when this log was created.
+ final DateTime time;
+
+ LogEvent(this.level, this.message, [this.error, this.stackTrace])
+ : time = DateTime.now();
}
class OutputEvent {
- final Level level;
final List lines;
+ final LogEvent origin;
+
+ Level get level => origin.level;
- OutputEvent(this.level, this.lines);
+ OutputEvent(this.origin, this.lines);
}
-@Deprecated('Use a custom LogFilter instead')
typedef LogCallback = void Function(LogEvent event);
-@Deprecated('Use a custom LogOutput instead')
typedef OutputCallback = void Function(OutputEvent event);
/// Use instances of logger to send log messages to the [LogPrinter].
@@ -46,6 +50,10 @@ class Logger {
/// All logs with levels below this level will be omitted.
static Level level = Level.verbose;
+ static final Set _logCallbacks = {};
+
+ static final Set _outputCallbacks = {};
+
final LogFilter _filter;
final LogPrinter _printer;
final LogOutput _output;
@@ -112,13 +120,19 @@ class Logger {
}
var logEvent = LogEvent(level, message, error, stackTrace);
if (_filter.shouldLog(logEvent)) {
+ for (var callback in _logCallbacks) {
+ callback(logEvent);
+ }
var output = _printer.log(logEvent);
if (output.isNotEmpty) {
- var outputEvent = OutputEvent(level, output);
+ var outputEvent = OutputEvent(logEvent, output);
// Issues with log output should NOT influence
// the main software behavior.
try {
+ for (var callback in _outputCallbacks) {
+ callback(outputEvent);
+ }
_output.output(outputEvent);
} catch (e, s) {
print(e);
@@ -128,6 +142,10 @@ class Logger {
}
}
+ bool isClosed() {
+ return !_active;
+ }
+
/// Closes the logger and releases all resources.
void close() {
_active = false;
@@ -135,4 +153,28 @@ class Logger {
_printer.destroy();
_output.destroy();
}
+
+ /// Register a [LogCallback] which is called for each new [LogEvent].
+ static void addLogListener(LogCallback callback) {
+ _logCallbacks.add(callback);
+ }
+
+ /// Removes a [LogCallback] which was previously registered.
+ ///
+ /// Returns whether the callback was successfully removed.
+ static bool removeLogListener(LogCallback callback) {
+ return _logCallbacks.remove(callback);
+ }
+
+ /// Register an [OutputCallback] which is called for each new [OutputEvent].
+ static void addOutputListener(OutputCallback callback) {
+ _outputCallbacks.add(callback);
+ }
+
+ /// Removes a [OutputCallback] which was previously registered.
+ ///
+ /// Returns whether the callback was successfully removed.
+ static void removeOutputListener(OutputCallback callback) {
+ _outputCallbacks.remove(callback);
+ }
}
diff --git a/lib/src/outputs/console_output.dart b/lib/src/outputs/console_output.dart
index 277b604..8670db1 100644
--- a/lib/src/outputs/console_output.dart
+++ b/lib/src/outputs/console_output.dart
@@ -1,5 +1,5 @@
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_output.dart';
+import 'package:logger/src/logger.dart';
/// Default implementation of [LogOutput].
///
diff --git a/lib/src/outputs/file_output.dart b/lib/src/outputs/file_output.dart
index c58c8e0..35b7b32 100644
--- a/lib/src/outputs/file_output.dart
+++ b/lib/src/outputs/file_output.dart
@@ -1,8 +1,8 @@
import 'dart:convert';
import 'dart:io';
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_output.dart';
+import 'package:logger/src/logger.dart';
/// Writes the log output to a file.
class FileOutput extends LogOutput {
diff --git a/lib/src/outputs/file_output_stub.dart b/lib/src/outputs/file_output_stub.dart
new file mode 100644
index 0000000..b4eb4db
--- /dev/null
+++ b/lib/src/outputs/file_output_stub.dart
@@ -0,0 +1,20 @@
+import 'dart:convert';
+import 'dart:io';
+
+import '../log_output.dart';
+import '../logger.dart';
+
+class FileOutput extends LogOutput {
+ FileOutput({
+ required File file,
+ bool overrideExisting = false,
+ Encoding encoding = utf8,
+ }) {
+ throw UnsupportedError("Not supported on this platform.");
+ }
+
+ @override
+ void output(OutputEvent event) {
+ throw UnsupportedError("Not supported on this platform.");
+ }
+}
diff --git a/lib/src/outputs/memory_output.dart b/lib/src/outputs/memory_output.dart
index f0f4100..0a46f23 100644
--- a/lib/src/outputs/memory_output.dart
+++ b/lib/src/outputs/memory_output.dart
@@ -1,7 +1,7 @@
import 'dart:collection';
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_output.dart';
+import 'package:logger/src/logger.dart';
/// Buffers [OutputEvent]s.
class MemoryOutput extends LogOutput {
diff --git a/lib/src/outputs/multi_output.dart b/lib/src/outputs/multi_output.dart
index bfa50d7..2e40ea2 100644
--- a/lib/src/outputs/multi_output.dart
+++ b/lib/src/outputs/multi_output.dart
@@ -8,6 +8,7 @@ class MultiOutput extends LogOutput {
MultiOutput(List? outputs) {
_outputs = _normalizeOutputs(outputs);
}
+
List _normalizeOutputs(List? outputs) {
final normalizedOutputs = [];
@@ -24,16 +25,22 @@ class MultiOutput extends LogOutput {
@override
void init() {
- _outputs.forEach((o) => o.init());
+ for (var o in _outputs) {
+ o.init();
+ }
}
@override
void output(OutputEvent event) {
- _outputs.forEach((o) => o.output(event));
+ for (var o in _outputs) {
+ o.output(event);
+ }
}
@override
void destroy() {
- _outputs.forEach((o) => o.destroy());
+ for (var o in _outputs) {
+ o.destroy();
+ }
}
}
diff --git a/lib/src/outputs/stream_output.dart b/lib/src/outputs/stream_output.dart
index 8523b76..1a34329 100644
--- a/lib/src/outputs/stream_output.dart
+++ b/lib/src/outputs/stream_output.dart
@@ -1,7 +1,7 @@
import 'dart:async';
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_output.dart';
+import 'package:logger/src/logger.dart';
class StreamOutput extends LogOutput {
late StreamController> _controller;
diff --git a/lib/src/printers/hybrid_printer.dart b/lib/src/printers/hybrid_printer.dart
index 83d4d64..9b3e655 100644
--- a/lib/src/printers/hybrid_printer.dart
+++ b/lib/src/printers/hybrid_printer.dart
@@ -1,5 +1,5 @@
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_printer.dart';
+import 'package:logger/src/logger.dart';
/// A decorator for a [LogPrinter] that allows for the composition of
/// different printers to handle different log messages. Provide it's
@@ -13,21 +13,26 @@ import 'package:logger/src/log_printer.dart';
/// Will use the pretty printer for all logs except Level.debug
/// logs, which will use SimplePrinter().
class HybridPrinter extends LogPrinter {
- final LogPrinter _realPrinter;
- var _printerMap;
+ final Map _printerMap;
- HybridPrinter(this._realPrinter,
- {debug, verbose, wtf, info, warning, error}) {
- _printerMap = {
- Level.debug: debug ?? _realPrinter,
- Level.verbose: verbose ?? _realPrinter,
- Level.wtf: wtf ?? _realPrinter,
- Level.info: info ?? _realPrinter,
- Level.warning: warning ?? _realPrinter,
- Level.error: error ?? _realPrinter,
- };
- }
+ HybridPrinter(
+ LogPrinter realPrinter, {
+ LogPrinter? debug,
+ LogPrinter? verbose,
+ LogPrinter? wtf,
+ LogPrinter? info,
+ LogPrinter? warning,
+ LogPrinter? error,
+ }) : _printerMap = {
+ Level.debug: debug ?? realPrinter,
+ Level.verbose: verbose ?? realPrinter,
+ Level.wtf: wtf ?? realPrinter,
+ Level.info: info ?? realPrinter,
+ Level.warning: warning ?? realPrinter,
+ Level.error: error ?? realPrinter,
+ };
@override
- List log(LogEvent event) => _printerMap[event.level].log(event);
+ List log(LogEvent event) =>
+ _printerMap[event.level]?.log(event) ?? [];
}
diff --git a/lib/src/printers/logfmt_printer.dart b/lib/src/printers/logfmt_printer.dart
index 63083e5..85c5024 100644
--- a/lib/src/printers/logfmt_printer.dart
+++ b/lib/src/printers/logfmt_printer.dart
@@ -29,6 +29,9 @@ class LogfmtPrinter extends LogPrinter {
}
});
}
+ if (event.error != null) {
+ output.write(' error="${event.error}"');
+ }
return [output.toString()];
}
diff --git a/lib/src/printers/prefix_printer.dart b/lib/src/printers/prefix_printer.dart
index 256012e..6b89d92 100644
--- a/lib/src/printers/prefix_printer.dart
+++ b/lib/src/printers/prefix_printer.dart
@@ -1,5 +1,5 @@
-import 'package:logger/src/logger.dart';
import 'package:logger/src/log_printer.dart';
+import 'package:logger/src/logger.dart';
/// A decorator for a [LogPrinter] that allows for the prepending of every
/// line in the log output with a string for the level of that log. For
@@ -37,7 +37,7 @@ class PrefixPrinter extends LogPrinter {
}
int _longestPrefixLength() {
- var compFunc = (String a, String b) => a.length > b.length ? a : b;
+ compFunc(String a, String b) => a.length > b.length ? a : b;
return _prefixMap.values.reduce(compFunc).length;
}
}
diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart
index f58f599..bf2cc74 100644
--- a/lib/src/printers/pretty_printer.dart
+++ b/lib/src/printers/pretty_printer.dart
@@ -1,8 +1,9 @@
import 'dart:convert';
+import 'dart:math';
-import 'package:logger/src/logger.dart';
-import 'package:logger/src/log_printer.dart';
import 'package:logger/src/ansi_color.dart';
+import 'package:logger/src/log_printer.dart';
+import 'package:logger/src/logger.dart';
/// Default implementation of [LogPrinter].
///
@@ -24,6 +25,7 @@ class PrettyPrinter extends LogPrinter {
static const doubleDivider = '─';
static const singleDivider = '┄';
+ static final whiteColor = AnsiColor.fg(255);
static final levelColors = {
Level.verbose: AnsiColor.fg(AnsiColor.grey(0.5)),
Level.debug: AnsiColor.none(),
@@ -83,6 +85,10 @@ class PrettyPrinter extends LogPrinter {
/// (boxing can still be turned on for some levels by using something like excludeBox:{Level.error:false} )
final bool noBoxingByDefault;
+ /// To exclude user's custom path
+ /// for example if you made a Mylog util redirect to logger.log,
+ /// you can add your Mylog path in [excludePaths].
+ final List excludePaths;
late final Map includeBox;
String _topBorder = '';
@@ -99,6 +105,7 @@ class PrettyPrinter extends LogPrinter {
this.printTime = false,
this.excludeBox = const {},
this.noBoxingByDefault = false,
+ this.excludePaths = const [],
}) {
_startTime ??= DateTime.now();
@@ -115,7 +122,9 @@ class PrettyPrinter extends LogPrinter {
// Translate excludeBox map (constant if default) to includeBox map with all Level enum possibilities
includeBox = {};
- Level.values.forEach((l) => includeBox[l] = !noBoxingByDefault);
+ for (var l in Level.values) {
+ includeBox[l] = !noBoxingByDefault;
+ }
excludeBox.forEach((k, v) => includeBox[k] = !v);
}
@@ -136,7 +145,7 @@ class PrettyPrinter extends LogPrinter {
String? timeStr;
if (printTime) {
- timeStr = getTime();
+ timeStr = getTime(event.time);
}
return _formatAndPrint(
@@ -149,23 +158,25 @@ class PrettyPrinter extends LogPrinter {
}
String? formatStackTrace(StackTrace? stackTrace, int methodCount) {
- var lines = stackTrace.toString().split('\n');
- if (stackTraceBeginIndex > 0 && stackTraceBeginIndex < lines.length - 1) {
- lines = lines.sublist(stackTraceBeginIndex);
- }
- var formatted = [];
- var count = 0;
- for (var line in lines) {
- if (_discardDeviceStacktraceLine(line) ||
- _discardWebStacktraceLine(line) ||
- _discardBrowserStacktraceLine(line) ||
- line.isEmpty) {
+ List lines = stackTrace
+ .toString()
+ .split('\n')
+ .where(
+ (line) =>
+ !_discardDeviceStacktraceLine(line) &&
+ !_discardWebStacktraceLine(line) &&
+ !_discardBrowserStacktraceLine(line) &&
+ line.isNotEmpty,
+ )
+ .toList();
+ List formatted = [];
+
+ for (int count = 0; count < min(lines.length, methodCount); count++) {
+ var line = lines[count];
+ if (count < stackTraceBeginIndex) {
continue;
}
formatted.add('#$count ${line.replaceFirst(RegExp(r'#\d+\s+'), '')}');
- if (++count == methodCount) {
- break;
- }
}
if (formatted.isEmpty) {
@@ -175,12 +186,25 @@ class PrettyPrinter extends LogPrinter {
}
}
+ bool _isInExcludePaths(String segment) {
+ for (var element in excludePaths) {
+ if (segment.startsWith(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
bool _discardDeviceStacktraceLine(String line) {
var match = _deviceStackTraceRegex.matchAsPrefix(line);
if (match == null) {
return false;
}
- return match.group(2)!.startsWith('package:logger');
+ final segment = match.group(2)!;
+ if (segment.startsWith('package:logger')) {
+ return true;
+ }
+ return _isInExcludePaths(segment);
}
bool _discardWebStacktraceLine(String line) {
@@ -188,8 +212,12 @@ class PrettyPrinter extends LogPrinter {
if (match == null) {
return false;
}
- return match.group(1)!.startsWith('packages/logger') ||
- match.group(1)!.startsWith('dart-sdk/lib');
+ final segment = match.group(1)!;
+ if (segment.startsWith('packages/logger') ||
+ segment.startsWith('dart-sdk/lib')) {
+ return true;
+ }
+ return _isInExcludePaths(segment);
}
bool _discardBrowserStacktraceLine(String line) {
@@ -197,27 +225,30 @@ class PrettyPrinter extends LogPrinter {
if (match == null) {
return false;
}
- return match.group(1)!.startsWith('package:logger') ||
- match.group(1)!.startsWith('dart:');
+ final segment = match.group(1)!;
+ if (segment.startsWith('package:logger') || segment.startsWith('dart:')) {
+ return true;
+ }
+ return _isInExcludePaths(segment);
}
- String getTime() {
- String _threeDigits(int n) {
+ String getTime(DateTime time) {
+ String threeDigits(int n) {
if (n >= 100) return '$n';
if (n >= 10) return '0$n';
return '00$n';
}
- String _twoDigits(int n) {
+ String twoDigits(int n) {
if (n >= 10) return '$n';
return '0$n';
}
- var now = DateTime.now();
- var h = _twoDigits(now.hour);
- var min = _twoDigits(now.minute);
- var sec = _twoDigits(now.second);
- var ms = _threeDigits(now.millisecond);
+ var now = time;
+ var h = twoDigits(now.hour);
+ var min = twoDigits(now.minute);
+ var sec = twoDigits(now.second);
+ var ms = threeDigits(now.millisecond);
var timeSinceStart = now.difference(_startTime!).toString();
return '$h:$min:$sec.$ms (+$timeSinceStart)';
}
@@ -272,10 +303,8 @@ class PrettyPrinter extends LogPrinter {
String? error,
String? stacktrace,
) {
- // This code is non trivial and a type annotation here helps understanding.
- // ignore: omit_local_variable_types
List buffer = [];
- var verticalLineAtLevel = (includeBox[level]!) ? (verticalLine + ' ') : '';
+ var verticalLineAtLevel = (includeBox[level]!) ? ('$verticalLine ') : '';
var color = _getLevelColor(level);
if (includeBox[level]!) buffer.add(color(_topBorder));
@@ -284,8 +313,7 @@ class PrettyPrinter extends LogPrinter {
for (var line in error.split('\n')) {
buffer.add(
color(verticalLineAtLevel) +
- errorColor.resetForeground +
- errorColor(line) +
+ errorColor(whiteColor(line)) +
errorColor.resetBackground,
);
}
diff --git a/lib/src/printers/simple_printer.dart b/lib/src/printers/simple_printer.dart
index d7a4adf..7041036 100644
--- a/lib/src/printers/simple_printer.dart
+++ b/lib/src/printers/simple_printer.dart
@@ -1,8 +1,8 @@
import 'dart:convert';
-import 'package:logger/src/logger.dart';
-import 'package:logger/src/log_printer.dart';
import 'package:logger/src/ansi_color.dart';
+import 'package:logger/src/log_printer.dart';
+import 'package:logger/src/logger.dart';
/// Outputs simple log messages:
/// ```
@@ -36,7 +36,7 @@ class SimplePrinter extends LogPrinter {
List log(LogEvent event) {
var messageStr = _stringifyMessage(event.message);
var errorStr = event.error != null ? ' ERROR: ${event.error}' : '';
- var timeStr = printTime ? 'TIME: ${DateTime.now().toIso8601String()}' : '';
+ var timeStr = printTime ? 'TIME: ${event.time.toIso8601String()}' : '';
return ['${_labelFor(event.level)} $timeStr $messageStr$errorStr'];
}
diff --git a/pubspec.yaml b/pubspec.yaml
index f0a021e..a441cbb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,11 @@
name: logger
description: Small, easy to use and extensible logger which prints beautiful logs.
-version: 1.1.0
-homepage: https://github.com/leisim/logger
+version: 1.3.0
+repository: https://github.com/Bungeefan/logger
environment:
- sdk: ">=2.12.0 <3.0.0"
+ sdk: "^2.12.0"
dev_dependencies:
test: ^1.16.8
- pedantic: ^1.11.0
+ lints: ^2.0.1
diff --git a/test/logger_test.dart b/test/logger_test.dart
index 1025c25..40db942 100644
--- a/test/logger_test.dart
+++ b/test/logger_test.dart
@@ -1,7 +1,7 @@
import 'dart:math';
-import 'package:test/test.dart';
import 'package:logger/logger.dart';
+import 'package:test/test.dart';
typedef PrinterCallback = List Function(
Level level,
@@ -168,4 +168,11 @@ void main() {
logger.w('This is');
expect(printedMessage, 'This is');
});
+
+ test('Logger.close', () {
+ var logger = Logger();
+ expect(logger.isClosed(), false);
+ logger.close();
+ expect(logger.isClosed(), true);
+ });
}
diff --git a/test/outputs/memory_output_test.dart b/test/outputs/memory_output_test.dart
index 4d92b2a..10874f4 100644
--- a/test/outputs/memory_output_test.dart
+++ b/test/outputs/memory_output_test.dart
@@ -5,9 +5,9 @@ void main() {
test('Memory output buffer size is limited', () {
var output = MemoryOutput(bufferSize: 2);
- final event0 = OutputEvent(Level.info, []);
- final event1 = OutputEvent(Level.info, []);
- final event2 = OutputEvent(Level.info, []);
+ final event0 = OutputEvent(LogEvent(Level.info, null), []);
+ final event1 = OutputEvent(LogEvent(Level.info, null), []);
+ final event2 = OutputEvent(LogEvent(Level.info, null), []);
output.output(event0);
output.output(event1);
diff --git a/test/outputs/multi_output_test.dart b/test/outputs/multi_output_test.dart
index ab7be20..0d83f56 100644
--- a/test/outputs/multi_output_test.dart
+++ b/test/outputs/multi_output_test.dart
@@ -8,7 +8,7 @@ void main() {
final multiOutput = MultiOutput([output1, output2]);
- final event0 = OutputEvent(Level.info, []);
+ final event0 = OutputEvent(LogEvent(Level.info, null), []);
multiOutput.output(event0);
expect(output1.buffer.length, 1);
@@ -16,7 +16,7 @@ void main() {
expect(output1.buffer.elementAt(0), equals(output2.buffer.elementAt(0)));
expect(output1.buffer.elementAt(0), equals(event0));
- final event1 = OutputEvent(Level.info, []);
+ final event1 = OutputEvent(LogEvent(Level.info, null), []);
multiOutput.output(event1);
expect(output1.buffer.length, 2);
@@ -29,11 +29,11 @@ void main() {
test('passing null does not throw an exception', () {
final output = MultiOutput(null);
- output.output(OutputEvent(Level.info, []));
+ output.output(OutputEvent(LogEvent(Level.info, null), []));
});
test('passing null in the list does not throw an exception', () {
final output = MultiOutput([null]);
- output.output(OutputEvent(Level.info, []));
+ output.output(OutputEvent(LogEvent(Level.info, null), []));
});
}
diff --git a/test/outputs/stream_output_test.dart b/test/outputs/stream_output_test.dart
index 506abad..7a9ba49 100644
--- a/test/outputs/stream_output_test.dart
+++ b/test/outputs/stream_output_test.dart
@@ -1,5 +1,5 @@
-import 'package:test/test.dart';
import 'package:logger/logger.dart';
+import 'package:test/test.dart';
void main() {
test('writes to a Stream', () {
@@ -9,19 +9,19 @@ void main() {
expect(e, ['hi there']);
});
- out.output(OutputEvent(Level.debug, ['hi there']));
+ out.output(OutputEvent(LogEvent(Level.debug, null), ['hi there']));
});
test('respects listen', () {
var out = StreamOutput();
- out.output(OutputEvent(Level.debug, ['dropped']));
+ out.output(OutputEvent(LogEvent(Level.debug, null), ['dropped']));
out.stream.listen((var e) {
expect(e, ['hi there']);
});
- out.output(OutputEvent(Level.debug, ['hi there']));
+ out.output(OutputEvent(LogEvent(Level.debug, null), ['hi there']));
});
test('respects pause', () {
@@ -32,8 +32,8 @@ void main() {
});
sub.pause();
- out.output(OutputEvent(Level.debug, ['dropped']));
+ out.output(OutputEvent(LogEvent(Level.debug, null), ['dropped']));
sub.resume();
- out.output(OutputEvent(Level.debug, ['hi there']));
+ out.output(OutputEvent(LogEvent(Level.debug, null), ['hi there']));
});
}
diff --git a/test/printers/hybrid_printer_test.dart b/test/printers/hybrid_printer_test.dart
index ce6e880..53ef327 100644
--- a/test/printers/hybrid_printer_test.dart
+++ b/test/printers/hybrid_printer_test.dart
@@ -1,14 +1,11 @@
-import 'package:logger/src/log_printer.dart';
-import 'package:logger/src/logger.dart';
-import 'package:logger/src/printers/simple_printer.dart';
+import 'package:logger/logger.dart';
import 'package:test/test.dart';
-import 'package:logger/src/printers/hybrid_printer.dart';
-
final realPrinter = SimplePrinter();
class TestLogPrinter extends LogPrinter {
LogEvent? latestEvent;
+
@override
List log(LogEvent event) {
latestEvent = event;
diff --git a/test/printers/logfmt_printer_test.dart b/test/printers/logfmt_printer_test.dart
index 4a98cec..ad3d4b9 100644
--- a/test/printers/logfmt_printer_test.dart
+++ b/test/printers/logfmt_printer_test.dart
@@ -1,5 +1,5 @@
-import 'package:test/test.dart';
import 'package:logger/logger.dart';
+import 'package:test/test.dart';
void main() {
var printer = LogfmtPrinter();
@@ -18,13 +18,14 @@ void main() {
test('with a string message includes a msg key', () {
expect(
- printer.log(LogEvent(
- Level.debug,
- 'some message',
- Exception('boom'),
- StackTrace.current,
- ))[0],
- contains('msg="some message"'));
+ printer.log(LogEvent(
+ Level.debug,
+ 'some message',
+ Exception('boom'),
+ StackTrace.current,
+ ))[0],
+ contains('msg="some message"'),
+ );
});
test('includes random key=value pairs', () {
@@ -39,6 +40,21 @@ void main() {
expect(output, contains('foo="bar baz"'));
});
+ test('handles an error/exception', () {
+ var output = printer.log(LogEvent(
+ Level.debug,
+ 'some message',
+ Exception('boom'),
+ StackTrace.current,
+ ))[0];
+ expect(output, contains('error="Exception: boom"'));
+
+ output = printer.log(LogEvent(
+ Level.debug,
+ 'some message',
+ ))[0];
+ expect(output, isNot(contains('error=')));
+ });
+
test('handles a stacktrace', () {}, skip: 'TODO');
- test('handles an error/exception', () {}, skip: 'TODO');
}
diff --git a/test/printers/prefix_printer_test.dart b/test/printers/prefix_printer_test.dart
index 7ca0a43..a3011e4 100644
--- a/test/printers/prefix_printer_test.dart
+++ b/test/printers/prefix_printer_test.dart
@@ -1,7 +1,4 @@
-import 'package:logger/src/logger.dart';
-import 'package:logger/src/printers/prefix_printer.dart';
-import 'package:logger/src/printers/pretty_printer.dart';
-import 'package:logger/src/printers/simple_printer.dart';
+import 'package:logger/logger.dart';
import 'package:test/test.dart';
void main() {
@@ -25,22 +22,22 @@ void main() {
test('prefixes logs', () {
var printer = PrefixPrinter(PrettyPrinter());
var actualLog = printer.log(infoEvent);
- actualLog.forEach((logString) {
+ for (var logString in actualLog) {
expect(logString, contains('INFO'));
- });
+ }
var debugLog = printer.log(debugEvent);
- debugLog.forEach((logString) {
+ for (var logString in debugLog) {
expect(logString, contains('DEBUG'));
- });
+ }
});
test('can supply own prefixes', () {
var printer = PrefixPrinter(PrettyPrinter(), debug: 'BLAH');
var actualLog = printer.log(debugEvent);
- actualLog.forEach((logString) {
+ for (var logString in actualLog) {
expect(logString, contains('BLAH'));
- });
+ }
});
test('pads to same length', () {
@@ -49,9 +46,9 @@ void main() {
var printer = PrefixPrinter(SimplePrinter(), debug: longPrefix);
for (var event in allEvents) {
var l1 = printer.log(event);
- l1.forEach((logString) {
+ for (var logString in l1) {
expect(logString.substring(0, len), isNot(contains('[')));
- });
+ }
}
});
}
diff --git a/test/printers/pretty_printer_test.dart b/test/printers/pretty_printer_test.dart
index 52727a2..0f852c8 100644
--- a/test/printers/pretty_printer_test.dart
+++ b/test/printers/pretty_printer_test.dart
@@ -2,8 +2,8 @@ import 'package:logger/logger.dart';
import 'package:test/test.dart';
void main() {
- String _readMessage(List log) {
- return log.reduce((acc, val) => acc + val);
+ String readMessage(List log) {
+ return log.reduce((acc, val) => "$acc\n$val");
}
final prettyPrinter = PrettyPrinter(printEmojis: false);
@@ -19,7 +19,7 @@ void main() {
);
final actualLog = emojiPrettyPrinter.log(event);
- final actualLogString = _readMessage(actualLog);
+ final actualLogString = readMessage(actualLog);
expect(actualLogString, contains(PrettyPrinter.levelEmojis[Level.debug]));
expect(actualLogString, contains(expectedMessage));
});
@@ -34,7 +34,7 @@ void main() {
);
final actualLog = prettyPrinter.log(withFunction);
- final actualLogString = _readMessage(actualLog);
+ final actualLogString = readMessage(actualLog);
expect(
actualLogString,
@@ -51,7 +51,7 @@ void main() {
);
final actualLog = prettyPrinter.log(withMap);
- final actualLogString = _readMessage(actualLog);
+ final actualLogString = readMessage(actualLog);
for (var expectedMsg in expectedMsgMap.entries) {
expect(
actualLogString,
@@ -69,7 +69,7 @@ void main() {
StackTrace.current,
);
final actualLog = prettyPrinter.log(withIterable);
- final actualLogString = _readMessage(actualLog);
+ final actualLogString = readMessage(actualLog);
for (var expectedMsg in expectedMsgItems) {
expect(
actualLogString,
@@ -88,11 +88,35 @@ void main() {
);
final actualLog = prettyPrinter.log(withFunction);
- final actualLogString = _readMessage(actualLog);
+ final actualLogString = readMessage(actualLog);
expect(
actualLogString,
contains(expectedMessage),
);
});
+
+ test('stackTraceBeginIndex', () {
+ final prettyPrinter = PrettyPrinter(
+ stackTraceBeginIndex: 2,
+ );
+ final withFunction = LogEvent(
+ Level.debug,
+ "some message",
+ 'some error',
+ StackTrace.current,
+ );
+
+ final actualLog = prettyPrinter.log(withFunction);
+ final actualLogString = readMessage(actualLog);
+
+ expect(
+ actualLogString,
+ allOf([
+ isNot(contains("#0 ")),
+ isNot(contains("#1 ")),
+ contains("#2 "),
+ ]),
+ );
+ });
}
diff --git a/test/printers/simple_printer_test.dart b/test/printers/simple_printer_test.dart
index ad3f904..c185d50 100644
--- a/test/printers/simple_printer_test.dart
+++ b/test/printers/simple_printer_test.dart
@@ -1,5 +1,4 @@
-import 'package:logger/src/logger.dart';
-import 'package:logger/src/printers/simple_printer.dart';
+import 'package:logger/logger.dart';
import 'package:test/test.dart';
const ansiEscapeLiteral = '\x1B';