Flutter上下文日志记录插件contextual_logging的使用

Flutter上下文日志记录插件contextual_logging的使用

我们都有过打印日志的经历。这些日志通常会打印到控制台或文件中。Dart 提供了一些方法来帮助我们记录信息,比如:

print('A message');
debugPrint('Another message');

这些方法在调试时非常有用。但是,当你需要追踪用户的行为时,仅仅打印信息可能不够。这时就需要添加上下文信息。上下文信息可以帮助我们了解是谁打印了这条信息。

什么是上下文日志记录?

上下文日志记录能够为每条日志消息添加额外的信息,以便更好地理解日志的来源。例如,你可以在每次打印日志时都手动添加上下文信息:

print('My Controller : A message');
debugPrint('My Controller : Another message');

虽然这种方法可行,但每次都写上下文信息可能会很繁琐。这就是 contextual_logging 插件要解决的问题。

日志记录器

混入类

你可以将 ContextualLogging 混入到你的类中,以启用上下文日志记录功能:

class MyController with ContextualLogging {
  Future<void> init() async {
    log.i('Initializing ...'); // 使用 log 字段访问日志功能
    await fetchData();
    log.i('Initialized!');
  }
}

这样,你就可以在控制台看到类似这样的输出:

10:03:00 [I] MyController : Initializing ...
10:03:01 [I] MyController : Initialized!

配置

默认情况下,每个带有 ContextualLogging 混入的类都会创建一个日志记录器。一旦你添加了混入,你就可以配置这个日志记录器。

上下文

logContext 属性用于在日志消息前添加上下文信息。默认情况下,它取值为 this.toString()。你可以覆盖这个属性以自定义上下文信息:

class MyController with ContextualLogging {
  @override
  String get logContext => 'SomeOtherContext';
  
  void test() {
    log.i('Test'); // 19:12:00 [I] SomeOtherContext : Test
  }
}
自定义日志记录器

如果你想要使用自定义的日志记录器,可以覆盖 customLogger 属性:

class MyController with ContextualLogging {
  @override
  Logger get customLogger => Logger(/* 配置日志记录器 */);
  
  void test() {
    log.i('Test'); // 仍然通过 `log` 属性访问
  }
}

默认日志配置

如果你想一次性更改所有对象的日志配置,可以在应用程序启动之前进行如下操作:

// ContextualLogger 混入默认使用这个默认日志记录器来获取附加了混入的对象的日志记录器。
ContextualLoggingConfig.defaultLogger = (forObject) => MyBeautifulLogger(forObject);

这样,所有带有 ContextualLogger 混入的对象都将使用这个新的配置。

上下文日志打印机

这是什么?

当你设置 ContextualLoggingConfig.defaultLogger 属性时,你可以创建一个日志记录器并提供任何你需要的日志打印机。或者你可以使用 ContextualLogger 默认使用的打印机 ContextualLogPrinter。这个打印机使日志消息看起来像这样:

12:01:00 [I] SomeOtherContext : Test

而不是这样:

Test

配置打印机

有很多属性可以修改:

属性 类型 描述 默认值
forObject Object 创建日志记录器的对象 this
timeFormat DateFormat 当前时间戳的格式 HH:mm:ss
timeInUtc bool 当前时间戳是否为 UTC false
printTime bool 是否打印时间戳 true
logLevelLabel Function 日志级别前缀 [I], [W] 等
示例

假设你已经覆盖了打印机:

ContextualLoggingConfig.defaultLogger = (forObject) {
  return Logger(
    printer: ContextualLogPrinter(
      forObject: forObject,
      printTime: false, // 注意!
    ),
  );
};

// 这将使你的消息看起来像这样:

[I] MyController : A message
日志级别标签

日志级别标签允许你区分不同级别的日志消息。logger 包提供了以下级别:

级别 函数 默认值 Emoji
Verbose log.v [V] None
Debug log.d [D] 🐛
Info log.i [I] 💡
Warning log.w [W] ⚠️
Error log.e [E] ⛔️
WTF log.wtf [WTF] 🗿
Nothing log.log None None

