关于node.js:关于-Nodejs-应用里使用-winston-进行日志记录的最佳实践

5次阅读

共计 5310 个字符,预计需要花费 14 分钟才能阅读完成。

Logging with Winston and Node.js

假如您有一个在生产环境中运行的应用程序,每天有数百万用户赚取数千美元。应用程序可能存在谬误的起因有多种,作为开发人员,您须要找出起因并修复它。没有人违心应用有问题的应用程序,修复谬误会破费工夫和金钱。

你怎么能解决这个问题?兴许通过回到代码并查看每一行代码是否按预期运行。这对于小型应用程序来说更容易,但即便如此,尝试触发与用户雷同类型的谬误也可能很艰难。设想一下,这在大型应用程序中会有多难。

假如有一个实例,应用程序收集一些用户的信息并将它们保留到数据库中。

如果应用程序失败,服务器将向最终用户返回零碎谬误。最好能捕捉这些实例并解决这些谬误。在这种状况下,您如何晓得用户 a 或用户 b 遇到了单个零碎谬误?这些谬误可能由代码中的谬误、损坏的文件、谬误的逻辑或数据类型不匹配触发。

如果你须要防止这种挫折,你就无奈防止日志记录。日志是程序员首先要查找的中央,用于跟踪谬误和事件流,尤其是来自服务器的事件。日志会告诉您当利用程序运行并与用户交互时会产生什么。日志记录的一个很好的用例是,例如,如果您的零碎中有一个谬误,并且您想理解导致其产生的步骤。

日志记录是将应用程序流动生成的信息记录到日志文件中的过程。保留在日志文件中的音讯称为日志。日志是记录在日志文件中的单个实例。

在 Node.js 中构建应用程序日志至关重要。在本地运行应用程序时,能够将其挂接到调试器上,十分棒,能够在运行应用程序时发现问题。在开发过程中,您通常会应用 console.log 来获取应用程序日志。

然而当一个应用程序投入生产并且用户开始与之交互时,你就不能再应用 console.log 了。如果呈现问题并且应用程序解体,则无奈应用控制台进行查看。如果你有一个简洁、洁净和高质量的日志中间件,比方 Winston,那会很有帮忙。

Winston 解决您的应用程序流动并将有用的信息生成到日志文件或数据库中。之后,您能够查看应用程序生成的所有流动。

本指南将在 Winston 的上下文中解释日志记录。

理解生产应用程序是否呈现问题的惟一办法是创立日志。记录从新创立并为您保留该问题。如果呈现问题或呈现问题,日志会告诉您。

理解零碎的行为形式。日志记录将生成无关零碎如何与用户交互以及进出零碎的信息。

跟踪您的系统活动。日志能够显示实例产生的工夫以及触发日志的起因。

通常,日志记录的临界值是:

  • 谬误跟踪
  • 调试
  • 利用性能

抉择 winston 的收益

Winston 是最好的日志中间件之一,每周下载量约为 4,000,000 次。以下属性使 Winston 成为整体通用的日志记录中间件。

  • 它应用简略且可配置。
  • 日志级别(优先级)。Winston 提供日志记录级别。它们示意日志优先级;这使您可能从须要较少关注的日志中整顿出要害日志。例如:{谬误:0,正告:1,信息:2,具体:3,调试:4,傻:5}。在这种状况下,谬误日志的优先级高于具体日志。
  • 记录通道(传输)。一个好的记录器有不同的形式来抉择你的日志输入目的地。应用 Winston,您能够以不同形式发送和保留日志,例如文件、数据库、电子邮件和控制台。
  • 日志格局。Winston 为您提供了多种日志格局。例如,在将日志保留到 Mongo 数据库时,日志格局须要为 JSON 格局。
  • 日志剖析。Winston 可帮忙您剖析代码块并测量胜利执行代码所需的工夫。

Winston transporters

Winston 的个性之一是它反对各种传输,例如文件传输。这会将生成的日志音讯保留到日志文件中。该文件是在您的零碎中指定的。如果应用程序创立了它的第一个日志实例,该文件将主动生成。之后,任何日志都将保留到创立的文件中。

为此,记录器配置对象须要指向一个文件(文件传输器)。只需将新 winston.transports.File 中的传输配置对象 .transports.Console() 替换为 .transports.File() 即可,如下所示。

transports.File({filename: 'logs/example.log'})

这指定生成的任何日志都将保留在日志文件夹下的 example.log 文件中。

传输配置将是:

// Logger configuration
const logConfiguration = {
    'transports': [
        new winston.transports.File({filename: 'logs/example.log'})
    ]
};

log 文件的内容:

Winston 容许您实现多个日志传输,即能够将日志记录到文件、控制台或数据库中。

上面的 Logger 配置记录到控制台和文件。咱们将向日志配置对象增加一个传输数组。在本指南的前面,咱们将向您展现如何将日志实例记录到数据库中。

