文章目录
- [Logstash 搭建与实战](#Logstash 搭建与实战)
-
- [一、ELK 架构与数据流向](#一、ELK 架构与数据流向)
-
- [1. 组件分工](#1. 组件分工)
- [2. 三种架构形态](#2. 三种架构形态)
- [3. Logstash 内部三阶段(面试高频)](#3. Logstash 内部三阶段(面试高频))
- [4. 一句话理解整条流](#4. 一句话理解整条流)
- [5. 面试常问对比](#5. 面试常问对比)
- [二、Logstash 部署](#二、Logstash 部署)
-
- [1. 安装 JDK(可跳过)](#1. 安装 JDK(可跳过))
- [2. 安装 Logstash](#2. 安装 Logstash)
- [3. 配置 JVM 堆内存](#3. 配置 JVM 堆内存)
- [4. 测试 Logstash](#4. 测试 Logstash)
- [三、Logstash 配置文件](#三、Logstash 配置文件)
-
- [1. 配置结构](#1. 配置结构)
- [2. 案例:采集系统日志 syslog 输出到 ES](#2. 案例:采集系统日志 syslog 输出到 ES)
- [四、实战(学习版):Logstash 直读 Nginx 日志](#四、实战(学习版):Logstash 直读 Nginx 日志)
-
- [步骤 1:编写 Logstash 配置文件](#步骤 1:编写 Logstash 配置文件)
- [步骤 2:检查权限(非常容易踩坑)](#步骤 2:检查权限(非常容易踩坑))
- [步骤 3:启动 Logstash 加载配置](#步骤 3:启动 Logstash 加载配置)
- [步骤 4:验证 ES 是否收到数据](#步骤 4:验证 ES 是否收到数据)
- [五、生产实践:Filebeat 采集 Nginx 日志 → Logstash → ES](#五、生产实践:Filebeat 采集 Nginx 日志 → Logstash → ES)
-
- [1. 生产链路图](#1. 生产链路图)
- [2. 安装 Filebeat](#2. 安装 Filebeat)
- [3. 配置 filebeat.yml](#3. 配置 filebeat.yml)
- [4. 权限处理(必做,否则读不到日志)](#4. 权限处理(必做,否则读不到日志))
- [5. 启动与开机自启](#5. 启动与开机自启)
- [6. Logstash 端配置(独立 Logstash 服务器)](#6. Logstash 端配置(独立 Logstash 服务器))
- [7. 语法检查与运行方式](#7. 语法检查与运行方式)
- 六、高频坑点总结
- 七、面试小问答
Logstash 搭建与实战
Logstash 是 ELK 栈中的数据处理管道,负责日志的采集、清洗与输出。本文从 ELK 整体架构讲起,涵盖 Logstash 部署、配置文件编写、Nginx 日志采集实战,以及生产环境 Filebeat + Logstash 的完整落地(rpm / apt 两种安装方式)。
一、ELK 架构与数据流向
ELK = Elasticsearch + Logstash + Kibana ,官方整套栈现在叫 Elastic Stack ,通常还会加入 Filebeat(轻量采集器,生产环境必用)。
1. 组件分工
| 组件 | 角色 |
|---|---|
| Filebeat | 部署在业务服务器,采集日志文件(轻量,占用资源很小) |
| Logstash | 数据处理管道:过滤、清洗、转换、解析日志(CPU 消耗更高) |
| Elasticsearch | 存储、索引日志数据,提供搜索查询能力(核心存储) |
| Kibana | 可视化 Web 界面,查日志、画图、做仪表盘 |
2. 三种架构形态
① 最简单架构(学习测试)
数据源 → Logstash → Elasticsearch ← Kibana
- 数据源:标准输入 stdin、文件、TCP 端口等
- Logstash 采用
input → filter → output三段式处理 - 缺点:生产不能这么玩------Logstash 直接部署在业务机太重,没有缓冲,日志量大容易丢
② 生产标准架构(Filebeat 版,企业最常用)
业务服务器日志文件 → Filebeat → Logstash → Elasticsearch ← Kibana
完整数据流向:
- 采集:Filebeat --- 部署在业务机器上,监听磁盘日志文件(nginx、java 应用日志等),读取新增日志行并发送给 Logstash。自带重试、断点续传,机器重启不会从头重读日志。
- 处理:Logstash --- 三阶段流水线:
input:接收 Filebeat 发来的原始日志filter(最重要):日志清洗!切割字段、时间格式化、过滤无效日志、IP 解析、去除无用内容output:把处理干净的结构化数据发送给 Elasticsearch
- 存储索引:Elasticsearch --- 接收 Logstash 推送的数据,自动建立索引,分片存储,对外提供搜索 API
- 可视化查询:Kibana --- 只读 ES,不碰原始日志;做日志检索、告警、报表图表
③ 高可用架构(大规模,加消息队列缓冲)
当日志流量暴涨,为防止 Logstash/ES 扛不住丢数据,中间加入消息队列(Kafka):
业务日志 → Filebeat → Kafka 消息队列 → Logstash 消费 Kafka → Elasticsearch ← Kibana
- Filebeat 把日志发给 Kafka,队列缓存峰值流量
- Logstash 从 Kafka 消费、慢慢处理;即使 ES 短暂故障,日志在 Kafka 里也不会丢失
3. Logstash 内部三阶段(面试高频)
ruby
input { } # 数据从哪里来(file/beats/stdin/tcp)
filter { } # 数据清洗转换,可空,测试环境经常省略
output { } # 数据输出去哪里(elasticsearch/stdout)
如果执行命令时没有写 filter,就是原始数据直接输出 ES。
4. 一句话理解整条流
Filebeat 去各个机器"捡日志",交给 Logstash"洗日志拆字段",洗好存进 Elasticsearch 数据库,最后 Kibana 给人看界面查日志。
5. 面试常问对比
Filebeat vs Logstash
| 对比项 | Filebeat | Logstash |
|---|---|---|
| 定位 | 轻量采集器,只采集、不做复杂处理 | 专注数据清洗转换 |
| 语言 / 资源 | Go 编写,占用极小 | JRuby,吃内存 CPU |
| 部署位置 | 业务服务器 | 独立服务器 |
为什么生产不用 Logstash 直接读日志文件?
Logstash 耗资源,部署在业务服务器会抢占业务程序 CPU 内存,所以用 Filebeat 分布式采集。
二、Logstash 部署
Logstash 一般部署在需要收集日志的服务器。在本案例中,Logstash 部署在 Web 节点 上,用于收集日志并发送到 Elasticsearch。
1. 安装 JDK(可跳过)
Logstash 7.x 之前的版本都需要安装 JDK;7.x 之后版本内置了 JDK 环境,可以不装,也可以自行安装。
2. 安装 Logstash
bash
# 上传、解压
tar -zxvf logstash-7.17.27-linux-x86_64.tar.gz -C /usr/local/
cd /usr/local/
mv logstash-7.17.27 logstash
# 创建软链接,方便全局使用 logstash 命令
ln -s /usr/local/logstash/bin/logstash /usr/local/bin/
3. 配置 JVM 堆内存
bash
vim /usr/local/logstash/config/jvm.options
properties
-Xms2g
-Xmx2g
4. 测试 Logstash
常用命令选项
| 选项 | 说明 |
|---|---|
-f |
指定 Logstash 配置文件,按文件配置输入和输出流 |
-e |
从命令行获取配置;若为空,默认 stdin 作为输入、stdout 作为输出 |
-t |
测试配置文件语法是否正确(只校验、不启动服务 ,返回 Configuration OK) |
-w |
指定 filter 线程数量,默认 5 |
-l |
指定日志文件名称 |
✅ 最佳实践:修改完配置文件,必须先执行
-t语法检查,再启动服务。
标准输入 → 标准输出
bash
# 输入采用标准输入,输出采用标准输出(类似管道),新版本默认使用 rubydebug 格式输出
logstash -e 'input { stdin{} } output { stdout{} }'
logstash -e 'input { stdin{} } output { stdout{ codec=>rubydebug } }'
运行后键入内容,终端输出:
json
www.baidu.com # 键入内容(标准输入)
{
"@timestamp" => 2020-12-22T02:15:39.136Z, # 输出结果(标准输出处理后的结果)
"@version" => "1",
"host" => "web1",
"message" => "www.baidu.com"
}
标准输入 → Elasticsearch
bash
logstash -e 'input { stdin{} } output { elasticsearch { hosts=>["192.168.80.20:9200"] } }'
www.baidu.com # 键入内容(标准输入)
www.sina.com.cn # 键入内容(标准输入)
www.google.com # 键入内容(标准输入)
结果不在标准输出显示,而是发送至 Elasticsearch。可浏览器访问
http://192.168.80.10:9100/(Elasticsearch Heads 插件)查看索引信息和数据浏览。
三、Logstash 配置文件
Logstash 配置文件基本由三部分组成:input、output 以及可选的 filter(根据需要选择使用)。
1. 配置结构
input { ... } # 数据从哪里来:采集数据(Kafka、日志文件等)
filter { ... } # 数据处理层:格式化、类型转换、数据过滤(支持正则)
output { ... } # 数据输出去哪里:处理后的数据送往何处
常用插件
| 部分 | 插件 | 说明 |
|---|---|---|
| input | file / beats / kafka / redis / stdin | 常见数据源 |
| filter | grok |
把若干大文本字段再分割成小字段,(?<字段名>正则表达式) |
| filter | date |
对数据中的时间格式进行统一和格式化 |
| filter | mutate |
重命名、删除、替换和修改事件字段(剔除无用字段、增加自定义字段) |
| filter | multiline |
对多行数据进行统一编排,将多行数据汇总为单一一行 |
| output | elasticsearch / stdout | 输出目标 |
参考资料:https://blog.csdn.net/weixin_42073629/article/details/110154037
配置文件内容格式
input {
...
}
filter {
...
}
output {
...
}
多数据源示例:每个部分中也可以指定多个访问方式。例如指定两个日志来源文件:
input {
file {
path => "/var/log/syslog"
type => "system_log"
}
file {
path => "/var/log/auth.log"
type => "auth_log"
}
}
2. 案例:采集系统日志 syslog 输出到 ES
bash
chmod +r /var/log/syslog # 让 Logstash 可以读取日志
mkdir /usr/local/logstash/conf.d/
cd /usr/local/logstash/conf.d/
vim syslog.conf
syslog.conf 内容:
input {
file {
path => "/var/log/syslog"
type => "system_log_192.168.80.13"
start_position => "beginning"
#ignore_older => 86400
sincedb_path => "/usr/local/logstash/sincedb_path/log_progress"
}
}
output {
elasticsearch { # 输出到 elasticsearch
hosts => ["192.168.80.10:9200","192.168.80.11:9200","192.168.80.12"] # 指定 elasticsearch 服务器的地址和端口
index => "system_log_192.168.80.13-%{+yyyy.MM.dd}" # 指定输出到 elasticsearch 的索引格式
}
}
file 插件常用参数
| 参数 | 说明 |
|---|---|
path |
要收集的日志文件位置,必须使用绝对路径,可使用通配符匹配;同时指定多个文件用 , 间隔 |
exclude |
排除不想监听的文件 |
type |
指定 Event 的 type 字段;若输入 ES 时未指定 document_type,此处 type 将作为 ES 中 index 的 type |
start_position |
beginning 表示从头开始读取,end 表示读取最新的(默认);该选项只在第一次启动时有效,需与 ignore_older 一起使用 |
ignore_older |
针对多久以内修改过的文件进行监控,默认一天,单位秒 |
sincedb_path |
sincedb 文件路径,保存每个日志文件已被读取到的位置;Logstash 重启后从上次位置继续读取。想重新从头读取需删除 sincedb 文件;设为 /dev/null 即不保存位置信息(必须指定文件而不是目录) |
sincedb_write_interval |
设置多久写入一次读取位置信息,单位秒 |
delimiter |
文件内容的行分隔符,默认按 \n 进行 Event 封装 |
启动前准备 sincedb 文件并运行:
bash
mkdir /usr/local/logstash/sincedb_path
touch /usr/local/logstash/sincedb_path/log_progress
logstash -f syslog.conf
完成后可用谷歌浏览器的 Elasticsearch Heads 插件查看索引信息。
四、实战(学习版):Logstash 直读 Nginx 日志
架构:Nginx日志文件 → Logstash(input读取文件) → filter解析nginx日志 → output输出ES
⚠️ 生产环境不推荐 Logstash 直接读日志,优先 Filebeat;这里演示 Logstash 直接读取文件的方式,适合学习。
Nginx 日志分两种:默认 access 普通日志 、error 错误日志 。日志路径一般在 /var/log/nginx/access.log、/var/log/nginx/error.log。
步骤 1:编写 Logstash 配置文件
新建配置文件(如 nginx_log.conf),放在 logstash 的 config/ 目录:
# input 输入:读取 nginx 访问日志
input {
file {
path => "/var/log/nginx/access.log" # nginx 访问日志路径
start_position => "beginning" # 第一次运行从文件开头读;后续默认记住偏移量,不会重复读
sincedb_path => "/dev/null" # 关闭记录读取偏移量的文件,测试用;生产去掉这个配置
}
}
# filter 过滤【重点:解析 nginx 日志,把一整行字符串拆成字段】
filter {
# 使用 grok 插件切割 nginx 访问日志
grok {
match => { "message" => '%{IPORHOST:client_ip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATH:request_uri}(?:\?%{URIPARAM:query})? HTTP/%{NUMBER:http_version}" %{NUMBER:response_code:int} %{NUMBER:bytes:int} "%{DATA:referer}" "%{DATA:user_agent}"' }
}
# 把日志里的时间字符串,转为 ES 识别的 @timestamp 时间字段
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
}
}
# output 输出:写入 ES
output {
elasticsearch {
hosts => ["192.168.80.10:9200"] # 你的 ES 地址
index => "nginx-access-%{+YYYY.MM.dd}" # 按天生成索引
}
# stdout { codec => rubydebug } # 打开可终端打印解析后的日志,调试用,生产注释
}
注意:上面 grok 模式适配 Nginx 默认的 combined 日志格式 。如果你的 nginx 改过
log_format,grok 表达式要跟着改,否则解析失败。
步骤 2:检查权限(非常容易踩坑)
logstash 运行用户一般是 logstash,这个用户读不到 /var/log/nginx 日志!
# 方案 1:给日志读权限
chmod 644 /var/log/nginx/*.log
# 方案 2:把 logstash 用户加入 nginx 组
usermod -aG nginx logstash
步骤 3:启动 Logstash 加载配置
# -f 指定配置文件路径
/usr/share/logstash/bin/logstash -f /etc/logstash/config/nginx_log.conf
打开调试输出 stdout { codec => rubydebug },启动后终端会打印解析好的结构化日志,用来验证 grok 是否解析成功。
步骤 4:验证 ES 是否收到数据
# 查看当天生成的 nginx 索引
curl -XGET 192.168.80.10:9200/_cat/indices?v | grep nginx-access
# 查询数据
curl 192.168.80.10:9200/nginx-access-2026.08.16/_search?q=*
Kibana 里创建索引模式,填入 nginx-access-*,即可可视化查看 nginx 访问日志。
五、生产实践:Filebeat 采集 Nginx 日志 → Logstash → ES
Logstash 很重,不适合部署在 Nginx 机器上读磁盘文件!正确做法:Nginx 服务器部署 Filebeat 读取日志文件,发送给 Logstash;Logstash 只做 filter 清洗,输出 ES。
1. 生产链路图
Nginx 机器:
nginx 日志文件(/var/log/nginx/*.log) → Filebeat(读取本地日志) → 主动连接 → Logstash 服务器:5044
Logstash 服务器:
5044 端口 beats input 接收数据 → filter(grok 解析清洗) → output 输出到 ES(9200)
ES ← Kibana 做查询展示
2. 安装 Filebeat
版本要求:Filebeat、Logstash、Elasticsearch 大版本号尽量保持一致,避免版本兼容问题,例如全部用 8.x。
方式一:rpm 安装(CentOS 7/8)
bash
# 下载 rpm 包,版本尽量和 ES、Logstash 大版本保持一致
rpm -ivh filebeat-8.11.0-x86_64.rpm
方式二:apt 安装(Debian / Ubuntu)
bash
# 步骤 1:安装依赖,导入 Elastic GPG 密钥
apt update
apt install -y apt-transport-https ca-certificates curl gnupg
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elastic.gpg
# 步骤 2:添加 elastic apt 源(想装 7.x 就把 packages/8.x 改成 packages/7.x)
echo "deb [signed-by=/usr/share/keyrings/elastic.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list
# 步骤 3:更新并安装
apt update
apt install -y filebeat
apt 注意点:
- 源里默认安装最新 8.x;需要指定版本可用
apt install filebeat=8.11.0锁定版本。 - 安装完默认是关闭的,不会自动采集任何日志 ,必须修改
filebeat.yml并启动。
安装路径对照表
| 项目 | CentOS(rpm) | Ubuntu(apt) |
|---|---|---|
| 主配置文件 | /etc/filebeat/filebeat.yml |
/etc/filebeat/filebeat.yml |
| 模块配置目录 | --- | /etc/filebeat/modules.d/ |
| 服务管理 | systemctl 管理 |
systemd 托管 |
| 日志查看 | journalctl -u filebeat -f |
/var/log/filebeat/(也可 journalctl) |
3. 配置 filebeat.yml
⚠️ yml 严格注意缩进:只能空格,不能用 tab,否则无法启动。
yaml
# ========== 输入源:采集 nginx 日志 ==========
filebeat.inputs:
- type: filestream
enabled: true
paths:
- /var/log/nginx/access.log # nginx 访问日志
- /var/log/nginx/error.log # nginx 错误日志
# ========== 输出:发给远程 Logstash,不要直接输出 ES ==========
output.logstash:
hosts: ["192.168.80.10:5044"] # Logstash 机器 IP:5044 端口
# 注释掉默认的 output.elasticsearch,避免 filebeat 直连 ES
#output.elasticsearch:
# hosts: ["http://localhost:9200"]
4. 权限处理(必做,否则读不到日志)
filebeat 服务运行用户是 filebeat,读不到 /var/log/nginx 的日志:
bash
# 把 filebeat 用户加入 nginx 组
usermod -aG nginx filebeat
# 日志文件保证组可读
chmod g+r /var/log/nginx/*.log
5. 启动与开机自启
bash
systemctl daemon-reload
systemctl start filebeat
systemctl enable filebeat
systemctl status filebeat
# 实时看 filebeat 日志排错
journalctl -u filebeat -f
排错:如果日志采集不到,优先看
journalctl -u filebeat -f。常见报错:权限不足、连不上 Logstash 的 5044 端口(防火墙拦截)。
防火墙
- Nginx 机器:Filebeat 主动向外发起连接 ,不需要开放本机端口,只需允许出站访问 Logstash 服务器 5044 端口。
- Logstash 机器:需要放行 5044 端口 接收 Filebeat 数据,例如
ufw allow 5044。
6. Logstash 端配置(独立 Logstash 服务器)
新建配置文件,例如 /etc/logstash/conf.d/nginx-pipeline.conf;Logstash 会读取 conf.d/ 目录下所有 .conf 后缀的配置文件。
ruby
# input 接收 filebeat,端口固定 5044
input {
beats {
port => 5044
}
}
filter {
# 解析 access 日志 grok,error 日志可以另外处理
grok {
match => { "message" => '%{IPORHOST:client_ip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATH:request_uri}(?:\?%{URIPARAM:query})? HTTP/%{NUMBER:http_version}" %{NUMBER:response_code:int} %{NUMBER:bytes:int} "%{DATA:referer}" "%{DATA:user_agent}"' }
}
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
}
}
output {
elasticsearch {
hosts => ["192.168.80.10:9200"]
index => "nginx-access-%{+YYYY.MM.dd}"
}
# stdout { codec => rubydebug } # 调试打开,打印解析后数据;生产注释
}
7. 语法检查与运行方式
Logstash
bash
# 语法检查 -t(只校验配置语法,不会真正启动服务;返回 Configuration OK 即通过)
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx-pipeline.conf -t
# 前台调试运行(终端打印日志,Ctrl+C 停止)
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx-pipeline.conf
# 生产后台运行(systemd 方式)
systemctl start logstash
systemctl enable logstash
systemctl status logstash
Filebeat (没有 -t,用 test config 校验)
bash
filebeat test config
# 输出 Config OK 代表配置文件语法没问题
六、高频坑点总结
- yaml 缩进:filebeat.yml 是 yaml 格式,缩进错误直接无法启动,不要用 tab。
- 日志权限 :filebeat / logstash 用户读不到 nginx 日志,无数据输出------加入 nginx 组并
chmod g+r。 - 防火墙 5044 :Logstash 机器未放行 5044 端口,filebeat 连接失败(
ufw allow 5044)。 - 配置校验 :修改 Logstash 配置后一定要先
-t语法校验,再重启服务 ;filebeat 用filebeat test config。 - grok 解析失败 :ES 文档出现
_grokparsefailure标签,代表日志格式和 grok 模板不匹配。 - sincedb_path :测试设置
/dev/null,每次启动从头读文件;生产一定要删掉,否则会重复消费全部日志。 - Nginx 日志轮转:日志切割后 filebeat 自动处理;logstash file 输入也支持,但不如 filebeat 稳定。
- 索引命名:不能大写,不能以下划线开头。
七、面试小问答
Q:为什么不用 Logstash 直接读业务机器的日志?
A:Logstash 基于 JVM,占用内存 CPU 高,如果部署在业务服务器会抢占业务资源;Filebeat 轻量级 Go 开发,专门做采集,只负责把日志推送出去,业务服务器只部署 Filebeat。
小面试点:rpm vs apt
CentOS(RPM) 用 yum/rpm;Ubuntu(Debian) 用 apt/deb。两者安装完配置逻辑完全一致,只是安装方式和包管理器不一样。