你可以覆盖 logLevelLabel 属性来自定义前缀:

ContextualLoggingConfig.defaultLogger = (forObject) {
  return Logger(
    printer: ContextualLogPrinter(
      forObject: forObject,
      logLevelLabel: (level) {
        /* 返回给定级别的前缀 */
      },
    ),
  );
  
// 或者这样做以启用表情符号级别的功能!
ContextualLoggingConfig.defaultLogger = (forObject) {
  return Logger(
    printer: ContextualLogPrinter(
      forObject: forObject,
      logLevelLabel: ContextualLogPrinter.emojiLevelLabel,
    ),
  );

完整示例

下面是一个完整的示例,展示了如何使用 contextual_logging 插件:

import 'package:contextual_logging/src/contextual_logger.dart';

Future<void> main() async {
  final weatherController = WeatherController();
  final cityController = CityController();

  await weatherController.initialize();
  await cityController.initialize();
}

class WeatherController with ContextualLogger {
  Future<void> initialize() async {
    try {
      log.i('Initializing ...');
      await fetchSomeData();
      log.i('Initialized successfully!');
    } on Exception catch (e, s) {
      log.e('Failed to initialize', e, s);
    }
  }
}

class CityController with ContextualLogger {
  Future<void> initialize() async {
    try {
      log.i('Initializing ...');
      await fetchSomeData();
      log.i('Initialized successfully!');
    } on Exception catch (e, s) {
      log.e('Failed to initialize', e, s);
    }
  }
}

Future<void> fetchSomeData() {
  return Future.value();
}

更多关于Flutter上下文日志记录插件contextual_logging的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter上下文日志记录插件contextual_logging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用contextual_logging插件进行上下文日志记录的示例代码。

首先,确保你已经在pubspec.yaml文件中添加了contextual_logging依赖:

dependencies:
  flutter:
    sdk: flutter
  contextual_logging: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中配置和使用contextual_logging插件。以下是一个简单的示例:

1. 配置Logger

首先,在你的应用入口(通常是main.dart)中配置Logger:

import 'package:flutter/material.dart';
import 'package:contextual_logging/contextual_logging.dart';

void main() {
  // 初始化Logger
  final logger = Logger(
    name: 'MyAppLogger',
    level: LogLevel.verbose, // 设置日志级别
    output: (log) {
      // 自定义日志输出,这里简单地打印到控制台
      print('${log.level.name}: ${log.message} - ${log.context}');
    },
  );

  // 设置全局Logger(可选,但推荐)
  Logger.global = logger;

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

2. 使用Logger记录日志

在你的应用组件中,你可以使用Logger来记录日志,并附带上下文信息:

import 'package:flutter/material.dart';
import 'package:contextual_logging/contextual_logging.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final logger = Logger.global; // 获取全局Logger

    return Scaffold(
      appBar: AppBar(
        title: Text('Contextual Logging Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 记录一个带有上下文的日志
            final contextData = {
              'screen': 'HomeScreen',
              'button': 'pressed',
            };
            logger.verbose('Button pressed', context: contextData);

            // 你也可以在其他逻辑中记录日志,例如网络请求、数据处理等
            // logger.info('Fetching data from API', context: {'api': 'exampleAPI'});
          },
          child: Text('Log Context'),
        ),
      ),
    );
  }
}

3. 运行应用并查看日志

运行你的Flutter应用,并点击按钮。你应该能在控制台中看到类似以下的日志输出:

VERBOSE: Button pressed - {screen: HomeScreen, button: pressed}

这个示例展示了如何在Flutter应用中使用contextual_logging插件进行上下文日志记录。你可以根据需要调整日志级别、输出格式和上下文数据。这个插件对于调试和监控复杂应用非常有用,因为它允许你轻松地关联日志消息和特定的上下文信息。

回到顶部