今天给大家带来的主题是 Node.js 生态的日志记录框架,即 Pino。话不多说,直接开始!
Pino 是一个强大的 Node.js 日志记录框架,拥有非常快的速度和非常全面的功能,同时因为性能优势它已经集成到了开源 Fastify Web 服务器中。 Pino 的多功能性还扩展到它易于与其他 Node.js Web 框架集成,使其成为可靠、灵活日志方案的首选。
Pino 包括日志框架中预期的所有标准功能,例如:可自定义的日志级别、格式化选项和多个日志传输选项。 它的灵活性是其突出的特点之一,因为它可以轻松扩展以满足特定要求,从而使其成为广泛应用的首选。
当选择具体的日志方案时,Node.js 生态有很多不错的可选项。Pino 是一个历史悠久且非常流行的日志记录工具,在 Github 上拥有超过 11.5K star,NPM 周平均下载量达到了惊人的 3601k。
Pino 提供了几个关键特性,使其非常适合在 Node.js 应用程序中使用:
要使用 Pino 也是非常简单,只需要首先安装相应的包,然后通过下面示例代码集成:
const logger = require('pino')();
logger.info('hello world');
const child = logger.child({ a: 'property' });
child.info('hello child!');
此时输出的日志格式如下:
{"level":30,"time":1531171074631,"msg":"hello world","pid":657,"hostname":"Davids-MBP-3.fritz.box"}
{"level":30,"time":1531171082399,"msg":"hello child!","pid":657,"hostname":"Davids-MBP-3.fritz.box","a":"property"}
由于 HTTP 日志记录是 Pino 的主要用例,因此 Pino 对 Node.js Web 框架生态系统具有一流的支持,比如:Fastify、Express、Hapi、Restify、Koa 等等
Fastify 是一个高度专注于以最少的开销和强大的插件架构提供最佳开发体验的 Web 框架。 它的灵感来自 Hapi 和 Express,据目前所知,它是目前 Node.js 生态中最快的 Web 框架之一。
Fastify web 框架默认集成了 Pino ,只需将 Fastify 的 logger 选项设置为 true 并使用 request.log 或 reply.log 来记录与每个请求对应的日志消息:
const fastify = require('fastify')({
logger: true,
});
// logger选项也可以设置为一个对象,该对象将作为 pino 选项对象直接传递。
fastify.get('/', async (request, reply) => {
request.log.info('something');
return { hello: 'world' };
});
fastify.listen({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
Express 是用于 Node.js 的快速、极简主义的 Web 框架,目前在 NPM 周平均下载量达到了惊人的 27545k。Express 的典型特征包括:
Pino 与 Express 的集成也非常简单,比如下面的示例:
const app = require('express')();
const pino = require('pino-http')();
app.use(pino);
app.get('/', function (req, res) {
req.log.info('something');
res.send('hello world');
});
app.listen(3000);
Hapi 是开发人员信任的简单、安全的框架 以最小的开销和完整的开箱即用功能构建功能强大、可扩展的应用程序,在 NPM 上周平均下载量达到了 512k。
Pino 与 Hapi 的集成也非常简单,比如下面的示例:
'use strict';
require('make-promises-safe');
const Hapi = require('@hapi/hapi');
const Pino = require('hapi-pino');
async function start() {
// 创建一个有host和port的服务器
const server = Hapi.server({
host: 'localhost',
port: 3000,
});
// 添加路由
server.route({
method: 'GET',
path: '/',
handler: async function (request, h) {
//request.log 是 HAPI 的标准日志记录方式
request.log(['a', 'b'], 'Request into hello world');
//也可以使用 pino 实例,这样会更快
request.logger.info('In handler %s', request.path);
return 'hello world';
},
});
awAIt server.register(Pino);
//也作为修饰的 API
server.logger.info('another way for accessing it');
//并通过 Hapi 标准日志系统
server.log(['subsystem'], 'third way for accessing it');
await server.start();
return server;
}
start().catch((err) => {
console.log(err);
process.exit(1);
});
restify 是一个框架,利用 connect 风格的中间件来构建 REST API。Pino 与 Restify 的集成也非常简单,比如下面的示例:
const server = require('restify').createServer({ name: 'server' });
const pino = require('restify-pino-logger')();
server.use(pino);
server.get('/', function (req, res) {
req.log.info('something');
res.send('hello world');
});
server.listen(3000);
Koa 是用于 node.js 的富有表现力的 HTTP 中间件框架,使 Web 应用程序和 API 编写起来更轻松。 Koa 的中间件以类似堆栈的方式流动,允许开发者在下游执行操作然后在上游过滤和操作响应。Koa 没有打包任何中间件。
Pino 与 Koa 的集成也非常简单,比如下面的示例:
const Koa = require('koa');
const app = new Koa();
const pino = require('koa-pino-logger')();
app.use(pino);
app.use((ctx) => {
ctx.log.info('something else');
ctx.body = 'hello world';
});
app.listen(3000);
Pino 与 http 的集成也非常简单,比如下面的示例:
const http = require('http');
const server = http.createServer(handle);
const logger = require('pino-http')();
function handle(req, res) {
logger(req, res);
req.log.info('something else');
res.end('hello world');
}
Nest 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。 它基于现代 JAVAScript,使用 TypeScript 构建(保留与纯 JavaScript 的兼容性)并结合了 OOP(面向对象编程)、FP(函数式编程)和 FRP(函数式响应式编程)的元素。
本质上,Nest 是基于 Express,但也提供了与广泛的其他库的兼容性,例如 Fastify,允许轻松使用无数可用的第三方插件。Pino 与 Nest 的集成也非常简单,比如下面的示例:
import { NestFactory } from '@nestjs/core'
import { Controller, Get, Module } from '@nestjs/common'
import { LoggerModule, Logger } from 'nestjs-pino'
@Controller()
export class AppController {
constructor(private readonly logger: Logger) {}
@Get()
getHello() {
this.logger.log('something')
return `Hello world`
}
}
@Module({
controllers: [AppController],
imports: [LoggerModule.forRoot()]
})
class MyModule {}
async function bootstrap() {
const app = await NestFactory.create(MyModule)
await app.listen(3000)
}
bootstrap()
H3 是为高性能和可移植性构建的最小 http 框架,NPM 上周平均下载量达到了 267K,具有以下典型特性:
Pino 与 H3 的集成也非常简单,比如下面的示例:
import { createServer } from 'http';
import { createApp } from 'h3';
import pino from 'pino-http';
const app = createApp();
app.use(pino());
app.use('/', (req) => {
req.log.info('something');
return 'hello world';
});
createServer(app).listen(process.env.PORT || 3000);
本文主要和大家介绍下 Node.js 生态的日志记录框架,即 Pino。相信通过本文的阅读,大家对 Pino 都会有一个初步的了解。
因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!
https://www.npmjs.com/package/h3
https://github.com/pinojs/pino
https://github.com/nestjs/nest
https://www.npmjs.com/package/fastify
https://www.npmjs.com/package/express
https://www.npmjs.com/package/@hapi/hapi
https://github.com/restify/node-restify
https://blog.logrocket.com/comparing-node-js-logging-tools/
https://www.npmjs.com/package/pino
https://github.com/pinojs/pino/blob/master/docs/benchmarks.md
封面图来自:
https://css-tricks.com/how-to-implement-logging-in-a-node-js-application-with-pino-logger/