elasticsearch+kibana+logstash+filebeat链路部署流程
节点分配:
192.168.24.41= node1:Elasticsearch + Kibana(存储+展示层)
192.168.24.42= node2:Logstash(数据处理层)
192.168.24.43= node3:Filebeat(日志采集层)
一、整体架构与原理
简述原理流程:
node3作为采集层、node2作为处理层、node1作为存储展示层,全链路通过轻量协议串联,支持断点续传和流量削峰。首先业务系统或系统服务(如sshd、内核)在node3上产生日志并写入/var/log/messages等文件,Filebeat作为轻量采集器,通过filestream插件实时监控文件变更,将读取进度记录到registry文件避免重复采集,再通过Beats私有协议把原始非结构化日志推送到node2的5044端口;随后Logstash作为数据处理中枢,先通过beats输入插件接收数据,再用grok插件把杂乱的syslog文本解析为带syslog_timestamp、syslog_hostname、syslog_message的结构化字段,date插件将日志自带的时间校准为@timestamp作为官方时间戳,mutate插件剔除agent.version、ecs这类冗余字段降低存储开销,之前调试用的stdout插件就是把处理后的结构化日志打印到控制台,方便验证解析规则是否正确,最后通过elasticsearch输出插件把数据批量发送到node1的9200端口;Elasticsearch作为分布式搜索引擎,按logs-YYYY.MM.dd的规则按天创建索引,将日志以JSON文档形式存储,通过倒排索引实现毫秒级检索,单节点模式下自动适配无副本的存储策略;最终Kibana作为可视化前端,通过REST API从ES拉取索引数据,在Discover页面提供时间范围筛选、关键词搜索、字段过滤能力,把结构化的JSON日志转化为可视化的表格,还可进一步生成统计仪表盘、配置异常告警,整套链路中Filebeat负责“轻量采集”、Logstash负责“清洗加工”、Elasticsearch负责“高效存储”、Kibana负责“直观展示”,各环节解耦可独立扩缩容,完美支撑从日志产生到问题排查的全生命周期需求。
1.1 架构流程图
1.2 核心原理
组件 | 核心逻辑 | 遇到的坑 |
|---|---|---|
Filebeat | 轻量采集器,记录日志偏移量到 | ① 两个output冲突 ② registry路径错 ③ 没权限读 |
Logstash | 日志处理中枢,ES8.x默认开启数据流,传统 | 没加 |
Elasticsearch | 分布式搜索引擎,单节点默认创建1个副本,无第二节点时副本无法分配,索引显示 | 之前看到 |
SELinux | 强制访问控制,默认拦截Filebeat读取系统日志 | 之前关了SELinux后才通 |
二、前置准备(所有节点执行)
2.1 基础环境配置
1. 关闭SELinux
、也可以打标签放行,这里不是学习重点可以关闭
# ★ 永久关闭,避免重启后失效 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config setenforce 0 getenforce # 输出Permissive/Disabled才算成功2. 关闭防火墙/开放端口
# 测试环境直接关 systemctl stop firewalld systemctl disable firewalld # 生产环境建议只开必要端口: # node1开9200/9300/5601,node2开50443. 配置主机名解析(所有节点都要做)
cat >> /etc/hosts << EOF 192.168.24.41 node1 192.168.24.42 node2 192.168.24.43 node3 EOF4. 时间同步查看(避免日志时间错乱)
yum install -y chrony systemctl enable --now chronyd chronyc sources -v # 看到^*开头说明同步成功时间同步配置
1. 修改 node1 的 Chrony 配置(作为Server):
vim /etc/chrony.conf添加或修改:
# 允许局域网内的节点同步 allow 192.168.24.0/24 # 即使断网,也使用本地硬件时钟作为备用 local stratum 10重启:systemctl restart chronyd
2. 修改 node2 和 node3 的配置(作为Client):
vim /etc/chrony.conf注释掉公网 NTP,指向 node1:
#pool 2.rhel.pool.ntp.org iburst server 192.168.24.41 iburst prefer 指定要同步的上游 NTP 服务器地址。 iburst (重点,非常实用) 作用:加速初始同步。 prefer (优先级标记) 作用:标记为首选服务器重启:systemctl restart chronyd
3. 验证集群内同步:
在 node2 或 node3 上执行:
chronyc sources -v [root@node3 ~]# chronyc sources MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* node1 2 6 17 19 -2149ns[ -17us] +/- 36ms意义:node2/node3 直接同步 node1,时间源完全一致,消除了公网延迟带来的微小差异。
第四步:硬件时钟同步(防止重启后漂移)
系统时间(Software)重启后会丢失,需要从硬件时钟(RTC/BIOS)读取。必须确保两者一致。
# 1. 查看硬件时钟 hwclock -r # 2. 如果系统时间准,但硬件时间不准,把系统时间写入硬件(非常重要!) hwclock -w # 3. 设置系统时区(ELK日志强烈建议使用UTC或统一时区) timedatectl set-timezone Asia/Shanghai # 或者统一用UTC(推荐,避免夏令时问题) # timedatectl set-timezone UTC第五步:终极一致性验证(你想要的“同一个时间”)
在三个节点上同时执行,看时间戳是否大概一致:
有些许误差是能够接受的
for i in 192.168.24.41 192.168.24.42 192.168.24.43; do echo -n "$i: " ssh $i "date +'%Y-%m-%d %H:%M:%S.%3N'" done root@192.168.24.41's password: 2026-07-22 19:29:47.650 root@192.168.24.42's password: 2026-07-22 19:29:49.988 root@192.168.24.43's password: 2026-07-22 19:29:52.2342.2 系统依赖与调优
1. 安装JDK(ELK基于Java开发)
Java Downloads | Oracle
dnf install -y java-25-openjdk java -version # 验证安装成功 [root@node1 ~]# java -version java version "25.0.3" 2026-04-21 LTS Java(TM) SE Runtime Environment (build 25.0.3+9-LTS-195) Java HotSpot(TM) 64-Bit Server VM (build 25.0.3+9-LTS-195, mixed mode, sharing)2. 创建ELK专用用户(禁止root运行,安全要求)
useradd elk mkdir -p /opt/elk /opt/logs/{elasticsearch,logstash,filebeat} chown -R elk:elk /opt/elk /opt/logs3. 内核参数调优(ES强制要求)
# 最大文件句柄数/进程数 cat >> /etc/security/limits.conf << EOF elk soft nofile 65535 elk hard nofile 65535 elk soft nproc 40960 elk hard nproc 40960 EOF # 虚拟内存参数(ES用mmap锁内存,必须改) echo "vm.max_map_count=262144" >> /etc/sysctl.conf sysctl -p原理解释:
limits.conf里的配置是为elk用户专门设置的资源门槛,nofile控制单进程最多能同时打开的文件句柄数,Elasticsearch和Logstash需要频繁读写大量日志文件和网络连接,默认1024的上限会直接导致服务崩溃,65535是确保高并发下稳定运行的基础保障;nproc则是限制用户能创建的最大进程数,防止日志采集和处理的子进程耗尽系统资源。soft是运行时的软限制,hard是系统允许的最高上限,软限制不能超过硬限制。
vm.max_map_count是Linux内核允许一个进程拥有的虚拟内存区域数量上限,Elasticsearch重度依赖mmap(内存映射)技术将磁盘上的索引文件直接映射到内存中进行高效读写,默认65530的数值远不能满足ES创建大量内存映射区的需求,262144这个值是官方经过大规模测试验证的最低要求,低于这个值ES会启动失败,调整它能确保ES在索引和搜索海量日志时不会因为内存映射区不足而报错。
三、分节点部署
3.1 node1(192.168.24.41):Elasticsearch + Kibana
3.1.1 Elasticsearch部署
Elasticsearch:官方分布式搜索和分析引擎 | Elastic
su - elk cd /opt/elk wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.18.8-linux-x86_64.tar.gz tar -zxvf elasticsearch-8.18.8-linux-x86_64.tar.gz ln -s /opt/elk/elasticsearch-8.18.8 /opt/elk/elasticsearch exit2. 核心配置/opt/elk/elasticsearch/config/elasticsearch.yml
cluster.name: elk-cluster node.name: node1 path.data: /opt/logs/elasticsearch path.logs: /opt/logs/elasticsearch network.host: 0.0.0.0 http.port: 9200 # 单节点模式(当前只有1个ES节点,后续扩集群再改) discovery.type: single-node # 测试环境关闭安全认证(生产环境务必开启) xpack.security.enabled: false xpack.security.enrollment.enabled: false xpack.security.http.ssl.enabled: false xpack.security.transport.ssl.enabled: false3. JVM内存配置(根据你的机器内存调整,不要超过物理内存50%)
vim /opt/elk/elasticsearch/config/jvm.options # 4G内存机器改这个: -Xms1g -Xmx1g4. 配置systemd服务
cat > /usr/lib/systemd/system/elasticsearch.service << EOF [Unit] Description=Elasticsearch Service After=network.target [Service] User=elk Group=elk ExecStart=/opt/elk/elasticsearch/bin/elasticsearch Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF5. 启动验证
systemctl daemon-reload systemctl enable --now elasticsearch # 等10秒后验证 curl http://192.168.24.41:9200 # 预期返回包含"You Know, for Search"的JSON tail -f /opt/logs/elasticsearch/elasticsearch.log # 看启动日志3.1.2 Kibana部署
1. 下载解压
su - elk cd /opt/elk wget https://artifacts.elastic.co/downloads/kibana/kibana-8.18.8-linux-x86_64.tar.gz tar -zxvf kibana-8.18.8-linux-x86_64.tar.gz ln -s /opt/elk/kibana-8.18.8 /opt/elk/kibana #这里相当于软链接的方式,也可以和之前一样移动过去 exit2. 核心配置/opt/elk/kibana/config/kibana.yml
需修改的地方
server.port: 5601 server.host: "0.0.0.0" # ★ 指向你的node1的ES地址 elasticsearch.hosts: ["http://192.168.24.41:9200"] i18n.locale: "zh-CN" server.host: "0.0.0.0" 表示让 Kibana 监听服务器上的所有网络接口。简单来说,它告诉 Kibana:“不管请求是从本机的回环地址(127.0.0.1)、内网网卡(192.168.24.41),还是其他任何网卡发过来的,只要是访问 5601 端口的,统统都要接受。” 这里一般生产按需求写,不然就相当于裸奔很不安全,但是只有一个如果ip变化也容易导致服务挂3. 配置systemd服务
cat > /usr/lib/systemd/system/kibana.service << EOF [Unit] Description=Kibana Service After=network.target elasticsearch.service [Service] User=elk Group=elk ExecStart=/opt/elk/kibana/bin/kibana Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF4. 启动验证
systemctl daemon-reload systemctl enable --now kibana ss -tlnp | grep 5601 # 验证端口监听 # 浏览器访问 http://192.168.24.41:5601 即可打开Kibana3.2 node2(192.168.24.42):Logstash部署
3.2.1 基础部署
1. 下载解压
su - elk cd /opt/elk wget https://artifacts.elastic.co/downloads/logstash/logstash-8.18.8-linux-x86_64.tar.gz tar -zxvf logstash-8.18.8-linux-x86_64.tar.gz ln -s /opt/elk/logstash-8.18.8 /opt/elk/logstash exit2. 核心管道配置 /opt/elk/logstash/config/log-pipeline.conf
input { beats { port => 5044 # 接收Filebeat发送的日志 } } filter { # 只处理Filebeat标记的syslog类型日志 if [type] == "syslog" { grok { match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" } } date { # 用日志自带时间作为@timestamp,避免用采集时间 match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] target => "@timestamp" } } mutate { # 删除冗余字段,节省存储空间 remove_field => ["[agent][version]", "ecs"] } } output { elasticsearch { # ★ 指向你的node1的ES地址 hosts => ["http://192.168.24.41:9200"] index => "logs-%{+YYYY.MM.dd}" # ★ 之前卡的核心点:关闭ES8.x默认的数据流,否则写不进去 data_stream => false } # 控制台输出调试,之前就是在这里看到rubydebug日志的 #stdout { codec => rubydebug } }注意:
注释掉 stdout { codec => rubydebug } 是为了保障生产性能,因为该配置会强制 Logstash 将每一条流经的日志同步打印到控制台,在高并发场景下会造成严重的 I/O 瓶颈和 CPU 开销,甚至导致日志堆积或进程崩溃;它应当仅在排查数据解析异常、验证 Grok 规则或确认字段映射时临时打开,作用是让你在不中断数据流的情况下,直观地观测日志经过 Filter 处理后的原始数据结构,从而快速定位配置错误。开启后你既能在终端前台运行时看到满屏的 JSON 日志,也能通过journalctl -u logstash -f在后台实时追踪这些数据。
3. JVM内存配置
vim /opt/elk/logstash/config/jvm.options # 处理层内存不用太大,512M足够 -Xms512m -Xmx512m4. 配置systemd服务
cat > /usr/lib/systemd/system/logstash.service << EOF [Unit] Description=Logstash Service After=network.target [Service] User=elk Group=elk # 指定自定义管道配置 ExecStart=/opt/elk/logstash/bin/logstash -f /opt/elk/logstash/config/log-pipeline.conf Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF5. 启动验证和查看管道状态
systemctl daemon-reload systemctl enable --now logstash ss -tlnp | grep 5044 # 验证5044端口监听 tail -f /opt/elk/logstash/logs/logstash-plain.log # 看启动日志 [root@node2 ~]# ss -lntup | grep 5044 tcp LISTEN 0 4096 *:5044 *:* users:(("java",pid=8147,fd=122)) [root@node2 logs]# curl -s http://localhost:9600/_node/stats/pipeline {"path":"/_node/stats/pipeline","status":404,"error":{"message":"Not Found"}}[root@node2 logs]# curl -s http://localhost:9600/_node/pipelines/main?pretty { "host" : "node2", "version" : "8.18.8", "http_address" : "127.0.0.1:9600", "id" : "841fe993-fccd-46e5-8de5-882e08990e09", "name" : "node2", "ephemeral_id" : "03c83ae1-95b5-4ca0-bd38-f4227a5c7112", "snapshot" : false, "status" : "green", "pipeline" : { "workers" : 4, "batch_size" : 125, "batch_delay" : 50 }, "pipelines" : { "main" : { "ephemeral_id" : "64639abe-9b50-462f-80f5-72452e0bb62c", "hash" : "822ca5d59d4db87e99ebf8a804dec461707e7a468d632b2ed11cf5d0c5f7bf07", "workers" : 4, "batch_size" : 125, "batch_delay" : 50, "config_reload_automatic" : false, "config_reload_interval" : 3000000000, "dead_letter_queue_enabled" : false } } }[root@node2 logs]#看logstash是否接受到filebeat的数据
[root@node2 logs]# curl -s http://localhost:9600/_node/stats/events?pretty { "host" : "node2", "version" : "8.18.8", "http_address" : "127.0.0.1:9600", "id" : "841fe993-fccd-46e5-8de5-882e08990e09", "name" : "node2", "ephemeral_id" : "03c83ae1-95b5-4ca0-bd38-f4227a5c7112", "snapshot" : false, "status" : "green", "pipeline" : { "workers" : 4, "batch_size" : 125, "batch_delay" : 50 }, "events" : { "in" : 1102, "filtered" : 1102, "out" : 1102, "duration_in_millis" : 4285, "queue_push_duration_in_millis" : 17 } in > 0 且持续增长 → Logstash 确实在源源不断收到数据 in ≈ filtered ≈ out → 数据处理正常,没有积压 如果 in 为 0 → 说明 Filebeat 根本没把数据送过来,问题在 node3 或网络 例子: "events": { "in": 293658, // 收到的事件总数 "filtered": 293658, // 经过 filter 处理的事件数 "out": 293658 // 发送给 output 的事件数 }3.3 node3(192.168.24.43):Filebeat部署
3.3.1 基础部署
1. 下载解压
su - elk cd /opt/elk wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.18.8-linux-x86_64.tar.gz tar -zxvf filebeat-8.18.8-linux-x86_64.tar.gz ln -s /opt/elk/filebeat-8.18.8 /opt/elk/filebeat exit2. 核心配置/opt/elk/filebeat/filebeat.yml
###################### Filebeat inputs ######################### filebeat.inputs: # filestream 是 8.x 推荐的类型,相比旧的 log 类型性能更好,占用资源更低 - type: filestream enabled: true # 采集路径:这里配置了两个目标 # /tmp/test_elk.log 是之前为了排除干扰创建的测试文件(权限最松) # /var/log/messages 和 /secure 是正式的系统日志 paths: - /tmp/test_elk.log - /var/log/messages - /var/log/secure # 自定义字段:给日志打上一个标记,告诉 Logstash “这是 syslog” fields: type: syslog # ★ 关键配置:将 fields 提到根级别 # 如果不设此项,Logstash 里要用 [fields][type] 才能取到值 # 设了此项,Logstash 里直接用 [type] 即可,简化了 grok 的条件判断 fields_under_root: true ###################### Output (只留 Logstash) ######################### # ★ 核心点:确保只有一个 output output.logstash: # 指向 node2 的 Logstash 地址 # Filebeat 会通过 Beats 协议将数据发送到此端口 hosts: ["192.168.24.42:5044"] ###################### Setup (全部关闭) ######################### # 关闭索引生命周期管理:因为你使用的是自定义的 Logstash 索引名(logs-*) # 如果不关,Filebeat 可能会尝试去连接 ES 管理策略,导致冲突 setup.ilm.enabled: false # 关闭 Kibana 自动配置:我们不通过 Filebeat 去配置 Kibana 的仪表盘 # 而是由我们在 Kibana 界面手动创建 Index Pattern setup.kibana.enabled: false ###################### Processors ######################### processors: # 添加主机元数据:自动把 hostname、IP 地址等信息塞进日志里 # 这样你在 Kibana 里就能看到这条日志来自哪台机器 - add_host_metadata: # 过滤条件:如果没有包含 forwarded 标签,才执行这个 processor # 防止日志被多次转发时重复添加主机信息 when.not.contains.tags: forwarded ###################### Logging (排错用) ######################### # ★ 排错神器:开启 Debug 模式 logging.level: debug # 指定 Debug 的范围:只关心输入(采集)、收割(读取文件)、发布(发送数据) # 不关心内部琐碎逻辑,避免日志刷屏 logging.selectors: ["input", "harvester", "publish"] # 日志输出到文件(而不是 stdout),方便持久化查看 logging.to_files: true logging.files: # Filebeat 自己的日志存放路径 path: /opt/elk/filebeat/logs name: filebeat # 保留最近 7 个日志文件,防止硬盘爆满 keepfiles: 73. 解决权限问题(之前遇到的/var/log/messages读不了的问题)
# 把elk加入系统日志读取组 usermod -aG adm elk # 修改日志文件权限,让elk能读 chmod 640 /var/log/messages /var/log/secure chown root:adm /var/log/messages /var/log/secure -aG:是两个参数的组合。 -G:修改用户的附加组(Supplementary Groups)。 -a(append,追加):极其重要。它表示“在原有附加组的基础上,新增一个组”。 如果不加 -a,直接执行 -G adm elk,会把 elk 用户原本加入的其他附加组(如果有的话)全部清空,只保留 adm 组,容易造成事故。 adm:是 Linux 系统的一个内置用户组。在 Debian/Ubuntu 和 RHEL/CentOS 系统中,/var/log/ 目录下的多数日志文件(如 messages、secure)的属组通常都是 adm,并且权限设置为 640(root:adm 可读)。4. 配置校验(必做,避免启动失败)
sudo -u elk /opt/elk/filebeat/filebeat test config -c /opt/elk/filebeat/filebeat.yml # 输出Config OK才算合格 [root@node3 ~]# sudo -u elk /opt/elk/filebeat/filebeat test config -c /opt/elk/filebeat/filebeat.yml Config OK [root@node3 logs]# sudo -u elk /opt/elk/filebeat/filebeat test output -c /opt/elk/filebeat/filebeat.yml logstash: 192.168.24.42:5044... connection... parse host... OK dns lookup... OK addresses: 192.168.24.42 dial up... OK TLS... WARN secure connection disabled talk to server... OK5. 配置systemd服务
cat > /usr/lib/systemd/system/filebeat.service << EOF [Unit] Description=Filebeat Log Collector After=network.target [Service] User=elk Group=elk ExecStart=/opt/elk/filebeat/filebeat -c /opt/elk/filebeat/filebeat.yml Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF6. 启动验证
systemctl daemon-reload systemctl enable --now filebeat systemctl status filebeat # 状态为active (running) # 看Filebeat日志,确认没有报错 journalctl -u filebeat -f四、全链路验证
4.1 基础服务状态验证
# node1验证 systemctl status elasticsearch kibana # node2验证 systemctl status logstash # node3验证 systemctl status filebeat所有服务均为active (running)。
4.2 生成测试日志(和你之前的操作一致)
在node3上写入唯一标识的测试日志:
echo "ELK_TEST_$(date +%s)" >> /var/log/messages 或者: logger -t "ELK_VERIFY" "CHAIN_OK_$(date +%s)"以下图片测试语句:
[root@node3 logs]# logger -t "ELK_FINAL_CHECK" "IF_YOU_SEE_THIS_IN_KIBANA_IT_IS_100_PERCENT_WORKING_$(date +%s)"4.3 Logstash侧验证
在node2上执行:
tail -f /opt/elk/logstash/logs/logstash-plain.log4.4 ES侧验证
在node1上执行:
curl -s http://192.168.24.41:9200/_cat/indices?v | grep logs [root@node1 ~]# curl -s http://192.168.24.41:9200/_cat/indices?v | grep logs green open .internal.alerts-observability.logs.alerts-default-000001 tTry6Fj4RwezJru7i58OqA 1 0 0 0 249b 249b 249b yellow open logs-2026.07.21 4Q87_1qCS7GnsO3UpE1lng 1 1 6944 0 2.8mb 2.8mb 2.8mb yellow open logs-2026.07.22 zODPvn8KRESte0GwCVmOnQ 1 1 3825 0 1.9mb 1.9mb 1.9mb [root@node1 ~]# logs-2026.07.22 业务日志yellow是单节点正常现象:
节点一 查询测试日志(message自己改一下就行)
[root@node1 ~]# curl -s "http://192.168.24.41:9200/logs-2026.07.22/_search?pretty" -H "Content-Type: application/json" -d '{"query":{"match":{"message":"TEST"}},"size":1}' { "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 12.600115, "hits" : [ { "_index" : "logs-2026.07.22", "_id" : "7UcGip8B2Lbiy6X6gLYw", "_score" : 12.600115, "_source" : { "@version" : "1", "message" : "TEST_LOG_VIA_SSH: 1784727095", "type" : "syslog", "host" : { "architecture" : "x86_64", "mac" : [ "00-0C-29-49-94-58", "16-D7-54-06-48-C9", "3E-9B-46-61-8B-BE", "7A-89-D0-7E-A5-00", "C2-28-AC-45-A8-5E", "CE-81-17-7C-BF-88", "F2-17-96-10-05-C3" ], "id" : "2007d48c709543b69c75168429fc3c77", "hostname" : "node3", "name" : "node3", "os" : { "platform" : "rhel", "codename" : "Coughlan", "type" : "linux", "version" : "10.1 (Coughlan)", "family" : "redhat", "name" : "Red Hat Enterprise Linux", "kernel" : "6.12.0-124.8.1.el10_1.x86_64" }, "containerized" : false, "ip" : [ "192.168.24.43", "fe80::20c:29ff:fe49:9458", "172.17.0.1", "172.18.0.1", "fe80::c028:acff:fe45:a85e", "fe80::cc81:17ff:fe7c:bf88", "fe80::7889:d0ff:fe7e:a500", "fe80::f017:96ff:fe10:5c3", "fe80::3c9b:46ff:fe61:8bbe" ] }, "@timestamp" : "2026-07-22T13:31:39.572Z", "agent" : { "name" : "node3", "id" : "7a74921a-4792-4902-8e08-4550f1a20464", "ephemeral_id" : "b3643330-abb2-4fde-a413-fc9507452bcc", "type" : "filebeat" } } } ] } } [root@node1 ~]#4.5 Kibana侧验证
访问
http://192.168.24.41:5601打开Kibana左侧Discover,时间范围选
All time,搜索KQL语句,即可看到日志。或者左侧日志,里面也有详细的内容
查询测试日志(左侧Discover)
一、为什么感觉“测试日志诞生得晚”?
测试时并不能马上查询到,以下时间参考,可能会更长
1. Filebeat 的采集间隔(最主要原因)
Filebeat 不是“文件一变就立刻读”,而是有一个扫描周期(默认scan_frequency: 10s)。
它每 10 秒才去检查一次
/var/log/messages有没有新内容。你写入日志后,最多可能要等 10 秒,Filebeat 才会发现文件变了并开始读取。
这是设计如此,避免高频扫描拖垮磁盘 I/O。
2. Logstash 的批处理机制(次要原因)
Logstash 不是“收到一条就立刻转发一条”,而是攒批:
pipeline.batch.size: 125:要攒够 125 条才发一批。pipeline.batch.delay: 50:最多等 50ms 凑批。如果你只写了一条测试日志,Logstash 会等够 125 条或超时后才发给 ES。
之前看到 ES 里一次性多了几千条,就是因为之前积压的旧日志被批量刷过去了。
3. Kibana 的刷新间隔
Kibana Discover 页面默认不会自动刷新,即使 ES 里已经有新数据,你不点刷新按钮或改时间范围,它就一直显示旧的查询结果。
五.后续操作
关掉Filebeat的Debug日志(不然会占满磁盘):
vim /opt/elk/filebeat/filebeat.yml # 把 logging.level: debug 改成 logging.level: info systemctl restart filebeat把Logstash的batch_size改回默认值(提高吞吐量):
vim /opt/elk/logstash/config/pipeline/log-pipeline.conf # 把 batch_size => 1 改回 batch_size => 125 systemctl restart logstash pipeline.workers: 4 # 默认是CPU核数,不用改 pipeline.batch.size: 250 # 默认125,日志量大可以翻倍 pipeline.batch.delay: 50 # 默认50ms,攒批超时时间Kibana里保存查询模板:
在Discover页面搜
TEST_LOG_VIA_SSH,点击右上角「保存」,以后直接打开就能看实时日志。扩展采集其他日志(比如Nginx/Java/Docker日志):
只要在node3的
filebeat.yml里加对应的paths,比如采集Nginx访问日志:paths: - /var/log/nginx/access.log - /var/log/nginx/error.log设置索引生命周期(避免磁盘爆满):
在Kibana的
Stack Management → Index Lifecycle Policies里,给logs-*索引设置自动删除30天前的旧日志。