Flutter日志记录插件log_4_dart_2的使用
Flutter日志记录插件log_4_dart_2的使用
概述
log_4_dart_2
是一个用于高级日志记录的 Dart 包,支持多种可配置的追加器。
目录
前言
该包正在建设中,仍需要一些调整和代码改进!
安装
pubspec.yaml
在 pubspec.yaml
文件中更新并添加以下依赖项:
dependencies:
log_for_dart_2: ^1.1.0
导入
导入包:
import 'package:log_4_dart_2/log_4_dart_2.dart';
使用
设置日志记录器
有以下两种方式来设置 Logger
:
- 将日志记录器配置存储在一个单独的 JSON 文件中,并将文件的完整路径传递给
initFromFile()
方法。 - 创建一个
Map<String, dynamic>
来保存配置,并将其传递给init()
方法。
void main(List<String> arguments){
// 从配置文件初始化日志记录器
Logger.initFromFile('/path/to/log4d.json');
// 或者通过 Map<String, dynamic>
Logger.init(config);
}
注意,Logger.init(...)
只能调用一次,最好在主方法中调用。它会内部配置一个实例,可以通过静态 Logger
(或 Logger.instance
)访问。
查看示例配置获取完整的示例。
日志记录
Logger
提供了多个方法用于不同级别的日志记录。
static String TAG = 'TestClass';
Logger.debug('Lorem Ipsum', tag: TAG);
Logger.trace('Lorem Ipsum', tag: TAG);
Logger.info('Lorem Ipsum', tag: TAG);
Logger.warn('Lorem Ipsum', tag: TAG);
Logger.error('Lorem Ipsum', tag: TAG);
Logger.fatal('Lorem Ipsum', tag: TAG);
注意,从版本 1.0.0 开始,旧的方式需要稍作修改:Logger().debug(...)
现在应称为 Logger().logDebug(...)
(相应级别)。
以下是两种被认为是客户端上下文中最佳的日志记录方式:
1: 通过 Logger
类上的静态日志方法直接记录:
class PlainClient {
void doStuff() {
Logger.debug('message', tag: 'some tag');
}
}
2: 通过 Log4Dart
混入。注意,这里的日志方法被称为 logDebug(...)
等,以明确其来自客户端代码。
class Client with Log4Dart {
void doStuff() {
logDebug('message', tag: 'some tag');
}
}
注意,在这两种情况下,都需要先初始化 Logger
,例如在主方法中:
void main() async {
await Logger.init(kLog4DartConfig);
...
}
追加器和配置
ConsoleAppender
ConsoleAppender
是一个简单的追加器,将每个日志条目追加到控制台输出。
type
: 追加器类型,必须设置为CONSOLE
。dateFormat
: 用于追加器的日期格式,默认为yyyy-MM-dd HH:mm:ss
。level
: 该追加器的日志级别。format
: 日志输出的格式。参见日志格式了解更多。brackets
: 是否用括号包裹所有消息块,消息不包括在内。
FileAppender
FileAppender
将每个日志条目追加到日志文件。
type
: 追加器类型,必须设置为FILE
。level
: 该追加器的日志级别。format
: 日志输出的格式。参见日志格式了解更多。dateFormat
: 用于追加器的日期格式,默认为yyyy-MM-dd HH:mm:ss
。filePattern
: 用于文件名的模式。fileExtension
: 文件扩展名,默认为log
。path
: 文件路径。rotationCycle
: 追加器的旋转周期。参见旋转周期。默认为NEVER
。
注意:如果指定了路径,路径也必须存在!
HttpAppender
HttpAppender
通过 HTTP POST
请求将日志条目发送到指定 URL。
type
: 追加器类型,必须设置为HTTP
。dateFormat
: 用于追加器的日期格式,默认为yyyy-MM-dd HH:mm:ss
。level
: 该追加器的日志级别。url
:POST
请求的 URL。headers
: 一个包含头名称和值的列表,名称和值由:
分隔。例如"Content-Type:application/json"
。
EmailAppender
EmailAppender
通过电子邮件将日志条目发送到指定地址。
type
: 追加器类型,必须设置为EMAIL
。dateFormat
: 用于追加器的日期格式,默认为yyyy-MM-dd HH:mm:ss
。level
: 该追加器的日志级别。host
: SMTP 服务器。user
: 服务器的用户。password
: 给定用户的密码。port
: SMTP 服务器的端口。fromMail
: 发送者的电子邮件。默认使用用户名。fromName
: 发送者的名称。to
: 要发送邮件的电子邮件地址列表。toCC
: 要接收副本的电子邮件地址列表。toBCC
: 要接收盲副本的电子邮件地址列表。ssl
: 是否使用 SSL。templateFile
: 包含要使用的模板的文件的完整路径。如果没有提供模板,追加器将发送 JSON 格式的日志记录。可以使用与格式设置相同的占位符。参见日志格式了解更多。html
: 给定模板是否为纯文本或 HTML。默认为false
。
注意:由于使用了 mailer
包来提供此追加器,这仅适用于需要用户/密码授权的邮件服务器。
MySqlAppender
MySqlAppender
将每个日志条目追加到 MySQL 数据库的表中。
type
: 追加器类型,必须设置为MYSQL
。level
: 该追加器的日志级别。host
: MySQL 数据库的主机。user
: 用户。password
: 用户的密码。port
: 主机的端口。database
: 数据库名称。table
: 要写入的表。
创建表时使用给定的语句。替换 <table>
为你所需的表名。
CREATE TABLE `$table` (
`id` INT NOT NULL AUTO_INCREMENT,
`tag` VARCHAR(45) NULL,
`level` VARCHAR(45) NULL,
`message` VARCHAR(45) NULL,
`time` VARCHAR(45) NULL,
PRIMARY KEY (`id`));
添加自定义追加器
Log4Dart2
支持使用自定义追加器。创建一个继承自 Appender
并实现 append
和 init
方法的类。
import 'package:log_4_dart_2/log_4_dart_2.dart';
class CustomAppender extends Appender {
@override
void append(LogRecord logRecord) {
// 实现 append 方法
}
@override
void init(Map<String, dynamic> config, bool test, DateTime date) {
// 实现 init 方法
}
@override
Appender getInstance(){
return CustomAppender();
}
@override
String getType(){
return 'CustomAppender';
}
}
在日志记录器初始化之前,通过 registerAppender()
方法注册自定义追加器。
Logger.instance.registerAppender(CustomAppender());
日志格式
可以为某些追加器配置日志条目的格式。
%d
: 日期。%i
: 标识符。%t
: 标签。%l
: 日志级别。%m
: 消息。%f
: 包含行号和列号的文件名(例如package:my_project/chat_screen.dart(42:7)
)。%c
: 包含行号的方法名和类名(例如ChatScreenState.getCurrentUser:42
)。
当应用程序在 Zone 中运行时,还可以添加 MDC(映射诊断上下文)占位符:
%X{
最好通过一个例子来展示:
void main() async {
await Logger.init(kLog4DartConfig);
// 我们定义 zone 的值作为第 3 个参数:zoneValues
// 这不能在测试回调中运行,目前这可以在直接运行或进一步执行...
await runZonedGuarded(() async {
// 应用程序运行时,我们在某个地方将一些变量设置到 zone:
if (Zone.current['LOG_SESSION_HASH_KEY'] != null) {
// 将 LOG_SESSION_HASH_KEY 设置为 865a15
Zone.current['LOG_SESSION_HASH_KEY'].add(generateMd5Fingerprint('Some data like app start timestamp'));
}
// 然后我们记录并交由日志库处理
Logger.debug('hello world');
}, (Object error, StackTrace stackTrace) {
print(error);
}, zoneValues: {
// 将 LOG_DEVICE_HASH_KEY 设置为 8634e3c65a15
'LOG_DEVICE_HASH_KEY': [generateMd5Fingerprint('Data that is consistent per platform like values delivered by device_info_plus')],
'vLOG_SESSION_HASH_KEY': [], // 当前为空,进一步设置
});
}
// 只是一个想法...
String generateMd5Fingerprint(String input) {
return md5.convert(utf8.encode(input)).toString().substring(0, 6);
}
}
使用此格式设置:
'format': '%d%i%X{logging.device-hash}%X{logging.session-hash}%t%l%c %m %f'
应该打印类似以下内容,其中两个部分 [634e3c]
和 [865a15]
对于日志分析非常有用:
[2022-04-28 14:44:26.934][CONSOLE][634e3c][865a15][tag-512][DEBUG][ClientWithLogEx.logStuff:60] hello world [package:my_project/chat_screen.dart(60:5)]
示例:
"%d %i %t %l %m"
"This log entry was created on %d from class %t from thread %i. It has the level %l and the message %m"
HTML 模板示例:
<h1>Log Event</h1>
<p>Message: %m</p>
<p>Class: %t</p>
<p>Time: %d</p>
<p>Level: %l</p>
旋转周期
旋转周期可以为某些追加器配置。它定义了创建新文件以存储日志数据的频率。
NEVER
(永不旋转)DAY
(每日旋转)WEEK
(每周旋转)MONTH
(每月旋转,每个月的第一天)YEAR
(每年旋转,每年的第一天)
示例配置
以下是带有所有可能追加器及其设置的一些配置示例。
var config = {
'appenders': [
{
'type': 'CONSOLE',
'format': '%d%i%t%l%c %m %f',
'level': 'TRACE',
'dateFormat': 'yyyy-MM-dd HH:mm:ss.SSS',
'brackets': true,
'mode': 'stdout'
},
{
'type': 'FILE',
'dateFormat' : 'yyyy-MM-dd HH:mm:ss',
'format': '%d %i %t %l %m',
'level': 'INFO',
'filePattern': 'log4dart2_log',
'fileExtension': 'txt',
'path': '/path/to/',
'rotationCycle': 'MONTH'
},
{
'type': 'EMAIL',
'dateFormat' : 'yyyy-MM-dd HH:mm:ss',
'level': 'INFO',
'host': 'smtp.test.de',
'user': 'test@test.de',
'password': 'test',
'port': 1,
'fromMail': 'test@test.de',
'fromName': 'Jon Doe',
'to': [
'test1@example.com',
'test2@example.com'
],
'toCC': [
'test1@example.com',
'test2@example.com'
],
'toBCC': [
'test1@example.com',
'test2@example.com'
],
'ssl': true,
'templateFile': '/path/to/template.txt',
'html': false
},
{
'type': 'HTTP',
'dateFormat' : 'yyyy-MM-dd HH:mm:ss',
'level': 'INFO',
'url': 'api.example.com',
'headers': [
'Content-Type:application/json'
]
},
{
'type': 'MYSQL',
'level': 'INFO',
'host': 'database.example.com',
'user': 'root',
'password': 'test',
'port': 1,
'database': 'mydatabase',
'table' : 'log_entries'
}
]
};
{
"appenders": [
{
"type": "CONSOLE",
"dateFormat" : "yyyy-MM-dd HH:mm:ss",
"format": "%d %i %t %l %m",
"level": "INFO"
},
{
"type": "FILE",
"dateFormat" : "yyyy-MM-dd HH:mm:ss",
"format": "%d %i %t %l %m",
"level": "INFO",
"filePattern": "log4dart2_log",
"fileExtension": "txt",
"path": "/path/to/",
"rotationCycle": "MONTH"
},
{
"type": "EMAIL",
"dateFormat" : "yyyy-MM-dd HH:mm:ss",
"level": "INFO",
"host": "smtp.test.de",
"user": "test@test.de",
"password": "test",
"port": 1,
"fromMail": "test@test.de",
"fromName": "Jon Doe",
"to": [
"test1@example.com",
"test2@example.com"
],
"toCC": [
"test1@example.com",
"test2@example.com"
],
"toBCC": [
"test1@example.com",
"test2@example.com"
],
"ssl": true,
"templateFile": "/path/to/template.txt",
"html": false
},
{
"type": "HTTP",
"dateFormat" : "yyyy-MM-dd HH:mm:ss",
"level": "INFO",
"url": "api.example.com",
"headers": [
"Content-Type:application/json"
]
},
{
"type": "MYSQL",
"level": "INFO",
"host": "database.example.com",
"user": "root",
"password": "test",
"port": 1,
"database": "mydatabase",
"table" : "log_entries"
}
]
}
更多关于Flutter日志记录插件log_4_dart_2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter日志记录插件log_4_dart_2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用log_4_dart_2
插件进行日志记录的示例代码。log_4_dart_2
是一个流行的日志记录库,可以帮助你更好地管理和记录应用程序中的日志信息。
首先,确保你已经在pubspec.yaml
文件中添加了log_4_dart_2
依赖:
dependencies:
flutter:
sdk: flutter
log_4_dart_2: ^x.y.z # 请将x.y.z替换为实际的版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用log_4_dart_2
进行日志记录:
- 导入包:
在你的Dart文件中导入log_4_dart_2
包。
import 'package:log_4_dart_2/log_4_dart_2.dart';
- 配置日志记录器:
在应用程序的入口点(通常是main.dart
文件)中配置日志记录器。
void main() {
// 配置日志记录器
var logger = Logger('MyAppLogger');
logger.level = LogLevel.DEBUG; // 设置日志级别
logger.addAppender(
ConsoleAppender()..layout = PatternLayout(pattern: '[%d] [%p] %c: %m%n'),
);
// 运行应用程序
runApp(MyApp());
}
- 记录日志:
在你的应用程序中记录不同级别的日志。
import 'package:flutter/material.dart';
import 'package:log_4_dart_2/log_4_dart_2.dart';
void main() {
var logger = Logger('MyAppLogger');
logger.level = LogLevel.DEBUG;
logger.addAppender(
ConsoleAppender()..layout = PatternLayout(pattern: '[%d] [%p] %c: %m%n'),
);
runApp(MyApp(logger: logger));
}
class MyApp extends StatelessWidget {
final Logger logger;
MyApp({required this.logger});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(logger: logger),
);
}
}
class MyHomePage extends StatefulWidget {
final Logger logger;
MyHomePage({required this.logger});
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
// 记录不同级别的日志
widget.logger.debug('This is a debug message');
widget.logger.info('This is an info message');
widget.logger.warn('This is a warning message');
widget.logger.error('This is an error message');
widget.logger.fatal('This is a fatal message');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Text('Check your console for log messages'),
),
);
}
}
在这个示例中,我们创建了一个全局的Logger
实例,并在应用程序的入口点配置了它。然后,在MyHomePage
组件的initState
方法中,我们记录了不同级别的日志消息。这些日志消息将按照配置的格式输出到控制台。
请注意,log_4_dart_2
插件的具体API和使用方式可能会根据版本的不同而有所变化。因此,建议查阅该插件的官方文档以获取最新和最准确的信息。