Files
amirrezaghabeli a7e208a5de merged branches
2025-08-12 09:11:26 +03:30

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,
);
}
}