马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
/// 日志级别
enum LogLevel {
verbose, // 详细信息
debug, // 调试信息
info, // 普通信息
warning, // 警告信息
error, // 错误信息
wtf // 严重错误
}
/// 应用程序日志管理类
class AppLogger {
static bool _initialized = false;
static final Map<String, Logger> _loggers = {};
// 日志级别与Logging包级别的映射
static final Map<LogLevel, Level> _levelMap = {
LogLevel.verbose: Level.FINEST,
LogLevel.debug: Level.FINE,
LogLevel.info: Level.INFO,
LogLevel.warning: Level.WARNING,
LogLevel.error: Level.SEVERE,
LogLevel.wtf: Level.SHOUT,
};
/// 初始化日志系统
static void init() {
if (_initialized) return;
hierarchicalLoggingEnabled = true;
// 在调试模式下显示所有日志在生产模式下只显示INFO级别以上
Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;
// 配置日志监听器
Logger.root.onRecord.listen((record) {
// 不在生产环境打印Verbose和Debug日志即使 Root Level 允许
if (!kDebugMode &&
(record.level == Level.FINEST ||
record.level == Level.FINER ||
record.level == Level.FINE)) {
return;
}
final lvlColor = _getLogLevelColor(record.level);
const resetColor = '\x1B[0m'; // ANSI 重置颜色代码
final emoji = _getLogEmoji(record.level);
final timestamp = DateTime.now().toString().substring(0, 19);
// 格式: 时间戳 [级别] [模块名] Emoji 日志内容
final messageHeader =
'$lvlColor$timestamp [${record.level.name}] [${record.loggerName}] $emoji $resetColor';
final messageBody = '$lvlColor${record.message}$resetColor';
final String logMessage;
if (record.error != null) {
// 添加错误详情和格式化的堆栈信息
final errorString = '$lvlColor错误: ${record.error}$resetColor';
// StackTrace 过滤:只显示应用相关的堆栈,限制行数
final stackTraceString = _formatStackTrace(record.stackTrace,
filterAppCode: true, maxLines: 15);
logMessage =
'$messageHeader $messageBody\n$errorString${stackTraceString.isNotEmpty ? '\n$lvlColor堆栈:$resetColor\n$stackTraceString' : ''}';
} else {
logMessage = '$messageHeader $messageBody';
}
// 使用 print 输出,以便颜色代码生效
// 在 release 版本中,由于 Logger.root.level 的限制,低于 INFO 的日志不会走到这里
print(logMessage);
});
_initialized = true;
}
/// 获取指定模块的日志记录器
static Logger getLogger(String name) {
if (!_initialized) init();
return _loggers.putIfAbsent(name, () {
final logger = Logger(name);
logger.level = Logger.root.level;
return logger;
});
}
/// 记录详细日志
static void v(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.verbose, message, error, stackTrace);
}
/// 记录调试日志
static void d(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.debug, message, error, stackTrace);
}
/// 记录信息日志
static void i(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.info, message, error, stackTrace);
}
/// 记录警告日志
static void w(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.warning, message, error, stackTrace);
}
/// 记录错误日志
static void e(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.error, message, error, stackTrace);
}
/// 记录严重错误日志
static void wtf(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.wtf, message, error, stackTrace);
}
// 为了向后兼容,添加简化的方法名
/// 记录信息日志(简化版)
static void info(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.info, message, error, stackTrace);
}
/// 记录错误日志(简化版)
static void error(String tag, String message,
[Object? error, StackTrace? stackTrace]) {
_log(tag, LogLevel.error, message, error, stackTrace);
}
/// 内部日志记录方法
static void _log(String tag, LogLevel level, String message,
[Object? error, StackTrace? stackTrace]) {
final logger = getLogger(tag);
final logLevel = _levelMap[level]!;
logger.log(logLevel, message, error, stackTrace);
}
/// 获取日志级别对应的emoji
static String _getLogEmoji(Level level) {
if (level == Level.FINEST || level == Level.FINER || level == Level.FINE) {
return '🔍'; // 调试
}
if (level == Level.CONFIG || level == Level.INFO) return '📘'; // 信息
if (level == Level.WARNING) return '⚠️'; // 警告
if (level == Level.SEVERE) return ''; // 错误
if (level == Level.SHOUT) return '💥'; // 严重错误
return '📝'; // 默认
}
/// 获取日志级别对应的ANSI颜色代码
static String _getLogLevelColor(Level level) {
if (level == Level.FINEST || level == Level.FINER || level == Level.FINE) {
return '\x1B[90m'; // 灰色 (Verbose/Debug)
}
if (level == Level.CONFIG || level == Level.INFO) {
return '\x1B[34m'; // 蓝色 (Info/Config)
}
if (level == Level.WARNING) return '\x1B[33m'; // 黄色 (Warning)
if (level == Level.SEVERE) return '\x1B[31m'; // 红色 (Error)
if (level == Level.SHOUT) return '\x1B[35;41m'; // 紫色 + 红色背景 (WTF/Shout)
return '\x1B[0m'; // 默认 (重置)
}
/// 格式化并过滤堆栈信息
static String _formatStackTrace(StackTrace? stackTrace,
{int maxLines = 10, bool filterAppCode = true}) {
if (stackTrace == null) return '';
final lines = stackTrace.toString().split('\n');
final formattedLines = <String>[];
const appPackagePrefix = 'package:ainoval/'; // 修改为你的应用包名
const flutterPackagePrefix = 'package:flutter/';
const dartPrefix = 'dart:';
int linesAdded = 0;
for (final line in lines) {
final trimmedLine = line.trim();
if (trimmedLine.isEmpty) continue;
bool isAppCode = trimmedLine.contains(appPackagePrefix);
bool isFrameworkCode = trimmedLine.contains(flutterPackagePrefix) ||
trimmedLine.startsWith(dartPrefix);
// 如果开启过滤,只保留应用代码;否则不过滤
// 同时排除纯dart:前缀和flutter框架内部调用除非没有应用代码帧时酌情显示
if (!filterAppCode ||
isAppCode ||
(!isFrameworkCode && !trimmedLine.startsWith('#'))) {
// 也包含一些非 package 的项目内部调用格式
// 尝试保持可点击的格式
// IDE 通常能识别类似 'package:my_app/my_file.dart:123:45' 的格式
formattedLines.add(' $trimmedLine'); // 添加缩进
linesAdded++;
if (linesAdded >= maxLines) break; // 限制最大行数
}
}
// 如果过滤后为空(可能错误发生在框架深处),则显示原始堆栈的前几行
if (formattedLines.isEmpty && lines.isNotEmpty) {
formattedLines.addAll(lines
.take(maxLines)
.map((l) => ' ${l.trim()}')
.where((l) => l.length > 2));
}
return formattedLines.join('\n');
}
}