206 lines
5.3 KiB
Dart
206 lines
5.3 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:logger/logger.dart';
|
|
|
|
/// AppLogger is a singleton class that provides centralized logging functionality
|
|
/// throughout the application using the logger package.
|
|
class AppLogger {
|
|
// Private constructor
|
|
AppLogger._internal();
|
|
|
|
// Singleton instance
|
|
static final AppLogger _instance = AppLogger._internal();
|
|
|
|
// Factory constructor to return the singleton instance
|
|
factory AppLogger() => _instance;
|
|
|
|
// Logger instance
|
|
late final Logger _logger;
|
|
|
|
// Initialize the logger with custom configuration
|
|
void init({Level? logLevel, bool? stackTraceEnabled}) {
|
|
_logger = Logger(
|
|
level: logLevel ?? (kDebugMode ? Level.debug : Level.info),
|
|
printer: PrettyPrinter(
|
|
methodCount: stackTraceEnabled ?? false ? 2 : 0,
|
|
errorMethodCount: 8,
|
|
lineLength: 120,
|
|
colors: true,
|
|
printEmojis: true,
|
|
dateTimeFormat: DateTimeFormat.onlyTimeAndSinceStart,
|
|
),
|
|
output: _CustomConsoleOutput(),
|
|
filter: _CustomLogFilter(),
|
|
);
|
|
}
|
|
|
|
// Get the logger instance (for advanced usage)
|
|
Logger get logger => _logger;
|
|
|
|
// Convenient logging methods
|
|
void debug(message, {error, StackTrace? stackTrace}) {
|
|
_logger.d(message, error: error, stackTrace: stackTrace);
|
|
}
|
|
|
|
void info(message, {error, StackTrace? stackTrace}) {
|
|
_logger.i(message, error: error, stackTrace: stackTrace);
|
|
}
|
|
|
|
void warning(message, {error, StackTrace? stackTrace}) {
|
|
_logger.w(message, error: error, stackTrace: stackTrace);
|
|
}
|
|
|
|
void error(message, {error, StackTrace? stackTrace}) {
|
|
_logger.e(message, error: error, stackTrace: stackTrace);
|
|
}
|
|
|
|
void fatal(message, {error, StackTrace? stackTrace}) {
|
|
_logger.f(message, error: error, stackTrace: stackTrace);
|
|
}
|
|
|
|
// Network logging
|
|
void logNetwork({
|
|
required String method,
|
|
required String url,
|
|
int? statusCode,
|
|
requestBody,
|
|
responseBody,
|
|
error,
|
|
}) {
|
|
final buffer = StringBuffer();
|
|
buffer.writeln('🌐 Network Request:');
|
|
buffer.writeln(' Method: $method');
|
|
buffer.writeln(' URL: $url');
|
|
|
|
if (statusCode != null) {
|
|
buffer.writeln(' Status: $statusCode');
|
|
}
|
|
|
|
if (requestBody != null) {
|
|
buffer.writeln(' Request Body: $requestBody');
|
|
}
|
|
|
|
if (responseBody != null) {
|
|
buffer.writeln(' Response: $responseBody');
|
|
}
|
|
|
|
if (error != null) {
|
|
buffer.writeln(' Error: $error');
|
|
}
|
|
|
|
if (error != null) {
|
|
_logger.e(buffer.toString());
|
|
} else if (statusCode != null && statusCode >= 400) {
|
|
_logger.w(buffer.toString());
|
|
} else {
|
|
_logger.i(buffer.toString());
|
|
}
|
|
}
|
|
|
|
// Performance logging
|
|
void logPerformance(String operation, Duration duration) {
|
|
final milliseconds = duration.inMilliseconds;
|
|
final message = '⏱️ Performance: $operation took ${milliseconds}ms';
|
|
|
|
if (milliseconds > 1000) {
|
|
_logger.w(message);
|
|
} else {
|
|
_logger.d(message);
|
|
}
|
|
}
|
|
|
|
// Navigation logging
|
|
void logNavigation(String from, String to) {
|
|
_logger.i('🧭 Navigation: $from → $to');
|
|
}
|
|
|
|
// Custom log with tag
|
|
void logWithTag(String tag, message, {Level? level}) {
|
|
final taggedMessage = '[$tag] $message';
|
|
|
|
switch (level ?? Level.info) {
|
|
case Level.debug:
|
|
debug(taggedMessage);
|
|
break;
|
|
case Level.info:
|
|
info(taggedMessage);
|
|
break;
|
|
case Level.warning:
|
|
warning(taggedMessage);
|
|
break;
|
|
case Level.error:
|
|
error(taggedMessage);
|
|
break;
|
|
case Level.fatal:
|
|
fatal(taggedMessage);
|
|
break;
|
|
default:
|
|
info(taggedMessage);
|
|
}
|
|
}
|
|
|
|
// Close the logger (call this in app disposal if needed)
|
|
void close() {
|
|
_logger.close();
|
|
}
|
|
}
|
|
|
|
/// Custom log filter to control which logs are shown
|
|
class _CustomLogFilter extends LogFilter {
|
|
@override
|
|
bool shouldLog(LogEvent event) {
|
|
// In debug mode, show all logs
|
|
if (kDebugMode) {
|
|
return true;
|
|
}
|
|
|
|
// In release mode, only show warnings and above
|
|
return event.level.value >= Level.warning.value;
|
|
}
|
|
}
|
|
|
|
/// Custom console output for better control over log output
|
|
class _CustomConsoleOutput extends ConsoleOutput {
|
|
@override
|
|
void output(OutputEvent event) {
|
|
// You can customize how logs are output here
|
|
// For example, you could write to a file in addition to console
|
|
super.output(event);
|
|
|
|
// Example: Write errors to a file (uncomment if needed)
|
|
// if (event.level == Level.error || event.level == Level.fatal) {
|
|
// _writeToFile(event.lines.join('\n'));
|
|
// }
|
|
}
|
|
|
|
// Example method for writing to file (implement if needed)
|
|
// Future<void> _writeToFile(String log) async {
|
|
// // Implementation for file writing
|
|
// }
|
|
}
|
|
|
|
// Global logger instance for easy access
|
|
final appLogger = AppLogger();
|
|
|
|
// Extension for convenient logging on any object
|
|
extension LoggerExtension on Object {
|
|
void logDebug([String? message]) {
|
|
appLogger.debug(message ?? toString());
|
|
}
|
|
|
|
void logInfo([String? message]) {
|
|
appLogger.info(message ?? toString());
|
|
}
|
|
|
|
void logWarning([String? message]) {
|
|
appLogger.warning(message ?? toString());
|
|
}
|
|
|
|
void logError([String? message, error, StackTrace? stackTrace]) {
|
|
appLogger.error(
|
|
message ?? toString(),
|
|
error: error,
|
|
stackTrace: stackTrace,
|
|
);
|
|
}
|
|
}
|