从头开始创建一个自动产生文档/类型安全的现代API(3) 日志搭建 - Bearalise

搭建日志平台Pino

Pino 是一个非常快速且简洁的 Node.js 日志库,其设计宗旨在于提供最小的开销以及高性能的日志记录功能。下面我们来在项目中搭建它。
安装:

1
bun add hono-pino pino

代码实现:
添加文件:middlewares/pino-logger.ts:

1
2
3
4
5
import { pinoLogger } from 'hono-pino';

export function pnLogger() {
return pinoLogger();
}

运行程序:bun run dev
访问localhost,返回 “Hello Hono”,同时控制台显示:
apidemo4

安装pino-pretty

可以看到,log的显示格式不大友好,不方便debug,可以安装pino-pretty:

1
bun add pino-pretty

代码实现,修改文件pino-logger.ts :

1
2
3
4
5
6
7
8
9
import { pinoLogger } from 'hono-pino';
import { PinoPretty } from 'pino-pretty';
import { pino } from 'pino';

export function pnLogger() {
return pinoLogger({
pino: pino(PinoPretty()),
});
}

运行程序:bun run dev
访问localhost,返回 “Hello Hono”,同时控制台显示,可以看出格式已经更新:
apidemo5

定制请求ID

当你查看这些日志时,如果出现问题,你希望请求 ID 是唯一的。你可以看到,默认情况下,这些 ID 只是从 1 开始递增的。所以,如果你在一个无服务器环境中,或者服务器上下线,这些请求 ID 会重置。我们希望这些 ID 是全局唯一的,为此,我们实际上可以传递一些选项给日志记录器。这里有一些 HTTP 选项,其中有一个请求 ID 选项,我们可以传递一个自定义函数。我会在这里使用 crypto API,crypto 是内置于 Web 标准中的,然后我们可以使用 randomUUID。
修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
import { pinoLogger } from 'hono-pino';
import { PinoPretty } from 'pino-pretty';
import { pino } from 'pino';

export function pnLogger() {
return pinoLogger({
pino: pino(PinoPretty()),
http: {
reqId: ()=> crypto.randomUUID(),
}
});
}

修改后返回:

1
reqId: "a1227e0e-c18b-4275-b05f-24f7e3d5be2e"

主动记录日志

可以看到使用middleware,系统已经可以捕捉系统调用的日志,如果想主动记录日志,可以用以下方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
interface AppBinding {
Variables: {
logger: PinoLogger;
}
}
const app = new OpenAPIHono<AppBinding>().basePath('/api');

...
app.get("/error", (c) => {
c.status(422);
//add a custom error message to logger
c.var.logger.info("Wow! Log here");
throw new Error("This is an error");
});

效果是,会在Console里显示:

1
[22:42:53.749] INFO (11157): Wow! Log here

根据环境确定输出日志内容和格式

有时我们希望能通过环境参数,控制日志的输出格式,我们可以这样做:
修改middlewares/pino-logger.ts:

1
2
3
4
5
6
7
8
9
10
11
...
export function pnLogger() {
return pinoLogger({
pino: pino({
level: process.env.LOG_LEVEL || "info"
}, process.env.NODE_ENV === "production" ? undefined:PinoPretty()),
http: {
reqId: ()=> crypto.randomUUID(),
}
});
};

这样我们通过判断 LOG_LEVEL 和 NODE_ENV 的值,就可以确定输出日志的等级和格式。

安装dotenv,支持从.env中读取参数

安装dotenv包

1
bun add dotenv dotenv-expand

修改middlewares/pino-logger.ts:

1
2
3
4
5
6
...
import { expand } from 'dotenv-expand';
import { config } from 'dotenv';

expand(config());
...

作者:Bearalise
出处:从头开始创建一个自动产生文档/类型安全的现代API(3) 日志搭建 - Bearalise
版权:本文版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明,必须在文章中给出原文链接。

请我喝杯咖啡吧~

支付宝
微信