Nginx ~ 日志平台
如何设置日志的格式?如何添加全局性的日志?如何在不同的 API 里面添加相关日志?或者在不同的业务逻辑里面添加日志?如何对日志进行管理(比如:时效性等)
参考答案
日志分层
一个成熟系统的日志分为三类:
| 层级 | 位置 | 作用 |
|---|---|---|
| ① 接入层日志 | Nginx | 谁访问了什么 |
| ② 应用层日志 | API / 业务代码 | 系统内部发生了什么 |
| ③ 业务日志 | 关键业务行为 | 用户干了什么 |
如何设置日志格式(标准化)
- Nginx 日志格式(JSON 结构化日志)
nginx
log_format json_log '{'
'"time":"$time_iso8601",'
'"remote_ip":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$uri",'
'"args":"$args",'
'"status":$status,'
'"request_time":$request_time,'
'"body_bytes":$body_bytes_sent,'
'"referer":"$http_referer",'
'"ua":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.json json_log;
- 应用日志格式(API / 业务代码)
推荐统一格式:
json
{
"time": "2026-01-26T11:30:00",
"level": "INFO",
"trace_id": "abc123",
"service": "order-service",
"api": "/api/order/create",
"user_id": 1001,
"msg": "create order success",
"cost": 120
}必须包含字段(强烈建议)
| 字段 | 作用 |
|---|---|
| time | 时间 |
| level | 日志级别 |
| trace_id | 全链路追踪 |
| service | 服务名 |
| api | 接口 |
| msg | 描述 |
| cost | 耗时 |
| user_id | 业务定位 |
如何设置全局日志(统一入口)
Nginx 全局日志
在 nginx.conf 的 http 块:
nginx
http {
log_format json_log ...;
access_log /var/log/nginx/access.json json_log;
}这样:所有 server / location 自动继承日志格式
应用全局日志(后端框架)
思路:中间件 / 拦截器
例如(伪代码):
go
func LoggerMiddleware(next Handler) Handler {
return func(req) {
start := time.Now()
next(req)
log.Info({
api: req.URL,
method: req.Method,
cost: time.Since(start),
ip: req.IP
})
}
}这样:每个 API 自动打日志,不用每个接口重复写。
日志的原则:
日志不是越多越好 是在“关键路径”打点
如何对日志进行管理(时效性 / 空间 / 合规)
- 日志分类型存储
| 类型 | 保存时间 |
|---|---|
| access_log | 7~30 天 |
| error_log | 30~90 天 |
| audit_log | 180 天 |
| 业务日志 | 30 天 |
- logrotate 管理磁盘
bash
/var/log/nginx/*.log {
daily
rotate 14
compress
missingok
notifempty
}- 生命周期管理(日志平台)
Elasticsearch ILM:
- 7 天热数据
- 30 天冷数据
- 60 天删除
不要记录:
- 密码
- 身份证
- 银行卡
- token
可脱敏:
text
phone=138****8888一、为什么要做日志平台?
1.1 没有日志平台会发生什么?
- 服务慢了:不知道慢在哪
- 服务挂了:不知道谁请求搞挂的
- 被攻击:不知道攻击源是谁
- 出现 Bug:无法复现问题
日志 = 系统的黑匣子(飞机出事靠它)
二、Nginx 日志基础
2.1 Nginx 默认日志
nginx
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;包含内容:
- IP
- 时间
- URL
- 状态码
- User-Agent
但:不适合分析(字段不结构化)
三、第一步:日志结构化(核心)
3.1 使用 JSON 日志格式
nginx
log_format json_log '{'
'"time":"$time_iso8601",'
'"remote_ip":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"method":"$request_method",'
'"uri":"$uri",'
'"args":"$args",'
'"bytes":$body_bytes_sent,'
'"referer":"$http_referer",'
'"ua":"$http_user_agent",'
'"request_time":$request_time'
'}';
access_log /var/log/nginx/access.json json_log;优点:
- 可被程序直接解析
- 方便进入日志平台
- 适合大数据分析
四、日志平台总体架构
4.1 标准企业架构(ELK)
Nginx
↓
Filebeat / Fluentd
↓
Elasticsearch / Loki
↓
Kibana / Grafana组件说明:
| 组件 | 作用 |
|---|---|
| Filebeat | 采集日志 |
| Elasticsearch | 存储与搜索 |
| Kibana | 可视化分析 |
| Grafana | 监控 + 告警 |
五、日志采集(Filebeat)
5.1 Filebeat 配置示例
yaml
filebeat.inputs:
- type: log
paths:
- /var/log/nginx/access.json
json.keys_under_root: true
json.add_error_key: true
output.elasticsearch:
hosts: ["http://localhost:9200"]作用:
- 监听日志文件变化
- 自动推送到 ES
六、日志存储设计(Elasticsearch)
6.1 索引设计
nginx-access-2026.01.26字段设计:
| 字段 | 说明 |
|---|---|
| remote_ip | 客户 IP |
| uri | 访问接口 |
| status | 状态码 |
| request_time | 响应时间 |
| ua | 浏览器 |
6.2 生命周期管理(ILM)
- 热数据:7 天
- 冷数据:30 天
- 自动删除:60 天
七、日志分析能力(Kibana)
7.1 核心分析维度
1. QPS
count by uri2. 错误率
status >= 5003. 慢请求
request_time > 24. 攻击识别
same ip + high frequency八、日志告警体系
8.1 告警规则示例
| 条件 | 告警 |
|---|---|
| 5xx 超过 5% | 发钉钉/企业微信 |
| 请求量突增 200% | 疑似攻击 |
| 响应时间 > 3s | 性能告警 |
Grafana Alert 示例:
IF avg(request_time) > 3s FOR 1m
THEN alert九、安全审计日志
9.1 记录关键行为
- 登录接口
- 支付接口
- 管理后台接口
9.2 追踪用户行为
IP + user_id + uri十、日志切割与磁盘保护
10.1 logrotate
bash
/var/log/nginx/*.log {
daily
rotate 14
compress
missingok
notifempty
}防止磁盘爆满导致服务宕机
十一、日志平台核心价值总结
| 价值 | 说明 |
|---|---|
| 稳定性 | 发现问题 |
| 安全 | 防攻击 |
| 性能 | 找瓶颈 |
| 合规 | 审计 |
| 决策 | 数据支持 |
日志平台 = 运维的眼睛 + 耳朵 + 大脑
