第4章:Logstash安装与基础——架构、Pipeline配置、启动与调试
说到ELK栈,很多人第一反应是Elasticsearch。但我个人认为,真正把数据玩出花样的,其实是Logstash。它就像一个数据,负责把各种各样、奇形怪状的日志,变成我们想要的样子。今天,我们就来好好聊聊它。
4.1 Logstash的核心架构:一条数据的奇幻漂流
Logstash的架构其实不复杂。说白了,就是三条:输入、过滤、输出。业内管这个叫“Pipeline”模型,也就是管道。
我在项目中第一次看到这个模型时,脑子里就浮现出一个画面:一堆乱七八糟的原材料(日志),被丢到传送带上;工人们(过滤器)在传送带两边挑挑拣拣、改改修修;最后成品被打包(输出)送到仓库(Elasticsearch)。嗯,就是这个感觉。
核心要点:Logstash的事件处理是一个单线程Pipeline。每个事件会依次经过输入、多个过滤器、输出。但如果你的机器够强,可以通过多Worker并行处理,这个后面会讲。
那么数据的生命周期长什么样?看下面这张图:
从上图你能看到,一个事件要穿过好几个区域。你想想看,如果其中任何一环出了问题,整个数据流就断了。所以理解这个架构,是你排查问题的第一步。
4.2 Pipeline配置:写你的第一个管道
好了,理论说完了,我们上手干活。Logstash的配置文件,本质上就是用Ruby风格的语法,告诉它「数据从哪来、怎么洗、往哪去」。
我最开始学的时候,总喜欢把三种配置写在一个文件里,结果项目一多,文件变得肥大臃肿。后来我的习惯是:一个场景一个文件,放在/etc/logstash/conf.d/下面,方便管理,也方便调试。
小技巧:在Linux上,/etc/logstash/conf.d/目录下的.conf文件会按字母顺序加载。如果涉及插件依赖,给文件编号是个好习惯,比如10-system.conf、20-nginx.conf。
我们看一个基础例子。假设你要从文件中读取Nginx的access.log,把IP地址提取出来,然后写入Elasticsearch:
input {
file {
path => "/var/log/nginx/access.log"
start_position => "beginning" # 从文件头开始读
sincedb_path => "/dev/null" # 测试时禁用sincedb,避免重复消费
codec => "plain" # 纯文本格式
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
}
mutate {
remove_field => [ "message" ] # 原始消息处理完后,可以丢掉
}
}
output {
stdout { codec => rubydebug } # 先打印到控制台调试
# elasticsearch { # 确认没问题后再打开
# hosts => ["localhost:9200"]
# index => "nginx-access-%{+YYYY.MM.dd}"
# }
}
看到了吗?我把Elasticsearch的输出注释掉了,用stdout先看效果。这是我个人的习惯——先跑通,再上线。别看这个小举动,帮我在之前省了不少排查时间。
配置文件里这些块的含义,我整理了一张表:
| 配置块 | 角色 | 常见插件 |
|---|---|---|
input |
定义数据来源 | file、beats、kafka、tcp、syslog |
filter |
数据清洗与转换 | grok、mutate、date、geoip、useragent |
output |
定义数据目的 | elasticsearch、stdout、kafka、file |
codec |
数据格式的编解码 | plain、json、rubydebug、multiline |
注意事项:input和output块是必须的,filter块可选。但大多数情况下你会至少需要一个filter,否则原始日志直接进ES,搜索分析会很痛苦。
4.3 启动与调试:让管道跑起来
配置写好了,接下来就是启动和调试。Logstash的启动命令很简单,但参数折腾了我不少时间。
最基本的命令是这样:
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx.conf
如果一切正常,你会看到Logstash启动并开始监听文件。但如果你直接在终端运行,它会占据前台。我在生产环境一般会通过systemd管理,这是后话了。
调试的时候,有几个参数特别实用:
--config.test_and_exit:只检查配置文件语法,不启动。我每次改完配置都会跑一下这个,省得启动报错。--config.reload.automatic:当配置文件变化时自动重载。调试时很有用,但生产环境建议关闭,避免意外触发。-r:同上,是--config.reload.automatic的缩写。-w:指定Worker数量。默认是1,但你的CPU核心数如果多,可以调大,比如-w 4。
举个例子,你写好配置后,先检查语法是否正确:
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx.conf --config.test_and_exit
看到Configuration OK字样,心里就有底了。然后你可以用-r让它自动重载,边改边看效果。
工程师小贴士:调试阶段,千万别忘了在output里加上stdout { codec => rubydebug }。这样你能直接看到事件经过filter后的样子,哪里解析错了,一目了然。我当初做grok调试时,几乎全靠这个。
还记得我之前提到的sincedb吗?在调试时,我建议像我一样把sincedb_path设为/dev/null。否则Logstash会记住已经读过的文件偏移量,你重启后它以为文件没更新,啥也不会输出。嗯,这个坑我踩过不止一次。
4.4 必知必会:启动参数与配置项速查
最后,我把常用的启动参数和核心配置项整理给你。不求全背,但用的时候知道在哪找。
| 参数/配置 | 作用 | 我的建议值 |
|---|---|---|
--config.test_and_exit |
验证配置语法 | 每次修改配置后必须执行 |
--config.reload.automatic |
自动重载配置 | 调试开,生产关 |
pipeline.workers |
并行处理Worker数 | CPU核心数的一半 |
pipeline.batch.size |
每个Worker批次处理事件数 | 125~500之间调试 |
queue.type |
队列类型(memory/persisted) | 小数据量memory,关键数据用persisted |
我个人最喜欢的调试流程是:写配置 → --config.test_and_exit验证 → 启动并加上-r和stdout → 灌入一小份测试日志 → 观察输出 → 调优filter → 确认没问题后,换回Elasticsearch输出并取消自动重载。这套流程走下来,基本不会出大乱子。
忍不住再说一句:如果你想测grok解析效果,Logstash自带了grokdiscover工具,也可以在线用 grok debugger。但作为运维,我推荐直接在stdout里看结果,因为能一块儿验证mutate、date等其他过滤器。
Logstash的基础就这些。它不难,但细节很多。