Skip to content

Commit f35eaa6

Browse files
feat: basic shape of file handler; noop logger always returns the same instance
1 parent c3bb6d1 commit f35eaa6

File tree

11 files changed

+136
-36
lines changed

11 files changed

+136
-36
lines changed

lib/handlers.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
library strlog.handlers;
1010

1111
export 'src/handlers/console_handler.dart';
12+
export 'src/handlers/file_handler/noop.dart'
13+
if (dart.libary.io) 'src/handlers/file_handler/io.dart';
14+
export 'src/handlers/file_handler/policy.dart';
1215
export 'src/handlers/memory_handler.dart';
1316
export 'src/handlers/multi_handler.dart';
1417
export 'src/handlers/stream_handler.dart';

lib/src/handlers/console_handler.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ class ConsoleHandler extends Handler {
1212
final Formatter _formatter;
1313
Filter? _filter;
1414

15-
/// Sets records filterer.
15+
/// Sets records filter.
1616
///
17-
/// Set filterer behaves the same way as a [Logger] filter.
17+
/// Set filter behaves the same way as a [Logger] filter.
1818
set filter(Filter filter) => _filter = filter;
1919

2020
@override
2121
void handle(Record record) {
22-
if (_filter != null && !_filter!(record)) {
22+
final filter = _filter;
23+
final shouldFilter = filter != null && !filter(record);
24+
if (shouldFilter) {
2325
return;
2426
}
2527

lib/src/handlers/file_handler/io.dart

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'dart:io' show BytesBuilder;
2+
import 'dart:typed_data' show Uint8List;
3+
4+
import 'package:file/file.dart' show File, FileSystem, IOSink;
5+
import 'package:file/local.dart' show LocalFileSystem;
6+
import 'package:strlog/formatters.dart' show Formatter;
7+
import 'package:strlog/strlog.dart' show Handler, Record, Filter;
8+
9+
import './policy.dart';
10+
11+
const _localFs = LocalFileSystem();
12+
13+
// [FileHandler] writes log records to the file via [fs].
14+
class FileHandler extends Handler {
15+
FileHandler(this._policy, {required Formatter formatter, FileSystem? fs})
16+
: _formatter = formatter,
17+
_fs = fs ?? _localFs,
18+
_buffer = BytesBuilder(copy: false),
19+
_stateMask = 0;
20+
21+
final FileRotationPolicy _policy;
22+
final Formatter _formatter;
23+
Filter? _filter;
24+
25+
final FileSystem _fs;
26+
final BytesBuilder _buffer;
27+
IOSink? _sink;
28+
int _stateMask; // controls lifecyrcle of the file
29+
30+
/// Sets records filter.
31+
///
32+
/// Set filter behaves the same way as a [Logger] filter.
33+
set filter(Filter? filter) => _filter = filter;
34+
35+
void _rotate() {}
36+
37+
void _tick() {
38+
if (_policy.shouldRotate()) {
39+
return _rotate();
40+
}
41+
42+
while (_buffer.isNotEmpty) {
43+
final bytes = _buffer.takeBytes();
44+
45+
_sink?.write(bytes);
46+
}
47+
}
48+
49+
@override
50+
void handle(Record record) {
51+
final filter = _filter;
52+
final shouldFilter = filter != null && !filter(record);
53+
if (shouldFilter) {
54+
return;
55+
}
56+
57+
_buffer.add(Uint8List.fromList(_formatter(record)));
58+
_tick();
59+
}
60+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'package:strlog/strlog.dart' show Handler, Record;
2+
3+
class FileHandler extends Handler {
4+
FileHandler();
5+
6+
@override
7+
void handle(Record record) {/* noop */}
8+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
abstract class FileRotationPolicy {
2+
// [FileRotationPolicy.never] creates a never rotating policy.
3+
//
4+
// [FileHandler] with the policy will never rotate a file, effectively
5+
// writting the data to the same file until the end of the application
6+
// lifetime.
7+
const factory FileRotationPolicy.never() = _NeverFileRotationPolicy;
8+
9+
// [FileRotationPolicy.interval] creates a interval based rotation policy.
10+
//
11+
// [FileHandler] with the policy will rotate a logging file each [duration].
12+
const factory FileRotationPolicy.interval(Duration duration) =
13+
_IntervalFileRotationPolicy;
14+
15+
bool shouldRotate();
16+
}
17+
18+
// [_NeverFileRotationPolicy] never rotates file.
19+
class _NeverFileRotationPolicy implements FileRotationPolicy {
20+
const _NeverFileRotationPolicy();
21+
22+
@override
23+
bool shouldRotate() => false;
24+
}
25+
26+
// [_intervalFileRotationPolicy] rotates a file each [duration].
27+
class _IntervalFileRotationPolicy implements FileRotationPolicy {
28+
const _IntervalFileRotationPolicy(this.duration);
29+
30+
final Duration duration;
31+
32+
@override
33+
bool shouldRotate() {
34+
final now = DateTime.now();
35+
final diff = now.difference(DateTime.now());
36+
37+
return diff.inMilliseconds < duration.inMilliseconds;
38+
}
39+
}

lib/src/handlers/multi_handler.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ class MultiHandler extends Handler {
2323

2424
final StreamController<Record> _controller;
2525

26-
/// Sets records filterer.
26+
/// Sets records filter.
2727
///
28-
/// Set filterer behaves the same way as a [Logger] filter.
28+
/// Set filter behaves the same way as a [Logger] filter.
2929
set filter(Filter filter) => _filter = filter;
3030

3131
@override

lib/src/handlers/stream_handler.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,26 @@ import 'package:strlog/strlog.dart' show Handler, Record, Filter;
88
/// Each log record is formatted using the `formatter` before
99
/// submitting it to the downstream.
1010
class StreamHandler extends Handler {
11-
StreamHandler(this._stream, {required Formatter formatter})
11+
StreamHandler(this._sink, {required Formatter formatter})
1212
: _formatter = formatter;
1313

14+
final StreamSink<List<int>> _sink;
1415
final Formatter _formatter;
15-
final StreamSink<List<int>> _stream;
1616
Filter? _filter;
1717

18-
/// Sets records filterer.
18+
/// Sets records filter.
1919
///
20-
/// Set filterer behaves the same way as a [Logger] filter.
20+
/// Set filter behaves the same way as a [Logger] filter.
2121
set filter(Filter? filter) => _filter = filter;
2222

2323
@override
2424
void handle(Record record) {
25-
if (_filter != null && !_filter!(record)) {
25+
final filter = _filter;
26+
final shouldFilter = filter != null && !filter(record);
27+
if (shouldFilter) {
2628
return;
2729
}
2830

29-
_stream.add(_formatter(record));
31+
_sink.add(_formatter(record));
3032
}
3133
}

lib/src/logger.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ abstract interface class Logger implements Interface {
4141
factory Logger.detached([String? name]) => LoggerImpl.detached(name);
4242

4343
/// Creates a new noop logger which never emits logs or delegates records to handlers.
44-
factory Logger.noop([String? name]) => NoopLogger(name);
44+
factory Logger.noop() => NoopLogger();
4545

4646
/// Retrieves or creates a logger with the given [name].
4747
///

lib/src/noop_logger.dart

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ final class NoopTimer implements Timer {
1313
}
1414

1515
final class NoopLogger with LoggerBase {
16-
NoopLogger([this.name]);
16+
factory NoopLogger() => _logger;
17+
NoopLogger._();
1718

1819
Level? _level;
1920

20-
static final NoopLogger _logger = NoopLogger();
21+
static final NoopLogger _logger = NoopLogger._();
2122
static final NoopTimer _timer = NoopTimer();
2223

2324
@override
@@ -29,43 +30,30 @@ final class NoopLogger with LoggerBase {
2930
Level get level => _level ?? Level.info;
3031

3132
@override
32-
final String? name;
33+
String? get name => null;
3334

3435
@override
3536
@pragma('vm:prefer-inline')
3637
Interface withFields([Iterable<Field>? fields]) => _logger;
3738

3839
@override
39-
set handler(Handler? handler) {
40-
// noop
41-
}
40+
set handler(Handler? handler) {/* noop */}
4241

4342
@override
44-
set filter(Filter? handler) {
45-
// noop
46-
}
43+
set filter(Filter? handler) {/* noop */}
4744

4845
@override
4946
Timer startTimer(String message, {Level level = Level.debug}) => _timer;
5047

5148
@override
52-
void log(Level level, String message, [Iterable<Field>? fields]) {
53-
// noop
54-
}
49+
void log(Level level, String message, [Iterable<Field>? fields]) {/* noop */}
5550

5651
@override
5752
String toString() {
5853
final buffer = StringBuffer();
5954

6055
buffer.write('NoopLogger(');
6156

62-
if (name != null) {
63-
buffer
64-
..write('name=')
65-
..write(name)
66-
..write(', ');
67-
}
68-
6957
buffer
7058
..write('level=')
7159
..write(level.name)

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ environment:
1818

1919
dependencies:
2020
meta: ^1.15.0
21+
file: ^7.0.1
2122

2223
dev_dependencies:
2324
test: ^1.25.8

0 commit comments

Comments
 (0)