snap_wish/lib/core/utils/logger.dart
2025-09-12 18:17:35 +08:00

260 lines
7.4 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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