mirror of
https://github.com/hanskokx/arcane_framework.git
synced 2026-08-12 06:10:55 +02:00
v2.0.2: Fix ArcaneLogger LoggerName mixin to be runtime safe (#9)
* Enhance reset method in ArcaneLogger to clear interceptors along with metadata and interfaces Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com> * Update Logging feature to replace @LoggingFeature annotation with LoggerName mixin for runtime accessibility Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com> * Bump version to 2.0.2 in pubspec.yaml and update CHANGELOG to reflect the new version Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com> * Add migration steps for replacing @LoggingFeature annotation with LoggerName mixin in CHANGELOG Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com> * Add TestLoggerWithLoggerName class to enhance logging functionality and verify LoggerName mixin behavior Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com> * Fix class declaration in migration example for LoggerName mixin Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com> --------- Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -1,3 +1,33 @@
|
|||||||
|
## 2.0.2
|
||||||
|
|
||||||
|
### Logging Service
|
||||||
|
|
||||||
|
- [BREAKING] Replaced the `@LoggingFeature(...)` annotation (compile-time only,
|
||||||
|
not readable at runtime in Flutter) with the `LoggerName` mixin.
|
||||||
|
Mix `LoggerName` into a `LoggingInterface` subclass and override
|
||||||
|
`name` to expose a runtime-accessible name inside `log()`.
|
||||||
|
|
||||||
|
#### Migration Steps (LoggingFeature)
|
||||||
|
|
||||||
|
1. Replace any `@LoggingFeature("...")` annotation with `with LoggerName` and
|
||||||
|
add an `@override String get name => '...';` getter to the class body.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
@LoggingFeature("my-feature")
|
||||||
|
class MyLogger extends LoggingInterface {...}
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
class MyLogger extends LoggingInterface with LoggerName {
|
||||||
|
@override
|
||||||
|
String get name => "my-feature";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 2.0.1
|
## 2.0.1
|
||||||
|
|
||||||
### Arcane Framework
|
### Arcane Framework
|
||||||
|
|||||||
@@ -514,12 +514,13 @@ class ExternalLogger extends LoggingInterface with LoggingInitialization {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to tag a destination, annotate the interface with
|
If you want to give a destination a name and access it at runtime,
|
||||||
`@LoggingFeature(...)`:
|
mix in `LoggerName` and override `name`:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@LoggingFeature("Analytics")
|
class AnalyticsLogger extends LoggingInterface with LoggerName {
|
||||||
class AnalyticsLogger extends LoggingInterface {
|
@override
|
||||||
|
String get name => 'Analytics';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void log(
|
void log(
|
||||||
@@ -529,6 +530,7 @@ class AnalyticsLogger extends LoggingInterface {
|
|||||||
StackTrace? stackTrace,
|
StackTrace? stackTrace,
|
||||||
Object? extra,
|
Object? extra,
|
||||||
}) {
|
}) {
|
||||||
|
// name is accessible here at runtime.
|
||||||
// Forward to analytics pipeline.
|
// Forward to analytics pipeline.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,12 +547,14 @@ Arcane.logger.interceptors.add(
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use this tag as source-level documentation and keep destination routing
|
You can use `name` inside `log()` and keep destination routing
|
||||||
explicit in interceptors.
|
explicit in interceptors.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@LoggingFeature("auth")
|
class AuthLogger extends LoggingInterface with LoggerName {
|
||||||
class AuthLogger extends LoggingInterface {
|
@override
|
||||||
|
String get name => 'auth';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void log(
|
void log(
|
||||||
String message, {
|
String message, {
|
||||||
|
|||||||
@@ -41,13 +41,24 @@ mixin LoggingInitialization implements LoggingInitializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Annotation used to tag a logging destination with a feature name.
|
/// Opt-in mixin that exposes a [name] string on a [LoggingInterface].
|
||||||
|
///
|
||||||
|
/// Mix this into a concrete logger to declare what [name] should be associated
|
||||||
|
/// with this logging interface.
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// `@LoggingFeature("analytics")`
|
/// ```dart
|
||||||
final class LoggingFeature {
|
/// class MyLogger extends LoggingInterface with LoggerName {
|
||||||
const LoggingFeature(this.value);
|
/// @override
|
||||||
|
/// String get name => 'my-feature';
|
||||||
/// The feature name associated with this logging destination.
|
///
|
||||||
final String value;
|
/// @override
|
||||||
|
/// void log(String message, {...}) {
|
||||||
|
/// print('[$name] $message');
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
mixin LoggerName on LoggingInterface {
|
||||||
|
/// The name associated with this logging interface.
|
||||||
|
String get name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -470,8 +470,8 @@ class ArcaneLogger {
|
|||||||
void clearPersistentMetadata() => _additionalMetadata.clear();
|
void clearPersistentMetadata() => _additionalMetadata.clear();
|
||||||
|
|
||||||
/// Resets the Arcane logging service by clearing all persistent metadata,
|
/// Resets the Arcane logging service by clearing all persistent metadata,
|
||||||
/// clearing all registered [LoggingInterface]s and marking the logging
|
/// clearing all registered [LoggingInterface]s, clearing all interceptors,
|
||||||
/// service as no longer being initialized.
|
/// and marking the logging service as no longer being initialized.
|
||||||
void reset() {
|
void reset() {
|
||||||
dispose();
|
dispose();
|
||||||
I._interfaceRegistrations.clear();
|
I._interfaceRegistrations.clear();
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
name: arcane_framework
|
name: arcane_framework
|
||||||
description: "Agnostic Reusable Component Architecture for New Ecosystems: a
|
description: "Agnostic Reusable Component Architecture for New Ecosystems: a
|
||||||
modern framework for bootstrapping new applications"
|
modern framework for bootstrapping new applications"
|
||||||
version: 2.0.1
|
version: 2.0.2
|
||||||
repository: https://github.com/hanskokx/arcane_framework
|
repository: https://github.com/hanskokx/arcane_framework
|
||||||
issue_tracker: https://github.com/hanskokx/arcane_framework/issues
|
issue_tracker: https://github.com/hanskokx/arcane_framework/issues
|
||||||
|
|
||||||
|
|||||||
@@ -110,9 +110,37 @@ class RedactingLogInterceptor implements LogInterceptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestLoggerWithLoggerName extends LoggingInterface with LoggerName {
|
||||||
|
@override
|
||||||
|
String get name => "test-logger";
|
||||||
|
|
||||||
|
final List<LogEvent> events = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void log(
|
||||||
|
String message, {
|
||||||
|
Map<String, Object?>? metadata,
|
||||||
|
Level? level,
|
||||||
|
StackTrace? stackTrace,
|
||||||
|
Object? extra,
|
||||||
|
}) {
|
||||||
|
events.add(
|
||||||
|
LogEvent(
|
||||||
|
message: message,
|
||||||
|
metadata: metadata == null ? null : Map<String, Object?>.from(metadata),
|
||||||
|
level: level,
|
||||||
|
stackTrace: stackTrace,
|
||||||
|
extra: extra,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
late TestLoggingInterface myInterface;
|
late TestLoggingInterface myInterface;
|
||||||
late LogInterceptor prefixInterceptor;
|
late LogInterceptor prefixInterceptor;
|
||||||
|
final TestLoggerWithLoggerName loggerWithLoggerName =
|
||||||
|
TestLoggerWithLoggerName();
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
Arcane.logger.reset();
|
Arcane.logger.reset();
|
||||||
@@ -677,4 +705,12 @@ void main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("LoggerName mixin exposes name at runtime", () {
|
||||||
|
expect(loggerWithLoggerName.name, "test-logger");
|
||||||
|
|
||||||
|
loggerWithLoggerName.log("Test message");
|
||||||
|
expect(loggerWithLoggerName.events.length, 1);
|
||||||
|
expect(loggerWithLoggerName.events.first.message, "Test message");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user