4. 日志收集与集中管理(ELK Stack、Splunk等)
说实话,做故障排查最怕什么?
不是问题多难,而是日志在哪都不知道。我记得早期带团队时,每次线上出问题,大家就各自登录服务器,用 grep 在几十个 log 文件里翻。那效率,简直了。你想想看,几十台机器,每台翻一遍,等找到线索,用户都骂了好几轮了。
后来我下定决心,必须上集中日志管理。今天我们就聊聊这玩意儿到底怎么玩。
1. 日志统一收集,告别 "ssh 到每台机器" 的原始时代。
2. 建立索引,实现秒级搜索。
3. 可视化展示,趋势一目了然。
4. 告警联动,问题还没爆发就先发现。
4.1 主流方案:ELK vs Splunk
目前业界两大主流方案:ELK Stack(开源)和 Splunk(商业)。我个人偏爱 ELK,主要是灵活,但 Splunk 在某些场景确实省心。
我们先看核心对比:
| 维度 | ELK Stack | Splunk |
|---|---|---|
| 开源/商业 | 开源(Elasticsearch + Logstash + Kibana) | 商业软件 |
| 上手难度 | 中(组件多,需要调优) | 低(开箱即用,文档全) |
| 扩展性 | 极强,水平扩展是原生能力 | 较强,但受 license 限制 |
| 搜索语法 | 基于 Lucene 的 Query DSL | 类 SQL 的 SPL(搜索处理语言) |
| 运维成本 | 高(ES 集群调优是个坑) | 低(Splunk 帮你兜底) |
| 成本 | 软件免费,运维人力贵 | 软件许可费贵,运维轻松 |
怎么选?我的建议是:小团队、预算有限直接上 ELK。大企业、业务敏感度高,Splunk 更省心。我在上一家公司两种方案都用过,后面会细说。
4.2 ELK 实战:从零搭一套日志系统
我重点讲讲 ELK。这玩意儿拆开讲就三个组件:
- Logstash:负责采集、解析、过滤日志。支持各种输入源。
- Elasticsearch:负责存储和索引,提供 RESTful 查询接口。
- Kibana:负责展示,画图表、做大盘。
现在的趋势是:用 Filebeat 替代 Logstash 做轻量采集。Filebeat 是 Go 写的,资源占用极低,我现场的系统都是这么配的。
4.2.1 配置示例:Filebeat + Logstash + ES
下面是一个典型的 Filebeat 配置文件,采集 app-debug.log:
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/myapp/app-debug.log
# 加个标签,方便后期区分
tags: ["myapp-debug"]
output.logstash:
hosts: ["logstash-server:5044"]
# 还可以加写入 Kafka 做缓冲
# output.kafka:
# hosts: ["kafka-broker:9092"]
# topic: "myapp-logs"
Logstash 接收后怎么做解析?举个例子,解析一个多行异常堆栈:
# logstash.conf
input {
beats {
port => 5044
}
}
filter {
if "myapp-debug" in [tags] {
multiline {
pattern => "^\s"
what => "previous"
negate => false
}
# 用 grok 提取关键字段
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{LOGLEVEL:level}\] %{GREEDYDATA:msg}" }
}
date {
match => [ "timestamp", "ISO8601" ]
}
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "myapp-debug-%{+yyyy.MM.dd}"
}
}
multiline 插件默认会把所有行吞掉,直到遇到下一个匹配行。如果你的堆栈每行开头都带空格,那就必须用 pattern => "^\s" 配合 what => "previous"。否则堆栈会被拆成一条条独立的日志,完全没法看。
4.3 Splunk 使用要点
Splunk 相对省心。它的核心是 SPL(Search Processing Language),说白了就是一种专为搜索日志设计的查询语法。查个接口调用次数:
index=myapp sourcetype=json
| search "api/v1/users"
| stats count by status
| sort - count
Splunk 的好处是:你不需要建索引,数据进来它就自动建好了。这对新手特别友好。但代价是——贵。我在某金融公司部署过 Splunk 集群,光 license 就花了小几十万,不过考虑到业务重要性,这个钱花得值。
4.4 最佳实践与坑点
日志集中管理不是说把日志堆到一起就行。我总结了几个关键点:
- 日志标准化:所有团队必须约定日志格式。我们当时统一要求:时间戳 + 日志级别 + 来源模块 + 请求 ID + 消息内容。这样解析起来才方便。
- 磁盘与性能规划:ES 集群写入太多会 IO 打满。我建议用 SSD,并且根据日志量提前规划分片数。一般日存量 ≤ 1TB,分片 5-10 个就够了。
- 生命周期管理:日志不能无限存。生产环境 debug 日志最多保留 7 天,info 日志 30 天,error 日志 90 天。利用 ES 的 ILM(索引生命周期管理)自动删除。
- 安全管控:日志里可能有用户密码、 等敏感信息。在 Logstash 或 Splunk 输入端做 脱敏(mask) 处理,避免数据泄露。
记住:日志采集一定要设置 限流(throttle) 和 采样(sampling)。高频日志可以按比例采集,或者设置每秒最多 1000 条。
4.5 从日志到故障定位
集中管理之后,排查故障就变成了一个 搜索 动作。比如:
- 用户反馈支付失败?查
requestId=xxx,几十毫秒就能看到完整链路。 - 系统突然变慢?看 Kibana 大盘,观察
response_time_avg趋势,找到时间拐点。 - 某个接口报 500 暴增?直接在 Kibana 里写个
level:ERROR AND api:/users,秒出结果。
我个人习惯把 关键错误 单独设置一个索引,比如 error-*。这样搜起来快,也不怕 debug 日志干扰。真正故障时,每秒钟都要抢,别浪费时间过滤无用的信息。