Flutter日志管理插件logcraft的使用
Flutter日志管理插件logcraft的使用
logcraft
是一个灵活的、跨平台的日志解决方案,适用于具有异步操作和基于环境配置的Dart应用程序。
特性
-
跨平台核心日志系统
- 平台无关的设计
- 可扩展的输出接收器接口
- 支持多个输出目的地
- 异步日志操作
-
基于环境的配置
- 开发环境:全量日志
- 测试环境:警告及以上级别
- 生产环境:错误及以上级别
-
多级日志
- CRITICAL:系统崩溃、致命错误
- ERROR:需要关注的错误
- WARNING:潜在问题
- INFO:一般信息
- DEBUG:调试信息
- VERBOSE:详细的调试信息
安装
在你的 pubspec.yaml
文件中添加以下依赖:
dependencies:
logcraft: ^1.0.0
然后运行:
dart pub get
使用
基础控制台日志记录
import 'package:logcraft/logcraft.dart';
void main() async {
// 初始化控制台输出
await Logger.init(LoggerConfig(
sinks: [ConsoleSink()],
environment: Environment.development,
));
// 记录日志
await Logger.info('Application started');
await Logger.debug('Test message');
await Logger.error('Error occurred');
// 清理资源
await Logger.dispose();
}
错误处理与堆栈跟踪
try {
throw Exception('Database connection failed');
} catch (e, stack) {
await Logger.error('Failed to connect', e, stack);
}
基于环境的配置
// 开发环境(全量日志)
await Logger.init(LoggerConfig(
sinks: [ConsoleSink()],
environment: Environment.development,
));
// 测试环境(警告及以上)
await Logger.init(LoggerConfig(
sinks: [ConsoleSink()],
environment: Environment.testing,
));
// 生产环境(错误及以上)
await Logger.init(LoggerConfig(
sinks: [ConsoleSink()],
environment: Environment.production,
));
自定义输出实现
class CustomSink implements LogSink {
[@override](/user/override)
Future<void> write(String message, LogLevel level) async {
// 实现自定义日志逻辑
}
[@override](/user/override)
Future<void> dispose() async {
// 清理资源
}
}
// 使用自定义接收器
await Logger.init(LoggerConfig(
sinks: [CustomSink()],
environment: Environment.development,
));
多个输出目的地
await Logger.init(LoggerConfig(
sinks: [
ConsoleSink(),
CustomSink(),
AnotherCustomSink(),
],
environment: Environment.development,
));
日志输出格式
每个日志消息包含时间戳和级别指示:
[2024-10-24 00:00:00.123][INFO] Application started
[2024-10-24 00:00:00.124][ERROR] Failed to connect
[2024-10-24 00:00:00.124][ERROR] Error details: Database connection failed
[2024-10-24 00:00:00.124][ERROR] Stack trace: ...
开发
运行测试
运行所有测试:
dart test
运行特定测试文件:
dart test test/logcraft_test.dart
示例
检查 example
目录以获取更多使用示例:
- 控制台输出
- 文件输出
- 多个输出目的地
- 按级别分文件日志
示例代码
import 'package:logcraft/logcraft.dart';
import 'dart:io';
import 'dart:convert';
/// 用于文件输出的简单实现
class FileSink implements LogSink {
final IOSink _sink;
FileSink(String path) : _sink = File(path).openWrite(mode: FileMode.append);
[@override](/user/override)
Future<void> write(String message, LogLevel level) async {
_sink.writeln(message);
await _sink.flush();
}
[@override](/user/override)
Future<void> dispose() async {
await _sink.flush();
await _sink.close();
}
}
/// 根据日志级别分文件的实现
class LevelBasedFileSink implements LogSink {
final Map<LogLevel, IOSink> _sinks = {};
final String _basePath;
LevelBasedFileSink(
String basePath, {
Set<LogLevel> levels = const {
LogLevel.error,
LogLevel.warning,
LogLevel.info,
},
bool append = true,
}) : _basePath = basePath {
// 为每个指定的级别创建对应的文件输出
for (final level in levels) {
final path = '${_basePath}.${level.name.toLowerCase()}.log';
_sinks[level] = File(path).openWrite(mode: append ? FileMode.append : FileMode.write);
}
// 创建通用日志文件
_sinks[LogLevel.verbose] = File('${_basePath}.log')
.openWrite(mode: append ? FileMode.append : FileMode.write);
}
[@override](/user/override)
Future<void> write(String message, LogLevel level) async {
final bytes = utf8.encode('$message\n');
// 写入对应级别的专门日志文件
if (_sinks.containsKey(level)) {
_sinks[level]!.add(bytes);
await _sinks[level]!.flush();
}
// 同时写入通用日志文件
_sinks[LogLevel.verbose]!.add(bytes);
await _sinks[LogLevel.verbose]!.flush();
}
[@override](/user/override)
Future<void> dispose() async {
for (final sink in _sinks.values) {
await sink.flush();
await sink.close();
}
_sinks.clear();
}
}
/// 示例 1: 基本的控制台输出
Future<void> example1_console() async {
print('\n=== Example 1: Console Output ===');
await Logger.init(LoggerConfig(
sinks: [ConsoleSink()],
environment: Environment.development,
));
await Logger.info('Starting application...');
await Logger.debug('Debug mode enabled');
await Logger.warning('Low memory warning');
await Logger.error('Failed to connect to service');
await Logger.dispose();
}
/// 示例 2: 输出到单一文件
Future<void> example2_file() async {
print('\n=== Example 2: File Output ===');
final logFile = File('example_output/app.log');
await logFile.parent.create(recursive: true);
await Logger.init(LoggerConfig(
sinks: [FileSink('example_output/app.log')],
environment: Environment.development,
));
await Logger.info('Application started');
await Logger.error('Connection error occurred');
await Logger.dispose();
print('Logs written to: ${logFile.absolute.path}');
}
/// 示例 3: 同时输出到控制台和文件
Future<void> example3_console_and_file() async {
print('\n=== Example 3: Console and File Output ===');
final logFile = File('example_output/combined.log');
await logFile.parent.create(recursive: true);
await Logger.init(LoggerConfig(
sinks: [
ConsoleSink(),
FileSink('example_output/combined.log'),
],
environment: Environment.development,
));
await Logger.info('Processing started');
await Logger.warning('Process taking longer than expected');
await Logger.error('Process failed');
await Logger.dispose();
print('Logs written to: ${logFile.absolute.path}');
}
/// 示例 4: 根据日志级别输出到不同文件
Future<void> example4_level_based_files() async {
print('\n=== Example 4: Level-based File Output ===');
await Directory('example_output').create(recursive: true);
final levelBasedSink = LevelBasedFileSink(
'example_output/app',
levels: {
LogLevel.error,
LogLevel.warning,
LogLevel.info,
},
);
await Logger.init(LoggerConfig(
sinks: [
ConsoleSink(), // 同时输出到控制台以便查看
levelBasedSink,
],
environment: Environment.development,
));
// 测试不同级别的日志
await Logger.info('User logged in');
await Logger.warning('High CPU usage detected');
await Logger.error('Database connection lost');
try {
throw Exception('Unexpected error occurred');
} catch (e, stack) {
await Logger.error('System error', e, stack);
}
await Logger.dispose();
print('Logs written to example_output/ directory:');
print('- app.log (all logs)');
print('- app.error.log (error logs)');
print('- app.warning.log (warning logs)');
print('- app.info.log (info logs)');
}
Future<void> example5_console_without_init() async {
print('\n=== Example 5: Console without init Output ===');
await Logger.info('Starting application...');
await Logger.debug('Debug mode enabled');
await Logger.warning('Low memory warning');
await Logger.error('Failed to connect to service');
await Logger.dispose();
}
/// 主函数运行所有示例
void main() async {
// 运行所有示例
await example1_console();
await example2_file();
await example3_console_and_file();
await example4_level_based_files();
await example5_console_without_init();
print(
'\nAll examples completed. Check example_output/ directory for log files.');
}
更多关于Flutter日志管理插件logcraft的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter日志管理插件logcraft的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
LogCraft
是一个用于 Flutter 应用的日志管理插件,它可以帮助开发者更方便地记录、过滤和管理日志信息。LogCraft
提供了丰富的功能,如日志级别控制、日志格式化、日志存储等。以下是如何在 Flutter 项目中使用 LogCraft
的基本步骤。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 logcraft
依赖:
dependencies:
logcraft: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 初始化 LogCraft
在你的 Flutter 应用启动时,初始化 LogCraft
。通常可以在 main.dart
文件中进行初始化:
import 'package:flutter/material.dart';
import 'package:logcraft/logcraft.dart';
void main() {
// 初始化 LogCraft
LogCraft.init(
level: LogLevel.verbose, // 设置日志级别
format: DefaultLogFormatter(), // 使用默认日志格式化器
storage: ConsoleLogStorage(), // 使用控制台日志存储
);
runApp(MyApp());
}
3. 记录日志
在你的代码中,你可以使用 LogCraft
来记录不同级别的日志信息:
void someFunction() {
LogCraft.v('Verbose log message'); // 详细日志
LogCraft.d('Debug log message'); // 调试日志
LogCraft.i('Info log message'); // 信息日志
LogCraft.w('Warning log message'); // 警告日志
LogCraft.e('Error log message'); // 错误日志
LogCraft.wtf('WTF log message'); // 严重错误日志
}
4. 日志级别控制
LogCraft
允许你通过设置 level
来控制哪些级别的日志会被记录。例如,如果你将日志级别设置为 LogLevel.warning
,那么只有 warning
、error
和 wtf
级别的日志会被记录。
LogCraft.init(
level: LogLevel.warning, // 只记录警告及以上级别的日志
format: DefaultLogFormatter(),
storage: ConsoleLogStorage(),
);
5. 日志格式化
LogCraft
允许你自定义日志的格式化方式。你可以实现 LogFormatter
接口来创建自己的日志格式化器。
class CustomLogFormatter implements LogFormatter {
[@override](/user/override)
String format(LogEntry entry) {
return '[${entry.level}] ${entry.time}: ${entry.message}';
}
}
LogCraft.init(
level: LogLevel.verbose,
format: CustomLogFormatter(), // 使用自定义日志格式化器
storage: ConsoleLogStorage(),
);
6. 日志存储
LogCraft
支持将日志存储到不同的地方,如控制台、文件、数据库等。你可以实现 LogStorage
接口来创建自己的日志存储方式。
class FileLogStorage implements LogStorage {
[@override](/user/override)
void store(LogEntry entry) {
// 将日志写入文件
}
}
LogCraft.init(
level: LogLevel.verbose,
format: DefaultLogFormatter(),
storage: FileLogStorage(), // 使用文件日志存储
);
7. 日志过滤
LogCraft
还支持日志过滤,你可以通过实现 LogFilter
接口来过滤某些日志。
class CustomLogFilter implements LogFilter {
[@override](/user/override)
bool shouldLog(LogEntry entry) {
return entry.message.contains('important'); // 只记录包含 'important' 的日志
}
}
LogCraft.init(
level: LogLevel.verbose,
format: DefaultLogFormatter(),
storage: ConsoleLogStorage(),
filter: CustomLogFilter(), // 使用自定义日志过滤器
);