log4js

307 阅读9分钟

log4js是一个为Node.js环境设计的日志记录工具,它提供了灵活的日志管理功能。以下是对log4js的用法的总结:

基本使用

  1. 安装 npm install log4js

  2. 引入log4js

    var log4js = require('log4js');
    
  3. 配置log4js: log4js的配置可以通过JSON文件或直接在代码中配置。配置信息包括定义appenders(日志输出目的地)、categories(日志分类)以及日志级别等。

    log4js.configure({
      appenders: {
        out: { type: 'stdout' },
        app: { type: 'file', filename: 'application.log' }
      },
      categories: {
        default: { appenders: ['out', 'app'], level: 'debug' }
      }
    });
    
  4. 获取Logger对象: 通过log4js.getLogger([category])获取Logger对象,如果未指定category,则使用默认分类。

    var logger = log4js.getLogger();
    
  5. 记录日志: 使用Logger对象记录不同级别的日志,如debug、info、warn、error等。

    logger.debug('这是一个debug级别的日志');
    logger.info('这是一个info级别的日志');
    

几个概念

Level

在log4js中,日志级别(Level)是用于定义日志事件(LogEvent)重要性或优先级的机制。日志级别决定了日志事件是否会被特定的日志输出目的地(Appender)处理。以下是对日志级别的详细说明:

日志级别的定义

日志级别是一个用于分类日志消息严重性的等级制标识。在log4js中,日志级别按照严重性递增的顺序排列如下:

  1. ALL - 用于开启所有日志级别。
  2. TRACE - 用于追踪程序的执行,用于最详细的调试信息。
  3. DEBUG - 用于提供调试信息。
  4. INFO - 用于常规信息输出,比如程序运行状态等。
  5. WARN - 用于警告信息,可能不会导致错误,但需要关注。
  6. ERROR - 用于错误信息,表示出现了问题。
  7. FATAL - 用于严重错误,通常会导致程序停止运行。
  8. MARK - 用于日志跟踪,可以标记特定的日志记录。
  9. OFF - 关闭所有日志记录。

日志级别的使用

在log4js的配置中,可以为每个日志分类(Category)指定一个日志级别。这个级别定义了该分类中将会被记录的最低重要性等级的日志。只有等于或高于这个级别的日志事件才会被处理和输出。

例如,如果一个分类的日志级别被设置为ERROR,那么只有ERRORFATALMARK级别的日志事件会被记录,而INFOWARNDEBUGTRACE级别的日志则会被忽略。

自定义日志级别

log4js允许用户定义自己的日志级别。在配置对象的levels属性中,可以添加或重新定义日志级别,包括设置它们的整数值和颜色。整数值用于确定日志级别的顺序。如果自定义的日志级别与默认级别同名,配置中的整数值将优先使用。

日志级别的配置

配置日志级别通常在log4js的配置阶段完成,可以是直接在代码中配置,也可以是通过一个JSON配置文件。配置对象中的levels属性是定义自定义日志级别的地方,而categories属性中的每个分类都可以指定一个日志级别。

示例配置

log4js.configure({
  levels: {
    cheese: {
      value: 1000,
      color: 'yellow'
    }
  },
  appenders: {
    cheeseAppender: {
      type: 'stdout',
      layout: {
        type: 'basic'
      }
    }
  },
  categories: {
    default: {
      appenders: ['cheeseAppender'],
      level: 'cheese'
    }
  }
});

在上面的示例中,我们定义了一个名为cheese的自定义日志级别,并为其指定了一个整数值和颜色。然后,我们创建了一个名为cheeseAppender的stdout类型的appender,并在默认分类中使用这个日志级别。

通过这种方式,log4js提供了一个灵活的日志级别系统,允许开发者根据需要调整日志记录的细节和重要性。

Categories

在log4js中,"Categories"(分类)是用于组织日志事件的一种方式。每个日志事件都可以被分配到一个特定的分类中,这样可以根据分类来控制日志的输出。以下是对Categories的详细说明:

Categories的定义和作用

  • 分类目的:Categories用于将日志事件分组。这可以基于模块(例如:'auth', 'payment', 'http')或任何其他逻辑来定义。
  • 日志路由:具有相同分类的日志事件将被发送到相同的Appenders(日志输出目的地)。
  • 层次结构支持:log4js支持Categories的层次结构,使用点(.)来分隔层级。例如,分类'myapp.submodule'的日志事件,如果'myapp.submodule'没有定义特定的日志级别或Appender,将使用'myapp'的日志级别和Appender。

Categories的配置

在log4js的配置中,至少要定义一个Category。Category的配置包括指定Appenders和日志级别。例如:

log4js.configure({
  appenders: {
    out: { type: "stdout" },
    app: { type: "file", filename: "application.log" },
  },
  categories: {
    default: { appenders: ["out"], level: "trace" },
    app: { appenders: ["app"], level: "trace" },
  },
});

在这个配置中,定义了两个Categories:'default'和'app'。'default' Category使用stdout Appender,并且设置为'trace'级别,这意味着所有未明确分类的日志事件都会使用这个Category的配置。'app' Category则将日志写入到文件'application.log'。

Categories的使用

在代码中,你可以通过log4js.getLogger('categoryName')来获取一个指定分类的Logger实例。例如:

const logger = log4js.getLogger();
logger.trace("This will use the default category and go to stdout");

const logToFile = log4js.getLogger("app");
logToFile.trace("This will go to a file");

在这个例子中,第一个Logger使用默认分类,第二个Logger则使用'app'。

Appenders

