node端日志记录工具-winston

一、简介

winston是一个简单通用的node服务端日志记录库。它有如下特点:

支持多种存储介质,例如将日志存储在本地文件、远程数据库或者直接输出在控制台

支持日志记录分级,以区分其重要程度

灵活可扩展,日志的格式、等级、存储介质皆可自定义

二、用法

1、使用createLogger方法创建日志记录器(官方推荐使用方式)

自创建日志记录器 折叠源码

import winston from 'winston'

const logger = winston.createLogger({

  level: 'info',

  format: winston.format.json(),

  transports: [

    new winston.transports.File({ filename: 'error.log', level: 'error' }),

    new winston.transports.File({ filename: 'combined.log' })

  ]

});

三、可配置项

参数名称默认值参数说明

levelswinston.config.npm日志记录分级标准,可自定义。

level'info'日志记录的最低级别,取值于levels,只记录严重程度大于等于'info'的日志记录

formatwinston.format.json每一条日志记录的格式,可自定义

transports[ ]指明了日志的存储位置,可扩展

exitOnErrortrue当winston发生错误时,是否退出

silentfalse设置为true,则所有日志记录被禁止,(实际访问时logger.silent为undefined)

1.levels

levels指明了日志可以分为几个级别,各级别定义了日志记录的严重程度。每个级别对应一个整数,随着整数值由小到大,记录的严重性由高到低。winston.config中内置了三个levels,默认的levels为winston.config.npm(如下),还有两个是winston.config.cli和winston.config.syslog。除了内置的levels,我们也可以自己定义levels。

winston.config.npm

{

  levels:

   { error: 0,

     warn: 1,

     info: 2,

     http: 3,

     verbose: 4,

     debug: 5,

     silly: 6

   },

  colors:

   { error: 'red',

     warn: 'yellow',

     info: 'green',

     http: 'green',

     verbose: 'cyan',

     debug: 'blue',

     silly: 'magenta'

   }

}

在使用winston.createLogger方法创建了日志记录器logger并在配置项中指定了levels之后,levels中的每个属性都将会作为记录器的方法,例如logger.error、logger.info。因此,写入记录时将有两种方式:logger.log(level,message[,meta])和logger.[levels属性](message[,meta])。

写入记录 折叠源码

//使用log方法写入日志

logger.log('info', "this is a info message")

logger.log('warn', "this is a warn message")

logger.log('error', "this is a error message")


//使用levels属性方法写入日志

logger.info("this is a info message")

logger.warn("this is a warn messagee")

logger.error("this is a error message")

2.format

     在winston中,写入的每一条日志记录都是一个info 对象。info 对象是一个可变的对象,但是它必须有level和message两个属性。format就是一系列对info 对象进行格式化处理的函数。winston内置了15个默认的格式化方法。常用的有以下几个:

colorize():控制台输出时,为日志记录中的level属性和message属性添加颜色;输出到文件时,使用此方法会导致乱码。

padlevels():格式对齐

timestamp():为info对象添加timestamp属性,属性的默认值为世界时,与北京时间有8小时时差。因此使用时要设置format参数,例timestamp({format:'YYYY-MM-DD HH:mm:ss'})

metadata():用来搜集处理写入到info对象中的元数据对象。

simple():格式化输出方法,只输出包含level属性和message属性的json

json():格式化输出方法,将info对象序列化为json输出。

printf():格式化输出方法。接收一个回调函数作为参数,可自定义输出的格式。

combine():用于将多个格式化方法合并。

info object

{

  level: 'info',               

  message: 'this is a info message!'

}

winston.format 折叠源码

import { createLogger, format, transports} from 'winston'

const { combine, metadata, timestamp, printf, colorize, padLevels } = format

