260 lines
7.4 KiB
Dart
260 lines
7.4 KiB
Dart
import 'dart:developer' as developer;
|
||
import 'package:flutter/foundation.dart';
|
||
|
||
/// 日志级别枚举
|
||
enum LogLevel {
|
||
debug('DEBUG', 0),
|
||
info('INFO', 1),
|
||
warning('WARNING', 2),
|
||
error('ERROR', 3),
|
||
fatal('FATAL', 4);
|
||
|
||
final String name;
|
||
final int level;
|
||
|
||
const LogLevel(this.name, this.level);
|
||
}
|
||
|
||
/// 日志工具类
|
||
/// 提供统一的日志记录功能,支持不同的日志级别
|
||
class Logger {
|
||
// 私有构造函数,防止实例化
|
||
Logger._();
|
||
|
||
/// 当前日志级别(开发模式下为DEBUG,生产模式下为INFO)
|
||
static LogLevel _currentLevel = kDebugMode ? LogLevel.debug : LogLevel.info;
|
||
|
||
/// 日志标签
|
||
static const String _tag = 'InspoSnap';
|
||
|
||
/// 设置日志级别
|
||
static void setLogLevel(LogLevel level) {
|
||
_currentLevel = level;
|
||
}
|
||
|
||
/// 检查是否应该记录该级别的日志
|
||
static bool _shouldLog(LogLevel level) {
|
||
return level.level >= _currentLevel.level;
|
||
}
|
||
|
||
/// 记录调试日志
|
||
static void debug(String message, {Object? error, StackTrace? stackTrace}) {
|
||
if (_shouldLog(LogLevel.debug)) {
|
||
_log(LogLevel.debug, message, error: error, stackTrace: stackTrace);
|
||
}
|
||
}
|
||
|
||
/// 记录信息日志
|
||
static void info(String message, {Object? error, StackTrace? stackTrace}) {
|
||
if (_shouldLog(LogLevel.info)) {
|
||
_log(LogLevel.info, message, error: error, stackTrace: stackTrace);
|
||
}
|
||
}
|
||
|
||
/// 记录警告日志
|
||
static void warning(String message, {Object? error, StackTrace? stackTrace}) {
|
||
if (_shouldLog(LogLevel.warning)) {
|
||
_log(LogLevel.warning, message, error: error, stackTrace: stackTrace);
|
||
}
|
||
}
|
||
|
||
/// 记录错误日志
|
||
static void error(String message, {Object? error, StackTrace? stackTrace}) {
|
||
if (_shouldLog(LogLevel.error)) {
|
||
_log(LogLevel.error, message, error: error, stackTrace: stackTrace);
|
||
}
|
||
}
|
||
|
||
/// 记录致命错误日志
|
||
static void fatal(String message, {Object? error, StackTrace? stackTrace}) {
|
||
if (_shouldLog(LogLevel.fatal)) {
|
||
_log(LogLevel.fatal, message, error: error, stackTrace: stackTrace);
|
||
}
|
||
}
|
||
|
||
/// 内部日志记录方法
|
||
static void _log(
|
||
LogLevel level,
|
||
String message, {
|
||
Object? error,
|
||
StackTrace? stackTrace,
|
||
}) {
|
||
final logMessage = '[$level.name] $message';
|
||
|
||
// 开发环境下使用 developer.log
|
||
if (kDebugMode) {
|
||
developer.log(
|
||
logMessage,
|
||
name: _tag,
|
||
time: DateTime.now(),
|
||
level: level.level,
|
||
error: error,
|
||
stackTrace: stackTrace,
|
||
);
|
||
}
|
||
|
||
// 生产环境下可以考虑发送到日志服务器
|
||
if (!kDebugMode && level.level >= LogLevel.error.level) {
|
||
// TODO: 在生产环境下实现日志上报功能
|
||
// _reportToServer(level, message, error, stackTrace);
|
||
}
|
||
}
|
||
|
||
/// 记录方法进入(用于调试)
|
||
static void enter(String methodName, [Map<String, dynamic>? parameters]) {
|
||
if (_shouldLog(LogLevel.debug)) {
|
||
final message = parameters != null
|
||
? 'Entering $methodName with parameters: $parameters'
|
||
: 'Entering $methodName';
|
||
debug(message);
|
||
}
|
||
}
|
||
|
||
/// 记录方法退出(用于调试)
|
||
static void exit(String methodName, [dynamic result]) {
|
||
if (_shouldLog(LogLevel.debug)) {
|
||
final message = result != null
|
||
? 'Exiting $methodName with result: $result'
|
||
: 'Exiting $methodName';
|
||
debug(message);
|
||
}
|
||
}
|
||
|
||
/// 记录方法执行时间
|
||
static Future<T> measureTime<T>(
|
||
String operationName,
|
||
Future<T> Function() operation,
|
||
) async {
|
||
final stopwatch = Stopwatch()..start();
|
||
|
||
try {
|
||
Logger.enter(operationName);
|
||
final result = await operation();
|
||
stopwatch.stop();
|
||
Logger.exit(operationName);
|
||
Logger.info('$operationName completed in ${stopwatch.elapsedMilliseconds}ms');
|
||
return result;
|
||
} catch (error, stackTrace) {
|
||
stopwatch.stop();
|
||
Logger.error('$operationName failed after ${stopwatch.elapsedMilliseconds}ms',
|
||
error: error, stackTrace: stackTrace);
|
||
rethrow;
|
||
}
|
||
}
|
||
|
||
/// 记录同步方法执行时间
|
||
static T measureSyncTime<T>(
|
||
String operationName,
|
||
T Function() operation,
|
||
) {
|
||
final stopwatch = Stopwatch()..start();
|
||
|
||
try {
|
||
Logger.enter(operationName);
|
||
final result = operation();
|
||
stopwatch.stop();
|
||
Logger.exit(operationName);
|
||
Logger.info('$operationName completed in ${stopwatch.elapsedMilliseconds}ms');
|
||
return result;
|
||
} catch (error, stackTrace) {
|
||
stopwatch.stop();
|
||
Logger.error('$operationName failed after ${stopwatch.elapsedMilliseconds}ms',
|
||
error: error, stackTrace: stackTrace);
|
||
rethrow;
|
||
}
|
||
}
|
||
|
||
/// 记录对象状态(用于调试)
|
||
static void dumpObject(String objectName, Object object) {
|
||
if (_shouldLog(LogLevel.debug)) {
|
||
debug('$objectName state: ${object.toString()}');
|
||
}
|
||
}
|
||
|
||
/// 记录异常信息
|
||
static void logException(
|
||
String context,
|
||
Object error, {
|
||
StackTrace? stackTrace,
|
||
bool isFatal = false,
|
||
}) {
|
||
final logLevel = isFatal ? LogLevel.fatal : LogLevel.error;
|
||
final message = 'Exception in $context: ${error.toString()}';
|
||
|
||
_log(logLevel, message, error: error, stackTrace: stackTrace);
|
||
}
|
||
|
||
/// 清理日志(如果有本地日志文件)
|
||
static Future<void> clearLogs() async {
|
||
// TODO: 如果有本地日志文件,实现清理逻辑
|
||
info('Logs cleared');
|
||
}
|
||
|
||
/// 获取日志级别名称
|
||
static String getLevelName(LogLevel level) {
|
||
return level.name;
|
||
}
|
||
|
||
/// 检查是否处于调试模式
|
||
static bool get isDebugMode => kDebugMode;
|
||
|
||
/// 检查是否处于发布模式
|
||
static bool get isReleaseMode => kReleaseMode;
|
||
|
||
/// 获取当前日志级别
|
||
static LogLevel get currentLevel => _currentLevel;
|
||
}
|
||
|
||
/// 日志混入类,方便在类中使用日志功能
|
||
mixin LoggerMixin {
|
||
/// 记录调试日志
|
||
void logDebug(String message, {Object? error, StackTrace? stackTrace}) {
|
||
Logger.debug(message, error: error, stackTrace: stackTrace);
|
||
}
|
||
|
||
/// 记录信息日志
|
||
void logInfo(String message, {Object? error, StackTrace? stackTrace}) {
|
||
Logger.info(message, error: error, stackTrace: stackTrace);
|
||
}
|
||
|
||
/// 记录警告日志
|
||
void logWarning(String message, {Object? error, StackTrace? stackTrace}) {
|
||
Logger.warning(message, error: error, stackTrace: stackTrace);
|
||
}
|
||
|
||
/// 记录错误日志
|
||
void logError(String message, {Object? error, StackTrace? stackTrace}) {
|
||
Logger.error(message, error: error, stackTrace: stackTrace);
|
||
}
|
||
|
||
/// 记录致命错误日志
|
||
void logFatal(String message, {Object? error, StackTrace? stackTrace}) {
|
||
Logger.fatal(message, error: error, stackTrace: stackTrace);
|
||
}
|
||
|
||
/// 记录方法进入(用于调试)
|
||
void logEnter(String methodName, [Map<String, dynamic>? parameters]) {
|
||
Logger.enter('$runtimeType.$methodName', parameters);
|
||
}
|
||
|
||
/// 记录方法退出(用于调试)
|
||
void logExit(String methodName, [dynamic result]) {
|
||
Logger.exit('$runtimeType.$methodName', result);
|
||
}
|
||
|
||
/// 记录方法执行时间
|
||
Future<T> logMeasureTime<T>(
|
||
String operationName,
|
||
Future<T> Function() operation,
|
||
) async {
|
||
return await Logger.measureTime('$runtimeType.$operationName', operation);
|
||
}
|
||
|
||
/// 记录同步方法执行时间
|
||
T logMeasureSyncTime<T>(
|
||
String operationName,
|
||
T Function() operation,
|
||
) {
|
||
return Logger.measureSyncTime('$runtimeType.$operationName', operation);
|
||
}
|
||
} |