日志管理:集中式日志架构(ELK/EFK)、日志采集与传输(Filebeat/Logstash)、日志分析与检索技巧
日志这东西,平时没人搭理它,一出事它就是唯一的救命稻草。我见过太多团队,系统崩了连日志都找不到,或者找到了打不开,打开了看不懂。说白了,日志管理不是锦上添花,是雪中送炭。
这一章,咱们聊聊集中式日志架构怎么搭,采集传输怎么搞,以及检索分析有哪些实用技巧。嗯,都是我在生产环境里摸爬滚打总结出来的。
集中式日志架构:ELK 还是 EFK?
先说说架构选型。ELK 是 Elasticsearch、Logstash、Kibana 三件套。EFK 就是把 Logstash 换成 Fluentd。我个人习惯用 EFK,原因很简单——Fluentd 更轻量,资源占用少,而且天然支持 Kubernetes。
但这不是绝对的。我在项目中遇到过 Logstash 处理复杂数据转换的场景,它的 Filter 插件生态确实比 Fluentd 丰富。你想想看,如果你的日志格式特别奇葩,需要大量正则解析和字段提取,Logstash 会更顺手。
下面是一个典型的 ELK 架构图(文字版):
应用服务器 → Filebeat → Logstash → Elasticsearch → Kibana
↓
(缓存层: Redis/Kafka)
为什么要加缓存层?我曾经踩过这个坑。有一次业务高峰期,日志量突然暴涨,Logstash 处理不过来,直接把 Elasticsearch 打挂了。从那以后,我都在 Logstash 前面加一层 Kafka 或者 Redis 做缓冲。说白了,就是给系统加个「泄洪闸」。
日志采集与传输:Filebeat vs Logstash
很多人搞不清楚 Filebeat 和 Logstash 的区别。我简单说:Filebeat 是「搬运工」,Logstash 是「加工厂」。
Filebeat 只负责读日志文件、发出去。它轻量、稳定、不占资源。Logstash 则能做解析、过滤、转换、丰富数据。但 Logstash 吃内存,Java 写的嘛,你懂的。
我的建议是:采集用 Filebeat,处理用 Logstash。分工明确,各司其职。
来看一个 Filebeat 的配置示例:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
service: nginx
env: production
output.logstash:
hosts: ["192.168.1.100:5044"]
loadbalance: true
这里有个细节:loadbalance: true。我建议开启,这样 Filebeat 会轮询多个 Logstash 节点,避免单点故障。嗯,这个配置我是在一次 Logstash 宕机事故后加上的。
再看 Logstash 的配置:
input {
beats {
port => 5044
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
mutate {
remove_field => ["message"]
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "nginx-logs-%{+YYYY.MM.dd}"
}
}
日志分析与检索技巧
日志都存进去了,怎么查?很多人只会用 Kibana 的搜索框输入关键词,然后翻页翻到怀疑人生。其实 Elasticsearch 的查询语法很强大,掌握几个核心技巧就够了。
1. 精确匹配 vs 全文搜索
默认情况下,Kibana 的搜索是全文搜索。比如你搜 error,它会匹配所有包含 error 的字段。但如果你只想搜 level: error,就得用字段查询:
level: "error"
或者你想搜某个 IP 的访问记录:
client_ip: "192.168.1.1"
我刚开始用的时候,经常搜出一堆无关结果。后来养成习惯,先看字段名,再写查询语句。效率提升不止一倍。
2. 范围查询
查时间范围,别用鼠标点日历。直接写:
@timestamp: [now-1h TO now]
查响应时间超过 5 秒的请求:
response_time: > 5000
这个在排查慢接口时特别好用。我记得有一次线上告警说接口超时,我直接用这个查询把 TOP 10 慢请求揪出来了。
3. 布尔查询
组合条件用 AND、OR、NOT:
level: "error" AND service: "payment"
排除某些干扰项:
level: "error" NOT message: "healthcheck"
为什么要排除 healthcheck?因为健康检查的日志太多了,不排除的话,真正的错误会被淹没。这个坑我踩过,后来学乖了。
4. 聚合分析
Kibana 的 Visualize 功能可以帮你做聚合。比如统计每个服务的错误数:
{
"size": 0,
"aggs": {
"by_service": {
"terms": {
"field": "service.keyword",
"size": 10
}
}
}
}
这个查询返回的是每个服务的错误数量排名。我经常用它来做日报,看看哪个服务今天「表现最差」。
- 采集用 Filebeat,处理用 Logstash,存储检索用 Elasticsearch,可视化用 Kibana
- 一定要加缓存层(Kafka/Redis),防止日志洪峰打垮 ES
- Grok 正则先调试再上线,避免解析失败
- 检索时多用字段查询和布尔组合,少用全文搜索
- 聚合分析是排查问题的利器,别只停留在搜索层面
最后说一句:日志系统建好了,不是一劳永逸的。你得定期检查索引大小、清理过期数据、优化查询性能。我每个月都会做一次 ES 集群的健康检查,看看有没有分片分配不均、查询慢、磁盘快满的情况。说白了,运维就是个持续优化的活。
下一章咱们聊聊监控告警,那又是另一片天地了。