114 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'dart:io';
 | 
						|
 | 
						|
import 'package:logging/logging.dart';
 | 
						|
import 'package:path/path.dart' as path;
 | 
						|
 | 
						|
class LogManager {
 | 
						|
  static LogManager? _instance;
 | 
						|
  final Logger _logger;
 | 
						|
  late IOSink? _logSink;
 | 
						|
 | 
						|
  factory LogManager.getInstance() {
 | 
						|
    _instance ??= LogManager._internal();
 | 
						|
    return _instance!;
 | 
						|
  }
 | 
						|
 | 
						|
  LogManager._internal() : _logger = Logger('MumbleBullet') {
 | 
						|
    _logSink = null;
 | 
						|
  }
 | 
						|
 | 
						|
  void initialize({
 | 
						|
    required Level level,
 | 
						|
    required bool logToConsole,
 | 
						|
    String? logFilePath,
 | 
						|
    int maxLogFiles = 5,
 | 
						|
    int maxLogSizeBytes = 1024 * 1024, // 1MB
 | 
						|
  }) {
 | 
						|
    Logger.root.level = level;
 | 
						|
 | 
						|
    if (logToConsole) {
 | 
						|
      Logger.root.onRecord.listen((record) {
 | 
						|
        stdout.writeln('${record.time}: ${record.level.name}: ${record.message}');
 | 
						|
        if (record.error != null) {
 | 
						|
          stdout.writeln('Error: ${record.error}');
 | 
						|
        }
 | 
						|
        if (record.stackTrace != null) {
 | 
						|
          stdout.writeln('Stack trace: ${record.stackTrace}');
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (logFilePath != null) {
 | 
						|
      _setupFileLogging(logFilePath: logFilePath, maxLogFiles: maxLogFiles, maxLogSizeBytes: maxLogSizeBytes);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void _setupFileLogging({required String logFilePath, required int maxLogFiles, required int maxLogSizeBytes}) {
 | 
						|
    final directory = path.dirname(logFilePath);
 | 
						|
    final dirFile = Directory(directory);
 | 
						|
    if (!dirFile.existsSync()) {
 | 
						|
      dirFile.createSync(recursive: true);
 | 
						|
    }
 | 
						|
 | 
						|
    // Check if log rotation is needed
 | 
						|
    final logFile = File(logFilePath);
 | 
						|
    if (logFile.existsSync() && logFile.lengthSync() > maxLogSizeBytes) {
 | 
						|
      _rotateLogFiles(logFilePath, maxLogFiles);
 | 
						|
    }
 | 
						|
 | 
						|
    _logSink = logFile.openWrite(mode: FileMode.append);
 | 
						|
 | 
						|
    Logger.root.onRecord.listen((record) {
 | 
						|
      _logSink?.writeln('${record.time}: ${record.level.name}: ${record.message}');
 | 
						|
      if (record.error != null) {
 | 
						|
        _logSink?.writeln('Error: ${record.error}');
 | 
						|
      }
 | 
						|
      if (record.stackTrace != null) {
 | 
						|
        _logSink?.writeln('Stack trace: ${record.stackTrace}');
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  void _rotateLogFiles(String logFilePath, int maxLogFiles) {
 | 
						|
    // Remove oldest log file if maxLogFiles is reached
 | 
						|
    for (var i = maxLogFiles; i >= 1; i--) {
 | 
						|
      final oldFile = File('$logFilePath.$i');
 | 
						|
      if (oldFile.existsSync() && i == maxLogFiles) {
 | 
						|
        oldFile.deleteSync();
 | 
						|
      } else if (oldFile.existsSync()) {
 | 
						|
        oldFile.renameSync('$logFilePath.${i + 1}');
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    // Rename current log file to .1
 | 
						|
    final currentFile = File(logFilePath);
 | 
						|
    if (currentFile.existsSync()) {
 | 
						|
      currentFile.renameSync('$logFilePath.1');
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void close() {
 | 
						|
    _logSink?.flush();
 | 
						|
    _logSink?.close();
 | 
						|
    _logSink = null;
 | 
						|
  }
 | 
						|
 | 
						|
  Logger get logger => _logger;
 | 
						|
 | 
						|
  void debug(String message, [Object? error, StackTrace? stackTrace]) {
 | 
						|
    _logger.fine(message, error, stackTrace);
 | 
						|
  }
 | 
						|
 | 
						|
  void info(String message, [Object? error, StackTrace? stackTrace]) {
 | 
						|
    _logger.info(message, error, stackTrace);
 | 
						|
  }
 | 
						|
 | 
						|
  void warning(String message, [Object? error, StackTrace? stackTrace]) {
 | 
						|
    _logger.warning(message, error, stackTrace);
 | 
						|
  }
 | 
						|
 | 
						|
  void error(String message, [Object? error, StackTrace? stackTrace]) {
 | 
						|
    _logger.severe(message, error, stackTrace);
 | 
						|
  }
 | 
						|
}
 |