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

1 回复

更多关于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,那么只有 warningerrorwtf 级别的日志会被记录。

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(), // 使用自定义日志过滤器
);
回到顶部