1.  使用

有两种方式使用winston,一是通过默认的logger,二是实例化自己的Logger,前者设计的目的是在应用程序中共享logger比较方便。

1.1 使用默认Logger

使用默认的logger很方便,直接通过winston模块获取,logger的任何方法都可以通过默认的logger实例得到。

var winston = require('winston');
winston.log('info','Hello distributed log files!');
winston.info('Hello distributed log files!');
winston.level = 'debug';
winston.log('debug','Now my debug message are written to console!'); 

默认情况logger仅仅只设置了console。可以通过add()和remove()来增加和清除其他处理方式。
winston.add(winston.transports.File,{filename:'somefile.log'});
winston.remove(winston.transports.Console);

或者使用configure()来配置。

winston.configure({
transports:[new (winston.transports.File)({filename:'somefile.log'})]
});

Winston更多处理方式的文档,可以查看Winston Transports文档。

1.2 自定义Logger

如果你想管理loggers对象的生存期,可以自定义logger对象。

 var logger =  new (winston.Logger)({
level:'info',
transports:[
new (winston.transports.Console)(),
new (winston.transports.File)({filename:'somefile.log'})
]
});

它和默认的logger工作方式一样。

logger.log('info','Hello distributed log files!');
logger.info('Hello distributed log files!');
logger.add(winston.transports.File)
 .remove(winston.transports.Console);

同样,使用configure方法也可以重新配置winston.Logger。

var logger =  new (winston.Logger)({
level:'info',
transports:[
new (winston.transports.Console)(),
new (winston.transports.File)({filename:'somefile.log'})
]
});
//替换以前整个transports通过一个新的配置
logger.configure({
level:'verbose',
transports:[
new (require('winston-daily-rotate-file'))(opts)
]
});

2.元数据处理

除了打印字符串信息,winston也能够打印JSON元数据,如下:

winston.log('info','Test Log Message',{anything:'This is metadata'});

不同的日志方式可能导致储存对象会发生变化,有一个比较好的方式去操作元数据:

1.Console:Logger via util.inspect(meta)
2.File:Logger via util.inspect(meta)

3.同种日志类型多种处理方式

通过定义,可以对相同transports的winston.transports.File设置多种不同level处理方式。

var logger = new (winston.Logger)({
transports:[
new (winston.transports.File)({
name : 'info-file',
filename:'filelog-info.log',
level:'info'
}),
new (winston.transports.File)({
name:'error-file',
filename:'filelog-error.log',
level:'error'
})
]
});

如果你想删除其中一种处理方式,可以如下:

logger.remove("info-file");

在这个例子中也可以通过删除Transport本身获得相同的效果:

var infoFile = logger.transports[0];
logger.remove(infoFile);

4.分析

除了对消息和元数据进行处理之外,winston对任何logger也有一个简单的分析机制:

//开始分析test,
//使用Date.now()来标记一个异步操作
winston.profile("test");
setTimeout(function(){
//结束分析test
winston.profile('test');
},1000)
//info: test durationMs=1001

所有分析信息默认设置为'info',在这个配置中消息和元数据都是可选的,没有明显的区别,但是我还是说出这个建议或者问题。

5.字符串插值

log提供和util.format一样的字符串插值方法,允许这样打印信息:

logger.log('info','test message %s', 'my string');
//info: test message my string
logger.log('info','test message %d',123);
//info: test message 123
logger.log('info','test message %j',{number:123},{});
//info: test message {"number":123}
logger.log('info','test message %s, %s','first','second',{number:123});
//info: test message first, second number=123
logger.log('info','test message', 'first', 'second', {number:123});
//info: test message first second number=123
logger.log('info','test message %s,%s','first','second',{number:123},function(){});
//info: test message first,second number=123
logger.log('info','test message', 'first','second',{number:123},function(){});
//info: test message first second number=123

6.查询日志

winston提供查询日志接口,和Logger-like类似,具体可以查看Loggly Search API.

var options = {
from:new Date - 24 * 60 * 60 * 1000,
util:new Date,
limit:10,
start:0,
order:'desc',
fields:['./somefile.log']
};
/*
找出昨天到今天的日志
*/
winston.query(options,function(err,results){
if(err){
throw err;
}
console.log(results);
});

7.日志流

streaming允许从你选择的处理方式流水返回日志。

winston.stream({start: -1}).on('log',function(log){
console.log(log);
});

异常

winston可以在进程中捕获和记录uncaughtException事件。

有两种不同方法能实现这个功能,分别是在默认的logger实例和自定义的实例。

如果你想通过默认的logger来使用这个特征,调用实例的.handleExceptions的方法

//你能增加一个单独的异常日志给.handleException

winston.handleException(new winston.transports.File({
filename:'path/to/exception.log'
}));
//也可以设置.handleException为true当你增加一个处理方式给winston
//可以使用.humanReadableUnhandledException选项或者更多可读的异常 winston.add(winston.transports.File,{
filename:'path/to/all-logs.log',
handleException:true,
humanReadableUnhandledException:true
}); //多个处理方式也能被异常操纵 winston.handleException([transports1,transports2,....]);

 退出和不退出

