Winston日志框架使用

winston日志框架使用

原來(lái)一直是使用log4js做日志輸出,原來(lái)只是輸出到標(biāo)準(zhǔn)輸出中,用了3年了,一直沒(méi)換過(guò)?,F(xiàn)在為了將詳細(xì)的日志都記錄下來(lái),不光輸出到標(biāo)準(zhǔn)出,而且根據(jù)服務(wù)的分層輸出到不同的文件中。如:全部的log都輸出到debug文件及標(biāo)準(zhǔn)輸出中,service層的log輸出service.log文件中,dao層的log輸出到dao.log文件中,為了防止log文件過(guò)大,需按日期切分,如:按天。

為何選擇winston

  1. github start數(shù)多,夠直接把。
  2. 更加靈活,可以靈活的組織transport,來(lái)完成比較復(fù)雜的日志輸出任務(wù)。
  3. 日志格式為json字符串,方便后期分析,當(dāng)然可以自定義format.
  4. 支持簡(jiǎn)單的log分析,Profiling。
  5. 支持stream Api。
  6. 簡(jiǎn)單Log Query Api,當(dāng)然無(wú)法和專(zhuān)業(yè)的日志分析工具比。

我要達(dá)到的效果

  1. 按天生成日志文件。
  2. 根據(jù)不同的代碼分層來(lái)產(chǎn)生不同的log輸出到不同的文件。
  3. 所有分層產(chǎn)生的log不光輸出到log文件還要輸出到標(biāo)準(zhǔn)輸出。
  4. 自定義格式化日志輸出,輸出到標(biāo)準(zhǔn)輸出的格式便于讀取,輸出到log文件的格式便于分析。
  5. 可以捕獲系統(tǒng)崩潰異常。

日志輸出方法

整合多個(gè)transport及封裝

格式化輸出到標(biāo)準(zhǔn)輸出的日志格式。

格式為

[2017-09-21 23:41:05.122] [DEBUG] - 輸出日志的module 日志詳細(xì)信息

但是在winston中沒(méi)有可以像log4js一樣可以定義category,為了達(dá)到這個(gè)效果,我們利用winston的 meta 特性來(lái)實(shí)現(xiàn)這一功能。winston中log方法輸出的最后一個(gè)參數(shù)為對(duì)象的話(huà),會(huì)被解析成 meta,我們?cè)?code>meta中自定義一個(gè)
module字段來(lái)標(biāo)記日志來(lái)自哪個(gè)模塊。

const myLogFormatter = function (options) {
    const timestamp = options.timestamp();
    const level = options.level.toUpperCase();
    const message = options.message || '';
    let module = 'default';
    // meta中module,標(biāo)記日志來(lái)自哪個(gè)模塊
    if (options.meta && options.meta.module) {
      module = options.meta.module;
    }
    const formatted = `[${timestamp}] [${level}] ${module} - `;
    if (options.colorize) {
      const colorStr = winston.config.colorize(options.level, formatted);
      return `${colorStr}${message}`;
    }
    return `${formatted}${message}`;
};

創(chuàng)建標(biāo)準(zhǔn)輸出的transport

const transportConsole = new winston.transports.Console({
    json: false,
    prettyPrint:true,
    colorize: true,
    level:'debug',
    timestamp: function () {
        return moment().format('YYYY-MM-DD HH:MM:ss.SSS');
    },
    formatter: myLogFormatter,
});

創(chuàng)建所有日志輸出到文件的transport,日志輸出到debug.log

const debugTransportFile = new winston.transports.File({
    name: 'full',
    filename: __dirname + '/logs/debug.log',
    json: true,
    level:'debug',
    maxsize: 1024 * 1024 * 10 // 10MB
});

service模塊專(zhuān)用輸出到文件的transport,日志輸出到service.log

const serviceTransportFile = new winston.transports.File({
    name: 'service',
    filename: __dirname + '/logs/service.log',
    json: true,
    level:'debug',
    maxsize: 1024 * 1024 * 10 // 10MB
});

dao模塊專(zhuān)用輸出到文件的transport,日志輸出到dao.log

