// set up distributed logging before everything else

var npmlog = global._global_npmlog = require('npmlog');

// npmlog is used only for emitting, we use winston for output

//不利用npmlog输出信息,而是利用winston来输出,所以将npmlog的等级设置为silent

npmlog.level = "silent";

//日志管理系统

var winston = require('winston')

//文件操作模块

  , fs = require('fs')

  //获取系统信息的模块

  , os = require('os')

  //处理和转换文件路径

  , path = require('path')

  //工具模块

  , util = require('util');

  //日期处理模块

require('date-utils');

 

//log等级定义

var levels = {

  debug: 1

, info: 2

, warn: 3

, error: 4

};

//各等级对应的字体颜色

var colors = {

  info: 'cyan'

, debug: 'grey'

, warn: 'yellow'

, error: 'red'

};

//定义log等级对应关系的字典

var npmToWinstonLevels = {

  silly: 'debug'

, verbose: 'debug'

, info: 'info'

, http: 'info'

, warn: 'warn'

, error: 'error'

};

 

var logger = null;

//时区

var timeZone = null;

//堆栈

var stackTrace = null;

 

// capture any logs emitted by other packages using our global distributed

// logger and pass them through winston

npmlog.on('log', function (logObj) {

  //根据传入的参数,得到对应的log等级,如果参数未被定义过,也就是说在字典中未找到,那么就设置为info

  var winstonLevel = npmToWinstonLevels[logObj.level] || 'info';

  //获得消息体

  var msg = logObj.message && logObj.prefix ?

              (logObj.prefix + ": " + logObj.message) :

              (logObj.prefix || logObj.message);

  logger[winstonLevel](msg);

  console.log("==========npmlog.on=================");

});

//将当前日期转化为YYYY-MM-DD HH24:MI:SS:LL形式

var timestamp = function () {

  var date = new Date();

  if (!timeZone) {

    //date.getTimezoneOffset()时差,精确到分钟,乘以60000,精确到毫秒数

    date = new Date(date.valueOf() + date.getTimezoneOffset() * 60000);

  }

  return date.toFormat("YYYY-MM-DD HH24:MI:SS:LL");

};

 

// Strip the color marking within messages.

// We need to patch the transports, because the stripColor functionality in

// Winston is wrongly implemented at the logger level, and we want to avoid

// having to create 2 loggers.

//解决winston在日志实现上bug,有时候会产生2个logger器

function applyStripColorPatch(transport) {

  var _log = transport.log.bind(transport);

  transport.log = function (level, msg, meta, callback) {

    var code = /\u001b\[(\d+(;\d+)*)?m/g;

    msg = ('' + msg).replace(code, '');

    _log(level, msg, meta, callback);

  };

}

//将log信息传输到控制台上

var _createConsoleTransport = function (args, logLvl) {

  var transport = new (winston.transports.Console)({

    name: "console"

    , timestamp: args.logTimestamp ? timestamp : undefined

    , colorize: !args.logNoColors

    , handleExceptions: true

    , exitOnError: false

    , json: false

    , level: logLvl

  });

  if (args.logNoColors) applyStripColorPatch(transport);

  return transport;

};

//将log信息传输到文件中

var _createFileTransport = function (args, logLvl) {

  var transport = new (winston.transports.File)({

      name: "file"

      , timestamp: timestamp

      , filename: args.log

      , maxFiles: 1

      , handleExceptions: true

      , exitOnError: false

      , json: false

      , level: logLvl

    }

  );

  applyStripColorPatch(transport);

  return transport;

};

//将log信息传输到webhook中,webhook就是将log信息传输到某一个指定url上,将log信息传输到web服务器上

var _createWebhookTransport = function (args, logLvl) {

  var host = null,

      port = null;

 

  if (args.webhook.match(':')) {

    var hostAndPort = args.webhook.split(':');

    host = hostAndPort[0];

    port = parseInt(hostAndPort[1], 10);

  }

 

  var transport = new (winston.transports.Webhook)({

    name: "webhook"

    , host: host || '127.0.0.1'

    , port: port || 9003

    , path: '/'

    , handleExceptions: true

    , exitOnError: false

    , json: false

    , level: logLvl

  });

  applyStripColorPatch(transport);

  return transport;

};