默认情况下,winston会退出如果记录到一个未捕获异常之后,如果不想退出。设置exitOnError =  false

var logger = new (winston.Logger)({
exitOnError:false
});
//或者这样
logger.exitOnError = false;

当自定义logger实例,你可以给一个处理方式传递exceptionHandlers属性或者在任何处理方式设置handlerExceptions。

例子1:

var logger = new (winston.Logger)({
transports:[
new winston.transports.File({
filename:'path/to/all-logs.log'
})
],
exceptionHandlers:[
new winston.transports.File({
filename:'path/to/exceptions.log'
})
]
});

例子2:

var logger = new (winston.Logger)({
transports:[
new winston.transports.Console({
json:true,
handleException:true
})
],
exitOnError:false
});

exitOnError选项也可以是一个函数,能防止某些错误的类型二退出。

function ignoreEpipe(err){
return err.code !== 'EPIPE';
}
var logger = new (winston.Logger)({
exitOnError:ignoreEpipe
});
//或者像这样:
logger.exitOnError = ignoreEpipe; 

日志等级

这个很简单了

进一步阅读

winston的事件和回调

每一个winston.Logger实例也都是一个EventEmitter实例,一个log事件被触发当写日志成功。

logger.on('logging',function(transport,level,msg,meta){
//msg和meta已经用level记录在[transport]
});
logger.info('CHILL WINSTON',{seriously:true});

值得一提的是,logger还能触发一个“错误”事件,如果你不想操作异常,你可以用来处理或者忽略它

logger.on("error",function(err){
/* do something */
});
//或者忽略它
logger.emitErrs = false;

每个logging方法在最后一个字段也有一个可选的回调函数,它触发当所有的transports已经特殊信息完毕

logger.info('CHILL WINSTON',{seriously:true},function(err.level.msg,meta)){
//msg和meta已经用level记录在[transport]
}

多个winston类目的日志

常常在一个大的,比较复杂的应用中是非常必要使用多个日志实例。每个日志对应不同的特性或者类型,winston有两种方式来处理:

通过winston.loggers或者winston.Container的实例。事实上,winston.loggers也是winston.Container预先定义的实例。

winston.loggers.add('category1',{
console:{
level:'silly',
colorize:true,
label:'category one'
},
file:{
filename:'/path/to/some/file'
}
}); winston.loggers.add('category2',{
couchdb:{
host:'127.0.0.1',
port:5984
}
});

注意:在应用中,你要访问你预配置的logger,你需要require("winston")在你的文件中。

var winston = require("winston");

var category1 = winston.loggers.get('category1');
category1.info('logging from you Ioc Contains-based logger'); 

如果你喜欢Container你可以实例化

var winston = require("winston"),
container = new winston.container(); container.add('category1',{
console:{
level:"silly",
colorize:true
},
file:{
filename:'path/to/some/file'
}
})

过滤和重写

过滤允许修正日志消息的内容,重写允许修改日志元数据,即掩盖日志中不出现的数据。

过滤和重写都是一个函数数组,它被创建一个winston.Logger对象时被提供。

var logger = new winston.Logger({
rewriters:[function(level,msg,meta){}],
filters:[function(level,msg,meta){}]
});

就像其他数组一样,修改日志能运行在winston内部,也没有什么副作用。

var logger = new winston.Logger({
rewriters:[function(level,msg,meta){}],
filters:[function(level,msg,meta){}]
});
logger.filters.push(function(level,msg,meta){
return meta.production ? maskCardNumbers(msg) :msg;
});
logger.info('transaction with card number 1234567890123456 successful');

这个输出的结果可能是:

info:transaction with card number 123456****2345 successful

而重写,你想把creditCard元数据重新实例化:

logger.rewriters.push(function(level,msg,meta){
if(meta.creditCard){
meta.creditCard = maskCardNumbers(meta.creditCard);
}
return meta;
}); logger.info('transaction ok',{creditCard:123456789012345});

输出结果可能是:

info:transaction ok creditCard=123456****2345

增加自定义日志处理方式

增加一个自定义处理方式非常简单,所有需要做的是接受一些选项,设置名字,执行log()方法,和winston暴露的一些transports(处理方式)

var util = require('util'),
winston = require('winston'); var CustomLogger = winston.transports.CustomLogger = function(options){
//logger的名字
this.name = 'customLogger';
//选项设置一个等级
this.level = options.level || "info";
//配置你想要的处理方式
}
// 继承winston.Transports,你能利用基本函数和.handlerExceptions()
util.inherit(CustomLogger,winston.Transports);
CustomLogger.prototype.log = function(level,msg,meta,callback){
callback(null,true);
}

自定义日志格式