const daoTransportFile = new winston.transports.File({
    name: 'dao',
    filename: __dirname + '/logs/dao.log',
    json: true,
    level:'debug',
    maxsize: 1024 * 1024 * 10 // 10MB
});

為各個(gè)container添加transport

// default container輸出日志到標(biāo)準(zhǔn)輸出及debug.log文件中
winston.loggers.add('default', {
  transports: [
    transportConsole,
    debugTransportFile
  ],
});
// service container輸出日志到標(biāo)準(zhǔn)輸出、debug.log及service.log文件中
winston.loggers.add('service', {
    transports: [
        transportConsole,
        serviceTransportFile,
        debugTransportFile
    ],
});
// dao container輸出日志到標(biāo)準(zhǔn)輸出、debug.log及dao.log文件中
winston.loggers.add('dao', {
    transports: [
        transportConsole,
        daoTransportFile,
        debugTransportFile
    ],
});

代理各個(gè)containerdebug、info等方法,達(dá)到可以顯示日志來(lái)自哪個(gè)module的功能。

const defaultLog = winston.loggers.get('default');
const serviceLog = winston.loggers.get('service');
const daoLog = winston.loggers.get('dao');
// 封裝default
const getDefaultLogger = (module) => {
  return {
    debug: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      defaultLog.debug.apply(defaultLog, fullParams);
    },
    info: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      defaultLog.info.apply(defaultLog, fullParams);
    },
    warn: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      defaultLog.warn.apply(defaultLog, fullParams);
    },
    error: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      defaultLog.error.apply(defaultLog, fullParams);
    }
  };
};
// 封裝service
const getServiceLogger = (module) => {
  return {
    debug: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      serviceLog.debug.apply(serviceLog, fullParams);
    },
    info: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      serviceLog.info.apply(serviceLog, fullParams);
    },
    warn: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      serviceLog.warn.apply(serviceLog, fullParams);
    },
    error: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      serviceLog.error.apply(serviceLog, fullParams);
    }
  };
};
// 封裝dao
const getDaoLogger = (module) => {
  return {
    debug: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      daoLog.debug.apply(daoLog, fullParams);
    },
    info: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      daoLog.info.apply(daoLog, fullParams);
    },
    warn: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      daoLog.warn.apply(daoLog, fullParams);
    },
    error: (...args) => {
      const meta = { module };
      const fullParams = args.concat(meta);
      daoLog.error.apply(daoLog, fullParams);
    }
  };
};

封裝后如何使用?

比如在我們代碼代碼的service層中的userService中打印日志“登錄成功”,日志級(jí)別為info。

getServiceLogger('userService').info('登錄成功');

控制臺(tái)輸出為:

[2017-09-22 00:09:45.026] [INFO] userService - 登錄成功

此日志會(huì)輸出在標(biāo)準(zhǔn)輸出中、debug.log中及service.log中,日志中寫(xiě)入的控制臺(tái)輸出的略有不同。

寫(xiě)入的日志格式為:

{"module":"userService","level":"info","message":"登錄成功","timestamp":"2017-09-21T16:01:45.026Z"}

更多功能

我寫(xiě)了幾個(gè)demo,包括基本使用,多個(gè)輸出源,捕獲系統(tǒng)崩潰錯(cuò)誤,按天生成日志文件。代碼地址為:

winstonDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評(píng)論 19 139
  • 在應(yīng)用程序中添加日志記錄總的來(lái)說(shuō)基于三個(gè)目的:監(jiān)視代碼中變量的變化情況,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 5,153評(píng)論 0 6
  • 在應(yīng)用程序中添加日志記錄總的來(lái)說(shuō)基于三個(gè)目的:監(jiān)視代碼中變量的變化情況,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 5,214評(píng)論 1 13
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,983評(píng)論 25 709
  • Ch.1 做自己的女神 自信、愛(ài)自己、贊美自己、樹(shù)立自己的風(fēng)格 自信的女人愛(ài)自己,沒(méi)有一處不愛(ài),包括缺憾。 有了自...
    ThatLight閱讀 707評(píng)論 0 5

友情鏈接更多精彩內(nèi)容