目录
上一篇:DartVM服务器开发(第四天)--代码优化
因为家里来了同学玩,所以昨天没有更新,今天我们来学习一下使用logging这个强大的日志工具库
1. 添加logging依赖
在项目根目录下的pubspec.yaml文件中添加logging的依赖
#....
dependencies:
http_server: ^0.9.8
logging: ^0.11.3+2
然后运行pub get命令
2.初始化
导入logging这个包到你需要使用的dart文件中
import 'package:logging/logging.dart';
初始化logging工具
//监听器能监听的范围
Logger.root.level=Level.ALL;
//日志监听器
Logger.root.onRecord.listen((rec){
//rec的类为LogRecord
print('${rec.level}::${rec.time}::${rec.message}');
});
上面代码的level就是下面onRecord监听能覆盖的范围,我们传入ALL,就是全部的日志输出都监听,LogRecord是一个日志记录类,里面包换的日志的相关信息,我们来了解下这个类吧
类型 | 参数 | 介绍 |
---|---|---|
Level | level | 日志的覆盖范围(重要性相反):ALL>FINEST>FINER>FINE>CONFIG>INFO>WARNING>SEVERE>SHOUT>OFF |
String | message | 日志消息 |
Object | object | 非字符串日志消息 |
String | loggerName | 日志名字 |
DateTime | time | 日志时间 |
int | sequenceNumber | 唯一序列号 |
Object | error | 非字符串错误信息 |
StackTrace | stackTrace | 记录时的堆栈 |
Zone | zone | 日志所属区域 |
接下来,我们在服务器初始化后,输出一条日志
//....
var requestServer = await HttpServer.bind(InternetAddress.loopbackIPv6, 8080);
Logger.root.info('服务器启动:http://localhost:${requestServer.port}');
//....
然后运行我们的项目
可以看到我们成功的输出了一条日志,日志等级为Info
接下来,我们改一下初始化日志工具的等级
//...监听器只接受错误范围的信息
Logger.root.level=Level.WARNING;
//...
然后再次运行一下项目
可以看到,日志监听没有接收到INFO的输出的日志,所以,只能接收WARNING以上的等级
3.记录日志输出到文件中
logging这个日志工具库,本质上是不帮你输出到文件的,所以,我们之前不是已经定义过一个记录到文件的方法嘛,下面是结合日志工具方法
Logger.root.level=Level.ALL;
Logger.root.onRecord.listen((rec){
//基本的消息
String log='${rec.sequenceNumber}::${rec.level}::${rec.time}::${rec.message}';
//添加错误信息
if(rec.error!=null){
log+='\n::${rec.error}';
}
//添加错误的堆栈
if(rec.stackTrace!=null){
log+='\n::${rec.stackTrace.toString()}';
}
//输出日志到控制台
print(log);
//只记录等级大于等于info的信息
if(rec.level.value>=Level.INFO.value){
writeLog(log);
}
});
//.....
void writeLog(String log) async {
var date = DateTime.now();
var year = date.year;
var month = date.month;
var day = date.day;
//如果recursive为true,会创建命名目录及父级目录
Directory directory =
await new Directory('log/$year').create(recursive: true);
File file = new File('${directory.path}/$year-$month-$day.log');
file.exists().then((isExists) {
file.writeAsString(isExists ? '\n\n$log' : log, mode: FileMode.append);
});
}
4.记录异常
当发生异常时,我们可以把它记录下来,并输出到文件中,这个是很有必要的,在维护中,可以根据这个异常信息,去排查bug,下面介绍添加异常,及堆栈信息
staticFiles.errorPageHandler=(request){
if(request.uri.pathSegments.last.endsWith('.html')){
staticFiles.serveFile(new File(webPath+'/404.html'), request);
}else{
try{
handleMessage(request);
throw ArgumentError('Warning happen');
}catch(e){
try{
//有可能没有回复客户端,所以这里回复一次
request.response
..statusCode=HttpStatus.internalServerError
..close();
}catch(_){}
Logger.root.warning('请求消息发生异常',e,e.runtimeType==ArgumentError?e.stackTrace:null);
}
}
};
我这里手动触发一条异常,然后我们运行服务器,给服务器发送一条请求消息
可以看到,我们的服务器产生了异常,异常详细的记录我们在哪里出现错误,我们再来看看日志文件
生成了日志文件了,来看看里面的内容
可以看到跟日志文件一样,接下来,来看一下我封装的日志工具类
import 'dart:io';
import 'package:logging/logging.dart';
class LogUt {
static LogUt log=new LogUt();
final Level level=Level.ALL;
LogUt(){
Logger.root..level=level
..onRecord.listen((rec){
//基本的消息
String log='${rec.sequenceNumber}::${rec.level}::${rec.time}::${rec.message}';
//添加错误信息
if(rec.error!=null){
log+='\n::${rec.error}';
}
//添加错误的堆栈
if(rec.stackTrace!=null){
log+='\n::${rec.stackTrace.toString()}';
}
print(log);
//只记录等级大于info的信息
if(rec.level.value>=Level.INFO.value){
writeLog(log);
}
});
}
void finest(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.FINEST, message, error, stackTrace);
void finer(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.FINER, message, error, stackTrace);
void fine(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.FINE, message, error, stackTrace);
void config(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.CONFIG, message, error, stackTrace);
void info(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.INFO, message, error, stackTrace);
void warning(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.WARNING, message, error, stackTrace);
void severe(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.SEVERE, message, error, stackTrace);
void shout(message, [Object error, StackTrace stackTrace]) =>
Logger.root.log(Level.SHOUT, message, error, stackTrace);
}
void writeLog(String log) async {
var date = DateTime.now();
var year = date.year;
var month = date.month;
var day = date.day;
//如果recursive为true,会创建命名目录及父级目录
Directory directory =
await new Directory('log/$year').create(recursive: true);
File file = new File('${directory.path}/$year-$month-$day.log');
file.exists().then((isExists) {
file.writeAsString(isExists ? '\n\n$log' : log, mode: FileMode.append);
});
}
然后就可以通过导入该工具使用了,并且不用初始化,下面是使用
LogUt.log.finest('服务器启动:http://localhost:${requestServer.port}');
好了,今天的学习就到这里了,明天见!
如果想继续学习DartVM服务器开发,请关注我,学习更多骚操作!
- 下一篇:DartVM服务器开发(第六天)--利用注解处理请求