# 内建日志系统（Pino）

URL: https://caijiao.org/fastify/performance/logging
Source: docs/fastify/performance/logging.md
Description: 介绍 Fastify 的内建日志系统 Pino，展示其高性能、低开销的特点，并指导如何在 Fastify 中使用和配置 Pino 进行日志记录。

[Fastify](/fastify/) 默认集成了 Pino，一个高性能的 JSON 格式日志库。Pino 被设计为具有极低的性能开销，特别适用于高并发的应用场景，能够快速记录和输出日志数据。其高效的性能和灵活的日志配置，使得 Pino 成为 Fastify 的理想选择。

## 1. Pino 的优势

Pino 的设计目标是提供一个快速、低开销且功能强大的日志解决方案。其优势包括：

- **高性能**：Pino 在设计上极其注重性能，它能够以非常高的速度输出日志，并且在高并发场景下也能保持良好的性能。
- **JSON 格式**：Pino 使用 JSON 格式输出日志，这使得日志数据易于结构化处理，便于后期分析、存储和处理。
- **异步记录**：Pino 支持异步日志记录，避免了日志记录对应用性能的阻塞影响。
- **灵活配置**：Pino 提供丰富的配置选项，可以灵活定制日志级别、输出格式、日志传输等。

## 2. Fastify 中的 Pino 配置

Fastify 默认启用了 Pino 作为日志系统，可以通过 [Fastify](/fastify/) 实例的 `logger` 选项进行配置。

### 默认配置

Fastify 会在启动时自动创建一个默认的 Pino 实例，记录如下信息：

- 请求的基本信息（如方法、路径、响应状态码）
- 请求处理的时间（响应时间）
- 错误信息（如有）

例如，Fastify 启动后会自动输出请求日志：

```txt
{"level":30,"time":1630367982965,"pid":12345,"hostname":"localhost","reqId":1,"req":{"method":"GET","url":"/","headers":{"accept":"application/json"}},"res":{"statusCode":200},"responseTime":4}
```

### 自定义配置

可以通过 `logger` 配置项来定制 Pino 的行为。例如，改变日志级别、格式、输出位置等：

```js
const fastify = require('fastify')({
  logger: {
    level: 'info', // 设置日志级别为 'info'
    prettyPrint: true, // 美化输出格式
    redact: ['req.headers.authorization'], // 对敏感数据进行脱敏处理
    base: { pid: false }, // 关闭 pid 信息
  }
})

fastify.get('/', async (request, reply) => {
  request.log.info('Handling / request')
  return { hello: 'world' }
})

fastify.listen(3000, err => {
  if (err) {
    fastify.log.error(err)
    process.exit(1)
  }
  fastify.log.info('Server started')
})
```

在上面的示例中，`logger` 配置了日志级别、格式化输出、脱敏处理等选项，确保日志符合特定需求。

## 3. Pino 日志级别

Pino 支持以下几种日志级别，用于控制日志输出的详细程度：

- **fatal**：表示非常严重的错误，导致应用无法继续运行。
- **error**：表示常规的错误。
- **warn**：表示警告信息，可能预示着潜在的问题。
- **info**：表示常规的操作信息，通常用于跟踪程序的执行流程。
- **debug**：用于调试信息，包含详细的诊断数据。
- **trace**：最详细的日志级别，用于详细追踪每个操作。

可以通过 `logger.level` 配置来设置日志级别，默认级别为 `info`。

## 4. 使用日志对象

Fastify 的请求和响应对象都可以通过 `.log` 属性访问到日志实例。这意味着你可以在路由处理函数中方便地记录日志信息：

```js
fastify.get('/', async (request, reply) => {
  request.log.info('Handling / request')
  reply.log.debug('Response will be sent soon')
  return { hello: 'world' }
})
```

在这个示例中，我们使用 `request.log` 和 `reply.log` 来记录信息和调试日志。

## 5. Pino 日志格式化

Pino 的输出默认是 JSON 格式，但可以通过 `prettyPrint` 配置项使其输出为易读的格式。`prettyPrint` 配置会在开发环境中启用更加友好的格式化输出，适合开发人员查看。

### 开发环境中的格式化输出

```js
const fastify = require('fastify')({
  logger: {
    level: 'info',
    prettyPrint: { colorize: true } // 启用彩色输出
  }
})
```

这将启用彩色的、易读的日志输出，适合开发时使用。

### 生产环境中的日志

在生产环境中，通常希望日志以 JSON 格式输出，以便进行集中式日志管理和分析。可以通过禁用 `prettyPrint` 配置，并确保日志输出到文件或日志聚合服务。

## 6. 集成日志存储与聚合

在大规模生产环境中，日志通常会被集中存储并进行分析。Pino 可以轻松集成到日志聚合服务（如 Elasticsearch、Loggly、Datadog 等）中。通过配置 `pino-http` 插件，Fastify 可以将日志发送到这些服务，进行实时监控和日志分析。

## 总结

Fastify 的内建日志系统 Pino 通过其高性能、低开销的设计，为开发者提供了一个强大且灵活的日志记录工具。无论是在开发环境中进行调试，还是在生产环境中进行日志存储和分析，Pino 都能满足高效、可定制的日志需求。
