告别笨重的 ELK,拥抱轻量级 PLG:NestJS 日志监控实战指南
💡 前言:
在微服务和容器化大行其道的今天,日志监控是必不可少的一环。传统的 ELK (Elasticsearch, Logstash, Kibana) 方案虽然强大,但对于中小型项目来说,资源占用过高(尤其是 ES)。
本文将带你实战一套轻量级的日志监控方案:**Promtail + Loki + Grafana (PLG)**,并结合 NestJS 实现结构化日志的采集与可视化。
🚀 为什么选择 PLG?
- Loki: 被称为 “云原生的 Prometheus”,它不索引日志全文,只索引 Label,因此资源占用极低,写入速度极快。
- Promtail: 专门为 Loki 设计的日志采集器,配置简单,支持多种抓取方式。
- Grafana: 颜值即正义,统一的监控大屏,不仅能看指标(Metrics),还能看日志(Logs)。
目标效果:
通过 Nginx 反向代理,访问 https://your-domain.com/log/ 直接查看实时日志仪表盘,且日志包含完整的 Req 和 Res 结构化数据。
🛠️ 第一步:NestJS 结构化日志改造
要想日志查得爽,日志格式必须标准。我们使用 winston 来生成 JSON 格式的日志。
1. 安装依赖
1 | pnpm add nest-winston winston |
2. 配置 Winston (app.module.ts)
重点是使用 winston.format.json(),这样 Promtail 才能轻松解析。
1 | // src/app.module.ts |
3. 全局日志中间件
手写一个 Middleware,把请求参数、响应体、耗时都记录下来。
1 | // src/common/middleware/logging.middleware.ts |
🐳 第二步:Docker Compose 编排 PLG
在 docker-compose.prod.yml 中一键拉起所有服务。
1 | services: |
⚙️ 第三步:Promtail 采集配置
Promtail 的核心在于 pipeline_stages,它决定了如何解析你的日志。
1 | # plg/promtail/config.yaml |
🔌 第四步:Nginx 反向代理与 Grafana 子路径
为了安全和方便,我们通常把 Grafana 藏在 Nginx 后面,通过 /log/ 访问。
Nginx 配置:
1 | location /log/ { |
踩坑指南:
- Grafana 白屏/404: 必须配置
GF_SERVER_SERVE_FROM_SUB_PATH=true。 - Proxy Pass 斜杠: Nginx 中
proxy_pass http://localhost:3001;后面尽量别带/,让 Grafana 自己处理路径前缀。
✨ 第五步:自动化 Dashboard (Provisioning)
不要每次部署都手动配数据源!使用 Grafana Provisioning 功能。
在 plg/grafana/provisioning/datasources/datasource.yml 中定义 Loki 数据源,容器启动时自动加载。这样即使容器销毁,配置也不会丢。
🎉 最终效果
部署完成后,打开 https://your-domain.com/log/:
- 实时流:
Live模式下看着日志一条条刷出来,极度舒适。 - 精准检索: 输入
{app="nest-prisma-app", level="error"}瞬间定位所有错误。 - 上下文详情: 点击日志展开,直接看到
req.body和res.body,再也不用猜用户传了什么参数!
总结
这套 PLG 方案占用资源极少(几十 MB 内存),但功能却非常强大。配合 NestJS 的结构化日志,是中小型项目监控的不二之选。