const loggerDebug = createLogger({

    level: 'debug',

    format: combine(

        colorize({all: true}),

        timestamp({format: 'YYYY-MM-DD HH:mm:ss'}),

        metadata({key: 'content', fillExcept: ['timestamp', 'level', 'message']}),

        padLevels(),

        printf(info => `${info.timestamp}  ${info.message}: ${safeStringify(info.content)}`)

    ),

    transports: [

        new transports.Console()

    ]

})

3.transports

        在winston中,transport指定了日志记录的存储位置。winston内置了四个transport:Console、File、Http、Stream。除此之外,winston的贡献者及社区人员也开发了非常多的transport。

winston.transports.Console(options)

Console的可配置项 折叠源码

new winston.transports.Console({

    level: 'info', //该transport应该记录哪一level的日志,默认值与logger中设置的相同

    silent: false, //是否禁止输出,默认为false

    eol: os.EOL, //string类型,结束字符串,默认为os.EOL

    stderrLevels:[],//levels过滤后的数组,包含了应当用stderr代替stdout来记录的level,默认为空数组

    consoleWarnLevels :[] //levels过滤后的数组,包含了应当使用console.warn/stderr代替stdout的level,默认为空数组

})

winston.transports.File

(options)

File可配置项 展开源码

winston.transports.DailyRotateFile(options)

transports.DailyRotateFile 折叠源码

new transports.DailyRotateFile({

           datePattern: 'YYYY-MM-DD',//日期格式

           filename: 'logs/info/info-%DATE%.log',//日志记录路径

           // zippedArchive: true,//除正在进行记录的日志文件外,其他文件是否压缩。设置为true后,压缩文件无法删除

           maxSize: '20m',//每个文件的最大存储容量,单位可为k、m、g

           maxFiles: '30d'//日志删除的条件,可为数字或数字后加d表示的天数。

       })

winston.transports.Http

(options)

Http可配置项 折叠源码

new winston.transports.Http({

    host: 'localhost',//存储日志的主机名(Default: localhost)

    port: 80,// 端口号(Default: 80 or 443)

    path: '',//日志存储的文件路径(Default: /)

    auth: {} ,//(Default: None) 包含http认证时所使用的username和password的对象

    ssl: false// 是否使用HTTPS,(Default: false)

})

winston.transports.Stream(

options)

Stream可配置项 折叠源码

new winston.transports.Stream({

    stream: fs.createWriteStream('/dev/null'),//any Node.js stream. If an objectMode stream is provided then the entire info object will be written. Otherwise info[MESSAGE] will be written.

    level: 'info', //该transport应该记录哪一level的日志,默认值与logger中设置的相同

    silent: false, //是否禁止输出,默认为false

    eol: '\r\n', //string类型,结束字符串,默认为os.EOL

  })

四、异常处理

        当winston出现异常时,我们可以通过捕捉到这类异常,并将其记录下来。

winston异常处理 折叠源码

import { createLogger, format, transports } from 'winston'

//方法一:在创建日志记录器时,设置exceptionHandlers

const logger = createLogger({

    transports: [

        new transports.File({ filename: 'combined.log' })

    ],

    exceptionHandlers: [

        new transports.File({ filename: 'exceptions.log' })

    ]

});

//方法二:创建日志记录器后,调用logger.exceptions.handle方法添加

const logger1 = createLogger({

    transports: [

        new transports.File({ filename: 'combined.log' })

    ]

});

logger1.exceptions.handle(

    new transports.File({ filename: 'exceptions.log' })

);

五、日志查询

 使用日志记录器的query方法可以查询日志记录,它接收两个参数:查询条件options、查询结果处理函数。其中options中的可配置项可参照loggly(https://www.loggly.com/docs/api-retrieving-data/)。

日志查询 折叠源码

const options = {

  from: new Date() - (24 * 60 * 60 * 1000),

  until: new Date(),

  limit: 10,

  start: 0,

  order: 'desc',

  fields: ['message']

};

logger.query(options, function (err, results) {

  if (err) {

    /* TODO: handle me */

    throw err;

  }

  console.log(results);

});

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容