在log4js-node中,"Appender"是一个核心概念,它负责将日志事件序列化并输出到某种形式的媒介。Appender可以写入文件、发送电子邮件、通过网络发送数据等。所有的Appender都有一个type属性,这个属性决定了使用哪种Appender。以下是对Appender的详细说明:

核心Appenders

log4js-node包括了一系列内置的核心Appender,例如:

  • categoryFilter: 允许根据分类过滤日志事件。
  • console: 将日志输出到控制台。
  • dateFile: 每天创建一个新的文件来存储日志。
  • file: 将日志写入文件,并支持基于文件大小或日期的日志滚动。
  • fileSync: 同步写入文件。
  • logLevelFilter: 允许根据日志级别过滤日志事件。
  • multiFile: 允许将日志事件发送到多个文件。
  • multiprocess: 用于多进程环境中的日志记录。
  • noLogFilter: 不过滤任何日志事件。
  • recording: 记录日志事件但不立即输出。
  • stderr: 将日志输出到标准错误流。
  • stdout: 将日志输出到标准输出流。
  • tcp: 通过网络的TCP协议发送日志。
  • tcp-server: 作为TCP服务器接收日志事件。

自定义Appender

log4js-node允许加载核心Appender之外的自定义Appender。如果在配置中找不到匹配的Appender,则type配置值将用作require路径来加载Appender。例如,以下配置将尝试从cheese/appender模块加载Appender:

log4js.configure({
  appenders: { gouda: { type: "cheese/appender", flavour: "tasty" } },
  categories: { default: { appenders: ["gouda"], level: "debug" } },
});

高级配置

如果用户有自己的自定义Appender,或者在使用webpack等打包工具,可能会发现直接在配置中传递Appender模块比从node.js require路径加载更容易。例如:

const myAppenderModule = {
  configure: (config, layouts, findAppender, levels) => {
    /* ...your appender config... */
  },
};

log4js.configure({
  appenders: { custom: { type: myAppenderModule } },
  categories: { default: { appenders: ["custom"], level: "debug" } },
});

通过这种方式,log4js-node提供了极大的灵活性,允许开发者根据自己的需求定制日志记录的方式和目的地。

Layout

在log4js-node中,"Layout"是指用于格式化日志事件的函数,它们将日志事件转换为字符串形式以便于输出。Appenders 使用 Layouts 来确定日志的输出格式。以下是对Layout的详细说明:

内置Layouts

log4js-node提供了几种内置的Layouts,适用于不同的输出格式需求:

  1. Basic Layout (type: "basic"):

    • 这种Layout会输出时间戳、日志级别、分类和格式化的日志事件数据。

    示例输出:

    [2017-03-30 07:57:00.113] [ERROR] cheese - Cheese is too ripe!
    
  2. Coloured Layout (type: "coloured"type: "colored"):

    • 与Basic Layout类似,但时间戳、日志级别和分类会根据日志事件的级别着色(如果终端或文件支持)。
  3. Message Pass-Through Layout (type: "messagePassThrough"):

    • 这种Layout只格式化日志事件数据,不输出时间戳、级别或分类。通常用于使用特定格式序列化事件的Appenders(例如GELF)。

    示例输出:

    Cheese is too ripe! Cheese was: gouda
    
  4. Dummy Layout (type: "dummy"):

    • 这种Layout只输出日志事件数据的第一个值。它是为了logstashUDP Appender添加的,但在其他情况下可能用处不大。

    示例输出:

    Cheese is too ripe! Cheese was:
    
  5. Pattern Layout (type: "pattern"):

    • 这种Layout使用一个模式字符串来指定输出格式,模式字符串中可以包含任意字符,但以%开头的序列将被替换为从日志事件或其他环境值中获取的值。

    模式字符串可以包含如下占位符:

    • %r 时间,使用toLocaleTimeString格式
    • %p 日志级别
    • %c 日志分类
    • %h 主机名
    • %m 日志数据
    • %d 日期,格式化,默认为ISO8601
    • %% 字面量%
    • 等等...

    用户可以通过%[padding].[truncation][field]{[format]}格式定义输出,其中padding(填充)和truncation(截断)是可选的,format(格式)只适用于少数几个token(如日期)。

用户自定义Layouts

用户可以通过调用log4js.addLayout(type, fn)方法来添加自定义的Layouts,其中type是用户希望在Appender配置中使用的标签,fn是一个函数,它接受单个对象参数(包含布局实例的配置),并返回一个布局函数。布局函数接受一个日志事件参数并返回一个字符串(或者任何Appender能够处理的格式)。

示例:添加自定义JSON Layout

const log4js = require("log4js");

log4js.addLayout("json", function (config) {
  return function (logEvent) {
    return JSON.stringify(logEvent) + config.separator;
  };
});

log4js.configure({
  appenders: {
    out: { type: "stdout", layout: { type: "json", separator: "," } },
  },
  categories: {
    default: { appenders: ["out"], level: "info" },
  },
});

const logger = log4js.getLogger("json-test");
logger.info("this is just a test");
logger.error("of a custom appender");
logger.warn("that outputs json");
log4js.shutdown(() => {});

自定义的JSON Layout将输出如下格式的日志:

{"startTime":"2017-06-05T22:23:08.479Z","categoryName":"json-test","data":["this is just a test"],"level":{"level":20000,"levelStr":"INFO"},"context":{}}

通过使用Layouts,log4js-node允许用户根据自己的需求定制日志的输出格式,无论是简单的文本输出还是复杂的JSON格式,都能方便地实现。