@@ -8,9 +8,7 @@ import 'dart:ui';
88import 'package:flutter/foundation.dart' ;
99import 'package:path/path.dart' as p;
1010
11- class LogFileManager {
12- LogFileManager ._(this ._sendPort);
13-
11+ abstract class LogFileManager {
1412 static LogFileManager ? _instance;
1513
1614 static LogFileManager ? get instance => _instance ?? = _fromOtherIsolate ();
@@ -20,36 +18,63 @@ class LogFileManager {
2018 static LogFileManager ? _fromOtherIsolate () {
2119 final sendPort = IsolateNameServer .lookupPortByName (_logPortName);
2220 if (sendPort == null ) {
21+ debugPrint ('[mixin_logger] no logger isolate found' );
2322 return null ;
2423 }
25- return LogFileManager ._ (sendPort);
24+ return _LogFileMangerForOtherIsolate (sendPort);
2625 }
2726
2827 static Future <void > init (
2928 String logDir,
3029 int maxFileCount,
31- int maxFileLength,
32- ) async {
30+ int maxFileLength, {
31+ String ? fileLeading,
32+ }) async {
3333 final receiver = ReceivePort ();
3434 await Isolate .spawn (
3535 _logIsolate,
36- [receiver.sendPort, logDir, maxFileCount, maxFileLength],
36+ [
37+ receiver.sendPort,
38+ logDir,
39+ maxFileCount,
40+ maxFileLength,
41+ fileLeading,
42+ ],
3743 );
38- final sendPort = await receiver.first as SendPort ;
39- final removed = IsolateNameServer .removePortNameMapping (_logPortName);
40- if (removed) {
41- debugPrint ('Removed old logger isolate. this is ok if hot restarted app' );
42- }
43- IsolateNameServer .registerPortWithName (sendPort, _logPortName);
44- }
44+ final completer = Completer <void >();
45+ receiver.listen ((message) {
46+ if (message is SendPort ) {
47+ final sendPort = message;
48+ final removed = IsolateNameServer .removePortNameMapping (_logPortName);
49+ if (removed) {
50+ debugPrint (
51+ 'Removed old logger isolate. this is ok if hot restarted app' );
52+ }
53+ IsolateNameServer .registerPortWithName (sendPort, _logPortName);
54+ completer.complete ();
55+ } else {
56+ assert (false , 'unknown message: $message ' );
57+ }
58+ });
4559
46- final SendPort _sendPort;
60+ return completer.future;
61+ }
4762
4863 static Future <void > _logIsolate (List <dynamic > args) async {
4964 final responsePort = args[0 ] as SendPort ;
5065 final messageReceiver = ReceivePort ();
5166 final dir = args[1 ] as String ;
52- final logFileHandler = LogFileHandler (dir);
67+ final maxFileCount = args[2 ] as int ;
68+ final maxFileLength = args[3 ] as int ;
69+ final fileLeading = args[4 ] as String ? ;
70+
71+ final logFileHandler = LogFileHandler (
72+ dir,
73+ maxFileCount: maxFileCount,
74+ maxFileLength: maxFileLength,
75+ fileLeading: fileLeading,
76+ );
77+ LogFileManager ._instance = _LogFileManagerForLogIsolate (logFileHandler);
5378 messageReceiver.listen ((message) {
5479 if (message is String ) {
5580 logFileHandler.write (message);
@@ -58,11 +83,32 @@ class LogFileManager {
5883 responsePort.send (messageReceiver.sendPort);
5984 }
6085
86+ Future <void > write (String message);
87+ }
88+
89+ class _LogFileMangerForOtherIsolate implements LogFileManager {
90+ _LogFileMangerForOtherIsolate (this ._sendPort);
91+
92+ final SendPort _sendPort;
93+
94+ @override
6195 Future <void > write (String message) async {
6296 _sendPort.send (message);
6397 }
6498}
6599
100+ class _LogFileManagerForLogIsolate implements LogFileManager {
101+ _LogFileManagerForLogIsolate (this .handler);
102+
103+ final LogFileHandler handler;
104+
105+ @override
106+ Future <void > write (String message) {
107+ handler.write (message);
108+ return Future .value ();
109+ }
110+ }
111+
66112final _fileNameRegex = RegExp (r'^log_\d+.log$' );
67113final _fileNumberExtractRegex = RegExp (r'(?<=_)\d+(?=.log)' );
68114
@@ -73,6 +119,7 @@ class LogFileHandler {
73119 this .directory, {
74120 this .maxFileCount = 10 ,
75121 this .maxFileLength = 1024 * 1024 * 10 , // 10 MB
122+ this .fileLeading,
76123 }) : assert (maxFileCount >= 1 ),
77124 assert (maxFileLength >= 0 ) {
78125 final dir = Directory (directory);
@@ -108,10 +155,12 @@ class LogFileHandler {
108155
109156 void _prepareOutputFile () {
110157 final File outputFile;
158+ var newFileCreated = false ;
111159 if (files.isEmpty) {
112160 final file = File (p.join (directory, _generateFileName (0 )));
113161 files[0 ] = file;
114162 outputFile = file;
163+ newFileCreated = true ;
115164 } else {
116165 final max = files.keys.reduce (math.max);
117166 final file = files[max];
@@ -123,6 +172,7 @@ class LogFileHandler {
123172 final file = File (p.join (directory, _generateFileName (nextIndex)));
124173 files[nextIndex] = file;
125174 outputFile = file;
175+ newFileCreated = true ;
126176 }
127177 if (files.length > maxFileCount) {
128178 final min = files.keys.reduce (math.min);
@@ -142,6 +192,10 @@ class LogFileHandler {
142192 }
143193 _logFile = outputFile;
144194 _currentFileLength = outputFile.lengthSync ();
195+ if (newFileCreated && fileLeading != null ) {
196+ write (fileLeading! );
197+ write ('\n ' );
198+ }
145199 }
146200
147201 final String directory;
@@ -155,6 +209,8 @@ class LogFileHandler {
155209
156210 final int maxFileLength;
157211
212+ final String ? fileLeading;
213+
158214 void write (String message) {
159215 assert (_logFile != null , 'Log file is null' );
160216 final bytes = utf8.encode ('$message \n ' );
0 commit comments