3、日志采集与存储:日志采集工具(Filebeat、Logstash)、日志存储方案(Elasticsearch、文件系统)、日志轮转策略
日志采集与存储,是整个日志分析体系的基石。你想想看,如果连日志都收不上来、存不好,后面再牛的分析手段都是白搭。这一节,我就把这块硬骨头给大家啃透。
3.1 日志采集工具:Filebeat vs Logstash
先说采集层。市面上工具不少,但真正在生产环境里经得起考验的,我个人习惯用 Filebeat 和 Logstash 这对组合。它们俩分工明确,各司其职。
3.1.1 Filebeat:轻量级采集器
Filebeat 是 Elastic 官方出的一个轻量级采集器。说白了,它的核心任务就一个:把日志文件里的内容读出来,然后发出去。它不干别的,所以特别轻,资源占用极低。
我在项目中遇到过一台老旧的交易服务器,CPU 和内存都很紧张。当时如果上 Logstash 采集,机器直接扛不住。换成 Filebeat 后,CPU 占用率不到 5%,内存也就几十兆,完美解决。
Filebeat 的配置其实很简单。核心就三块:输入(从哪里读)、输出(发到哪里去)、以及一些处理逻辑。看个例子:
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/trading/*.log
multiline:
pattern: '^\d{4}-\d{2}-\d{2}'
negate: true
match: after
output.elasticsearch:
hosts: ["localhost:9200"]
index: "trading-logs-%{+yyyy.MM.dd}"
嗯,这里要注意 multiline 配置。交易系统的日志经常是多行的,比如一个异常堆栈会跨好几行。如果不做多行合并,Elasticsearch 里就会看到一堆碎片,根本没法分析。我刚开始用 Filebeat 时就踩过这个坑,后来才养成了必配 multiline 的习惯。
3.1.2 Logstash:强大的数据处理管道
Logstash 就不一样了。它是个重型武器,能干的事情多得多。除了采集,它还能做数据解析、过滤、转换、增强。你可以把它理解成一个数据加工厂。
为什么需要 Logstash?举个例子,交易日志里记录的金额可能是字符串 "1,234.56",但 Elasticsearch 里做聚合分析需要的是浮点数。Filebeat 干不了这个,但 Logstash 可以。
看一个典型的 Logstash 配置:
# logstash.conf
input {
beats {
port => 5044
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:message_body}" }
}
mutate {
convert => { "amount" => "float" }
}
date {
match => [ "timestamp", "ISO8601" ]
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "trading-logs-%{+yyyy.MM.dd}"
}
}
这里用到了 grok 插件来解析日志格式。我个人习惯把日志格式定义得尽量规范,这样 grok 匹配起来又快又准。如果日志格式乱七八糟,grok 规则会写得你想哭。
核心建议:Filebeat 负责采集和传输,Logstash 负责解析和加工。两者配合使用,既保证了采集层的轻量,又保证了处理层的强大。
3.2 日志存储方案:Elasticsearch vs 文件系统
日志存到哪里?这是个灵魂拷问。我见过不少团队,一开始图省事直接存文件系统,结果查询时想死的心都有。也见过一上来就上 Elasticsearch,结果集群维护成本高得吓人。
3.2.1 Elasticsearch:全文搜索与分析利器
Elasticsearch 是当前日志存储的事实标准。它为什么这么火?因为它解决了传统文件系统最大的痛点:搜索。
你想想看,如果日志存在文件里,你想查某个交易订单号的所有日志,得怎么做?要么用 grep 一行行扫,要么写脚本遍历。几百万行日志,查一次几分钟就过去了。而 Elasticsearch 基于倒排索引,毫秒级返回结果。
我在项目中遇到过线上故障,需要快速定位某个订单在哪个环节出了问题。用 Elasticsearch 的 Kibana 界面,输入订单号,一秒不到所有相关日志就出来了。如果当时用的是文件系统,估计故障都恢复了还没查完。
Elasticsearch 的索引设计也很关键。对于交易系统日志,我建议按天建索引,比如 trading-logs-2024.01.15。这样数据管理方便,过期删除也简单。
# 创建索引模板
PUT _index_template/trading-logs-template
{
"index_patterns": ["trading-logs-*"],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s"
},
"mappings": {
"properties": {
"@timestamp": { "type": "date" },
"level": { "type": "keyword" },
"message": { "type": "text" },
"order_id": { "type": "keyword" },
"amount": { "type": "float" }
}
}
}
}
注意:Elasticsearch 不是银弹。如果日志量特别大(每天几百 GB 以上),集群规模会迅速膨胀,运维成本很高。这时候要考虑冷热分层存储,或者结合其他方案。
3.2.2 文件系统:简单可靠的备选方案
文件系统存储日志,虽然查询不方便,但胜在简单、可靠、成本低。对于一些非核心系统,或者日志量特别小的情况,文件系统完全够用。
我曾经维护过一个内部监控系统,每天日志量不到 100MB。这种量级上 Elasticsearch 纯属浪费。直接按日期存文件,配合 grep 和 awk 就能搞定。
文件系统存储的关键是目录结构要规范。我建议这样组织:
/var/log/trading/
├── 2024/
│ ├── 01/
│ │ ├── trading-2024-01-15.log
│ │ ├── trading-2024-01-16.log
│ │ └── ...
│ └── 02/
└── archive/
└── 2023/
这种结构,配合脚本做归档和清理,管理起来很顺手。
3.3 日志轮转策略
日志轮转,说白了就是不能让日志文件无限增长。否则磁盘满了,系统就挂了。这个道理大家都懂,但真正做好的不多。
3.3.1 基于大小的轮转
最常用的策略是按文件大小轮转。比如每个日志文件最大 100MB,超过就自动切分。Linux 自带的 logrotate 工具就能实现。
/var/log/trading/*.log {
daily
rotate 30
size 100M
compress
delaycompress
missingok
notifempty
create 0640 trading trading
postrotate
systemctl reload filebeat
endscript
}
这里有个细节:delaycompress。它表示延迟压缩,也就是切分出来的第一个旧文件不立即压缩。为什么?因为 Filebeat 可能还在读这个文件。如果立即压缩成 .gz,Filebeat 就读不到了,会导致日志丢失。我曾经就因为这个丢过数据,后来才加上这个参数。
3.3.2 基于时间的轮转
按时间轮转也很常见,比如每天切一次。交易系统我建议按小时轮转,因为交易高峰期日志量特别大,按天轮转一个文件可能几个 GB,查询和传输都不方便。
经验之谈:轮转策略要结合采集工具一起考虑。Filebeat 有 close_inactive 参数,默认 5 分钟。如果日志轮转太快,Filebeat 可能还没来得及读完就关闭了文件句柄。我一般把轮转间隔设成 1 小时,Filebeat 的 close_inactive 设成 10 分钟,这样配合起来很顺畅。
3.3.3 保留策略
日志保留多久?这个没有标准答案,取决于业务需求和法规要求。交易系统通常要求保留 6 个月到 2 年。我建议分两层:
- 热数据(最近 7 天):存在 Elasticsearch 里,方便快速查询
- 温数据(7 天到 6 个月):压缩后存文件系统或对象存储
- 冷数据(6 个月以上):归档到低成本存储,必要时再恢复
这种分层策略,既保证了查询效率,又控制了存储成本。
3.4 整体架构图
说了这么多,我画一张图把整个流程串起来。这样大家能更直观地理解日志从采集到存储的完整链路。
3.5 避坑指南
最后,我把自己这些年踩过的坑总结一下,大家能少走弯路就少走。
我曾经犯过的错:
- 日志格式不统一:不同模块的日志格式五花八门,导致 grok 规则写了上百条,维护成本极高。后来我强制所有模块使用统一的 JSON 格式,解析效率提升 10 倍。
- 忽略磁盘监控:有一次日志量突然暴增,磁盘写满,导致交易系统直接挂掉。从那以后,我必配磁盘告警,阈值设在 80%。
- Filebeat 版本不匹配:Filebeat 和 Elasticsearch 的版本要匹配,否则可能出现兼容性问题。我建议保持大版本一致。
好了,日志采集与存储这块就讲到这里。记住一句话:采集要轻、存储要稳、轮转要勤。把这三点做到位,你的日志体系就成功了一大半。