const logConfiguration = {
    transports: [
        new winston.transports.Console({level: 'warn'}),
        new winston.transports.File({
            level: 'error',
            // Create the log directory if it does not exist
            filename: 'logs/example.log'
        })
    ]
};

const logger = winston.createLogger(logConfiguration);

// Log some messages
logger.error("Hello, Winston logger, the first error!");
logger.warn("Hello, Winston logger, the first warning!");
logger.warn("Hello, Winston logger, the second warning!");
logger.error("Hello, Winston logger, the second error!");
logger.info("Hello, Winston logger, some info!");
logger.debug("Hello, Winston logger, a debug!");

这规定:

  • 日志将显示在控制台输入中。
  • 只有属于谬误级别的日志才会记录在 example.log 文件中。

应用 Winston,您能够指定保留日志的默认格局。

例如,假如咱们想以 JSON 格局登录,咱们能够应用 Winston.format 指定,并且日志实例将以 JSON 格局保留。

format: winston.format()

该格局采纳其余日志表单属性,例如

  • ms() – 自记录上次日志以来的工夫(以毫秒为单位)。
  • label() – 向记录的音讯增加标签。
  • timestamp() – 收到日志音讯的工夫戳。
  • splat() – 提供字符串插值。

要将其利用到您的日志中,您须要应用 format.combine,如下例所示。

const logConfiguration = {
    transports: [new winston.transports.Console()
    ],
    format: winston.format.combine(
        winston.format.label({label: `Label🏷️`}),
        winston.format.timestamp({format: 'MMM-DD-YYYY HH:mm:ss'}),
        winston.format.printf(info => `${info.level}: ${info.label}: ${[info.timestamp]}: ${info.message}`),
    )
};

const logger = winston.createLogger(logConfiguration);

// Log a message
logger.info("Hello, Winston logger, some info!");

输入:

info: Label🏷️: Nov-18-2020 08:10:44: Hello, Winston logger, some info!

Configuring Winston with a server

让咱们创立一个简略的 Express 服务器,咱们能够应用 Winston 进行一些日志记录。这将是一个小我的项目,能够让您应用 Winston 记录来自服务器申请和响应的日志。

持续应用 npm install express 装置 Express 库。

这是咱们小我的项目的构造:

  • Logs – 将保留由 Winston 文件传输生成的日志文件。
  • app.js – 将成为咱们的服务器应用程序。
  • Utils – 将保留 Winston logger.js,咱们将在其中增加 Winston 传输和格局等配置。

Logger.js:

const {createLogger, format, transports} = require('winston');

module.exports = createLogger({
transports:
    new transports.File({
    filename: 'logs/server.log',
    format:format.combine(format.timestamp({format: 'MMM-DD-YYYY HH:mm:ss'}),
        format.align(),
        format.printf(info => `${info.level}: ${[info.timestamp]}: ${info.message}`),
    )}),
});

app.js:

const express = require('express');

// Require logger.js
const logger = require('./utils/logger');
const app = express();
const port = 3000;
const host = "localhost";

// Dummy Express GET call
app.get('/',(req,res) => {res.send("Hello World!");
    logger.info("Server Sent A Hello World!");
})

// Introduce error by using undefined variable 'y'
app.get('/calc',(req,res) => {
    const x = y + 10;
    res.send(x.toString());
})

// Capture 500 errors
app.use((err,req,res,next) => {res.status(500).send('Could not perform the calculation!');
   logger.error(`${err.status || 500} - ${res.statusMessage} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
})

// Capture 404 erors
app.use((req,res,next) => {res.status(404).send("PAGE NOT FOUND");
    logger.error(`400 || ${res.statusMessage} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
})
// Run the server
app.listen(port, () => {console.log("Server started...");
    logger.info(`Server started and running on http://${host}:${port}`)
})

每次服务器启动时,Winston 都会将日志记录到 server.log 文件中。

服务器运行时,拜访以下页面会在每次调用链接时创立日志。

http://localhost:3000/ – 服务器将发送一条 hello world 音讯。咱们心愿 Winston 捕捉它并将其记录在咱们的日志文件中。

http://localhost:3000/calc – 咱们试图将变量 y 增加到变量 x。在这种状况下,未定义变量 y。这将产生一个谬误,咱们心愿 Winston 为咱们捕捉这个实例。

http://localhost:3000/hello – 咱们创立的服务器没有这样的 URL。咱们心愿 Winston 在指向咱们 IP 地址的链接被拜访但无奈找到时告诉咱们;那是 404 谬误。

output:

info: Nov-12-2020 10:07:59: Server started and running on http://localhost:3000
info: Nov-12-2020 10:08:02: Server Sent A Hello World!
error: Nov-12-2020 10:08:05: 500 – Internal Server Error – y is not defined – /calc – GET – ::1
error: Nov-12-2020 10:08:10: 400 || Not Found – /hello – GET – ::1

更多 Jerry 的原创文章,尽在:” 汪子熙 ”:

正文完
 0