指定自定义格式应该为transport设置格式化函数,目前支持格式化的transports是:Console, File和Memory。可选对象作为参数传递给格式化对象。

一般属性有:时间戳、等级、消息、和元数据,取决于transports类型可能会有额外的属性。

var logger =  new (winston.Logger)({
transports:[
new (winston.transports.Console)({
timestamp:function(){
return Date.now();
}
formatter:function(options){
//返回字符串给logger
return options.timestamp() + ' ' +options.level.toUpperCase() + ''
(options.message ? options.message: "") + (options.meta && Object.keys(options.meta).length ?
'\n\t' + JSON.string(options.meta):"");
}
});
]
});
logger.info('Data to log');

winston写日志(译)的更多相关文章

  1. .NET Core的日志[5]:利用TraceSource写日志

    从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...

  2. [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件

    本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...

  3. Spring 使用 SLF4J代替 Commons Logging 写日志 异常

    项目的日志更换成slf4j和logback后,发现项目无法启动.错误提示 Caused by: java.lang.NoClassDefFoundError: Lorg/apache/commons/ ...

  4. 程序员的修养 -- 如何写日志(logging)

      在程序中写日志是一件非常重要,但是很容易被开发人员忽视的地方.写好程序的日志可以帮助我们大大减轻后期维护压力. 在实际的工作中,开发人员往往迫于的巨大时间压力,而写日志又是一个非常繁琐的事情,往往 ...

  5. ASP.NET Core 开发-Logging 使用NLog 写日志文件

    ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以 ...

  6. 2.2 代码块--delphi 写日志模块

    //2.2 代码块--写日志 //调用例句如:LogMsg('FTP上传线程终止',False,true); procedure LogMsg(AMsg: string; const blnIsErr ...

  7. php大力力 [041节] 今天没有写日志哈

    php大力力 [041节]  今天没有写日志哈  如何下拉,左边的side颜色  能顺延下去?? 今天做了一个表格显示

  8. 转:NLog 自定义日志内容,写日志到数据库;修改Nlog.config不起作用的原因

    转:http://www.cnblogs.com/tider1999/p/4308440.html NLog的安装请百度,我安装的是3.2.NLog可以向文件,数据库,邮件等写日志,想了解请百度,这里 ...

  9. How To Write In Sharepoint Log File 怎么对自定义的MOSS代码写日志

    How To Write In Sharepoint Log File 怎么对自定义的MOSS代码写日志 Add Microsoft.Office.Server dll in your project ...

随机推荐

  1. linux shell for循环使用命令中读取到的值实例

    #!/bin/bash file="states" for state in `cat $file` do echo "Visit beautiful $state&qu ...

  2. Centos网络配置

    网上搜索:centos网络配置的方法,主要包括dns.网关.IP地址,主要是配置resolv.conf\network\ifcfg-eth0这些网络配置文件. 稍后我会就centos7的网络配置进行实 ...

  3. shell实现ping命令查看哪些主机在线

    #!/bin/bash .{..};do -i 0.5 $a >/dev/null && echo "$a 在线" || echo "$a 离线&q ...

  4. JavaScript根据文件名判断文件类型

    //JavaScript根据文件名判断文件类型 var imgExt = new Array(".png",".jpg",".jpeg",& ...

  5. 【小白的CFD之旅】10 敲门实例

    按黄师姐的说法,做好第一个案例很重要.第一个案例既可以帮助理解CFD的工作流程,还可以帮助熟悉软件的操作界面. 黄师姐推荐的入门案例来自于ANSYS官方提供的培训教程,是一个关于交叉管内流动混合的案例 ...

  6. 帆软报表FineReport SQLServer数据库连接失败常见解决方案

    1. 问题描述 帆软报表FineReport客户端连接SQLServer(2000.2005等),常常会出现如下错误:com.microsoft.sqlserver.jdbc.SQLServerExc ...

  7. 【2016-11-7】【坚持学习】【Day22】【Oracle 分页查询】

    方法1: select * from (select rownum rn, temp.* from ( +sqlText+ ) temp ) where rn > "+ start + ...

  8. 苹果iOS强制HTTPS迫在眉睫,距离2017年只剩1天,准备好了么?

    其实不久前苹果就发了通告,要求ios上的应用全部以HTTPS来进行接口调用以及数据访问,这样做是为了数据安全,一方面为了自己,另一方面也是对应用的要求更加严格,这么做很好,也加强了市场app的规范,虽 ...

  9. 第三章SQL编程

    本章目标: 1.使用变量 2.输出语句 3.数据类型转换 4.逻辑控制语句 5.批处理 一.变量 1.什么是变量呢? 变量是存储数据的容器 T-SQL中的变量分为局部变量和全局变量 2.局部变量 局部 ...

  10. PHP的魔法方法__set() __get()

    php的魔法方法__set()与__get() Tags: PHP 我们先来看看官方的文档如何定义他们的: public void __set(string $name, mixed $value); ...