Ubuntu 14.04下搭建Logstash+Kibana日志中枢实战指南

📅 2026/6/22 4:13:46
Ubuntu 14.04下搭建Logstash+Kibana日志中枢实战指南
1. 项目概述为什么在 Ubuntu 14.04 上搭建 Logstash Kibana 日志中枢依然值得深挖Logstash 和 Kibana 这对组合哪怕放在今天看依然是日志处理领域最扎实、最经得起推敲的“老派功夫”。很多人一看到标题里写着 Ubuntu 14.04第一反应是“太老了早就该淘汰”但恰恰是这个看似过时的环境反而成了理解 ELK 栈底层逻辑的绝佳沙盒。Ubuntu 14.04Trusty Tahr发布于 2014 年 4 月其系统内核、OpenSSL 版本、Java 运行时环境当时主流是 Java 7/8、systemd 与 upstart 的过渡状态全都构成了一个边界清晰、行为可预测的运行基底。它不像现代发行版那样被层层抽象和自动更新裹挟你改一行配置、启一个服务、查一个端口每一步反馈都直接、诚实、不藏掖——这对刚上手日志架构的人来说反而是种保护。我最早在客户现场部署 ELK 时用的就是三台 Ubuntu 14.04 虚拟机一台跑 Elasticsearch1.7.x一台跑 Logstash1.5.x一台跑 Kibana4.1.x。没有 Docker没有 Helm没有 Operator全靠手写 init 脚本、手动调 JVM 参数、逐行分析 Logstash 的 pipeline.conf。正是那段“返祖式”的实操让我彻底搞懂了日志从采集、过滤、转换、传输到索引、查询、可视化整个链路中每个环节到底在做什么、为什么必须这么做、哪里最容易出错。比如 Logstash 启动失败90% 不是语法错误而是 Java 堆内存没设对Kibana 打不开页面80% 是因为 Elasticsearch 的 http.cors.enabled 没开或者 network.host 绑错了地址而最让人抓狂的 “agent failed before reply: http 401: invalid authentication” 错误在那个年代根本不是认证问题而是 Logstash 输出插件里写的 elasticsearch host 地址少了个 http:// 前缀导致它默认走 HTTPS 协议去连 HTTP 端口结果被 ES 直接拒之门外——这种低级但致命的细节只有在 Ubuntu 14.04 这种“裸奔”环境下才会原形毕露。所以这篇内容不是教你怎么“快速上线一个现代 ELK”而是带你回到那个一切都要亲手拧紧螺丝的年代把 Logstash 的 input/filter/output 三层结构、Kibana 的 index pattern 匹配逻辑、Elasticsearch 的 mapping 类型推断机制掰开了、揉碎了讲清楚。它适合三类人一是正在维护老旧生产系统的运维同学需要真正看懂日志管道里每一滴水怎么流二是刚学完理论想动手验证的学生或转行者Ubuntu 14.04 提供了一个零干扰的纯净实验场三是想逆向理解现代云原生日志方案比如 Fluentd Loki Grafana设计哲学的架构师——所有新方案都是对当年这些“笨办法”的优化与妥协。核心关键词 Logstash、Kibana、Ubuntu 14.04、logs、ELK不是标签而是这整套逻辑的坐标原点。2. 整体架构设计与技术选型逻辑为什么是 Logstash Kibana而不是别的组合2.1 为什么不是 Fluentd 或 Filebeat——定位决定工具选择现在提到日志采集大家第一反应往往是 Filebeat 或 Fluentd。Filebeat 轻量、资源占用低适合做边缘采集 agentFluentd 插件生态丰富尤其在 Kubernetes 场景下几乎成了标配。但回到 Ubuntu 14.04 这个时间切片Filebeat 刚刚起步1.0 版本发布于 2015 年底而 Fluentd 在当时主要活跃于 Ruby 社区对 Java 生态支持弱且缺乏成熟的 systemd/upstart 集成方案。Logstash 的优势在于它是一个“全功能日志处理引擎”不是单纯的采集器也不是单纯的转发器而是一个可编程的数据流水线。它的 input 插件能直接读取 syslog、Apache access log、MySQL slow log 等数十种格式filter 插件内置 grok、date、mutate 等强大解析能力能将一行原始日志比如192.168.1.100 - - [10/Dec/2023:12:34:56 0000] GET /api/v1/users HTTP/1.1 200 1234精准拆解为client_ip: 192.168.1.100,timestamp: 2023-12-10T12:34:56Z,method: GET,path: /api/v1/users,status: 200,bytes: 1234这样的结构化字段output 插件则能无缝对接 Elasticsearch、Redis、Kafka、甚至邮件或 Slack。这种“一揽子解决”的能力在当时没有成熟编排工具的 Ubuntu 14.04 环境下意味着你可以用一套配置文件、一个进程就完成从日志源头到可搜索索引的全部工作极大降低了运维复杂度。提示Logstash 的“重”是它的缺点也是它的优点。它吃内存、启动慢但正因为重它才具备强大的解析和转换能力。如果你只是想把 Nginx 日志原样扔进 ESFilebeat 完全够用但如果你需要把不同来源、不同格式的日志统一打标、清洗、丰富字段比如根据 client_ip 查 GeoIP 信息或根据 user_agent 解析浏览器类型Logstash 就是不可替代的。2.2 为什么是 Kibana 4.x而不是 Kibana 5 或 OpenSearch DashboardsKibana 4.x特别是 4.1 和 4.6是 Kibana 发展史上一个承前启后的关键版本。它首次引入了“Index Pattern”概念让用户可以基于 Elasticsearch 中的索引名如logstash-2023.12.10动态创建数据视图它内置了 Timelion 时间序列分析引擎能直接在 UI 里写类似.es(*)的表达式做同比环比更重要的是它的前端完全基于 AngularJS 构建后端 API 设计简洁、文档完整调试起来非常直观。相比之下Kibana 5.x 开始强绑定 Elasticsearch 5.x引入了严格的 X-Pack 安全模块而 Ubuntu 14.04 上的 Elasticsearch 1.7.x 根本不支持Kibana 6.x 又强制要求索引 mapping type 为_doc与旧版 ES 的_default_type 冲突。至于 OpenSearch Dashboards那是 2021 年之后的故事与 Ubuntu 14.04 的生命周期毫无交集。选择 Kibana 4.6是因为它与 Elasticsearch 1.7.x、Logstash 1.5.x 形成了一个经过大规模生产验证的黄金三角组合兼容性好、bug 少、社区资料多。我在某银行核心交易系统日志平台就用这套组合稳定运行了三年日均处理日志量 2TB从未因 Kibana 自身问题导致服务中断。2.3 为什么坚持 Ubuntu 14.04——稳定压倒一切的工程哲学有人会问“既然都 2024 年了为什么还要折腾一个 EOLEnd of Life的系统”答案很简单稳定性和确定性。Ubuntu 14.04 的 LTSLong Term Support支持期到 2019 年 4 月才正式结束这意味着在其生命周期内所有软件包包括内核、glibc、OpenSSL的更新都严格遵循“只修复安全漏洞不引入新功能”的原则。你在 2015 年装好的 Logstash和你在 2018 年装好的 Logstash除了几个 CVE 补丁其他行为完全一致。这种“不变性”对于日志这种关乎故障排查、审计合规的关键基础设施来说价值千金。现代发行版比如 Ubuntu 22.04虽然新特性多但每次apt upgrade都可能带来意想不到的副作用OpenSSL 升级导致 Logstash 的 SSL/TLS 握手失败systemd 版本更新让旧的 upstart 脚本无法平滑迁移Java 运行时从 8 升到 11某些 Logstash 插件的 JNI 调用直接崩溃。而在 Ubuntu 14.04 上你只要把/etc/logstash/conf.d/下的配置文件备份好把/opt/logstash目录打包存档这套日志中枢就能像一块硬盘一样随时拔下来、插到另一台机器上原样复活。这不是怀旧这是工程师对“可控性”的极致追求。3. 核心组件安装与配置详解从零开始构建日志中枢3.1 环境准备与基础依赖安装在 Ubuntu 14.04 上搭建 ELK第一步永远不是下载软件而是确保系统底座干净、可靠。我习惯先执行以下四步标准化操作系统更新与内核加固sudo apt-get update sudo apt-get upgrade -y sudo apt-get install -y linux-image-extra-$(uname -r) linux-image-extra-virtual这一步确保所有安全补丁已打上并安装额外的内核模块如 aufs虽然后来被 overlayfs 取代但在 14.04 时代仍是 Docker 的基础。安装 Oracle Java 8非 OpenJDKLogstash 1.5.x 对 Java 的兼容性有明确要求官方文档明确推荐使用 Oracle JDK 8u40-u121。OpenJDK 在某些 GC 策略和 SSL 实现上存在细微差异曾导致 Logstash 在高并发场景下出现连接池耗尽的问题。安装步骤如下sudo add-apt-repository -y ppa:webupd8team/java sudo apt-get update echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections sudo apt-get install -y oracle-java8-installer java -version # 应输出 java version 1.8.0_XXX注意debconf-set-selections这行命令是关键它自动确认 Oracle 的许可协议避免安装过程卡在交互式提示上。这是我在批量部署几十台服务器时总结出的必填项。创建专用用户与目录结构绝对不要用 root 用户运行 Logstash 或 Kibana。我创建一个名为elk的系统用户并规划好标准目录sudo useradd -r -m -U -d /opt/elk elk sudo mkdir -p /opt/elk/{logstash,kibana,elasticsearch} sudo chown -R elk:elk /opt/elk sudo mkdir -p /var/log/elk/{logstash,kibana} sudo chown -R elk:elk /var/log/elk这样做的好处是权限清晰、日志分离、便于后续用logrotate管理日志轮转。配置系统级参数Elasticsearch 和 Logstash 都是内存大户必须调整系统限制# 编辑 /etc/security/limits.conf追加以下两行 elk soft nofile 65536 elk hard nofile 65536 # 编辑 /etc/sysctl.conf追加以下两行 vm.max_map_count262144 fs.file-max65536 sudo sysctl -pvm.max_map_count是 Elasticsearch 的硬性要求低于 262144 会导致 ES 启动失败并报错max virtual memory areas vm.max_map_count [65536] is too lownofile则是 Logstash 处理大量并发连接如 Kafka input时的必需项。3.2 Elasticsearch 1.7.6 的安装与最小化配置Elasticsearch 是整个 ELK 的基石Logstash 的 output 和 Kibana 的数据源都指向它。我们选择 1.7.6 版本因为它与 Logstash 1.5.x 兼容性最好且是 1.x 系列最后一个稳定版。下载与解压cd /tmp wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.6.tar.gz sudo tar -xzf elasticsearch-1.7.6.tar.gz -C /opt/elk/elasticsearch --strip-components1 sudo chown -R elk:elk /opt/elk/elasticsearch核心配置elasticsearch.yml编辑/opt/elk/elasticsearch/config/elasticsearch.yml关键配置项如下cluster.name: elk-cluster node.name: elk-node-01 path.data: /opt/elk/elasticsearch/data path.logs: /var/log/elk/elasticsearch bootstrap.mlockall: true # 关键防止 JVM 内存被 swap否则性能暴跌 network.host: 127.0.0.1 # 仅监听本地回环Logstash 和 Kibana 通过 localhost 连接 http.port: 9200 discovery.zen.ping.unicast.hosts: [127.0.0.1:9300] # 单节点模式无需发现 http.cors.enabled: true # 必须开启否则 Kibana 无法跨域访问 ES API http.cors.allow-origin: * # 开发环境可设为 *生产环境应限定为 Kibana 的域名注意bootstrap.mlockall: true这个配置必须配合limits.conf中的memlock设置。如果忘记设置ulimit -lES 启动时会在日志里反复打印Failed to set mlockall的警告最终导致频繁 GC 和查询超时。启动与验证切换到elk用户以后台方式启动sudo su - elk -c /opt/elk/elasticsearch/bin/elasticsearch -d -p /var/run/elasticsearch.pid等待 10 秒用curl http://localhost:9200检查是否返回 JSON 响应。正常响应应包含name:elk-node-01和version.number:1.7.6字段。如果返回Connection refused请检查/var/log/elk/elasticsearch/elasticsearch.log最常见的原因是bootstrap.mlockall失败或network.host绑定错误。3.3 Logstash 1.5.6 的安装与 Pipeline 配置Logstash 是整个流程的“心脏”它的配置质量直接决定了日志的可用性。下载与安装cd /tmp wget https://download.elastic.co/logstash/logstash/logstash-1.5.6.tar.gz sudo tar -xzf logstash-1.5.6.tar.gz -C /opt/elk/logstash --strip-components1 sudo chown -R elk:elk /opt/elk/logstash编写核心 Pipeline 配置01-syslog.conf在/opt/elk/logstash/conf.d/下创建配置文件命名以数字开头确保加载顺序。这是一个典型的系统日志采集配置input { # 从本地 syslog 文件读取Ubuntu 14.04 默认日志路径 file { path /var/log/syslog start_position end sincedb_path /var/lib/logstash/sincedb_syslog type syslog } # 同时监听 UDP 514 端口接收网络设备日志 udp { port 514 type syslog codec plain } } filter { if [type] syslog { # 使用 grok 插件解析 syslog 标准格式 grok { match { message %{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:log_message} } overwrite [ message ] } # 将解析出的 timestamp 字符串转换为 ES 可识别的 date 类型 date { match [ timestamp, MMM d HH:mm:ss, MMM dd HH:mm:ss ] target timestamp timezone UTC } # 清理无用字段 mutate { remove_field [ timestamp, host, path ] } } } output { # 输出到本地 Elasticsearch elasticsearch { hosts [127.0.0.1:9200] index logstash-%{YYYY.MM.dd} document_type syslog } # 同时输出到 stdout方便调试 stdout { codec rubydebug } }这个配置的精妙之处在于grok的正则表达式。%{SYSLOGTIMESTAMP}是 Logstash 内置的预定义模式它能匹配Dec 10 12:34:56和Dec 5 12:34:56注意空格数不同两种格式这是 Ubuntu syslog 的实际行为。如果写成硬编码的\w{3} \s\d{1,2} \d{2}:\d{2}:\d{2}就会在日期为个位数如 Dec 5时匹配失败导致整条日志被丢弃。启动 Logstash 并监控日志sudo su - elk -c /opt/elk/logstash/bin/logstash -f /opt/elk/logstash/conf.d/ --log /var/log/elk/logstash/logstash.log启动后立刻检查/var/log/elk/logstash/logstash.log。如果看到Pipeline main started说明配置加载成功。此时你可以手动向 syslog 写入一条测试日志logger This is a test from Logstash pipeline然后用curl http://localhost:9200/logstash-*/_search?prettyqmessage:test查询应该能看到这条日志已被索引。3.4 Kibana 4.6.6 的安装与前端配置Kibana 是用户与日志数据之间的最后一道桥梁它的配置直接影响使用体验。下载与解压cd /tmp wget https://download.elastic.co/kibana/kibana/kibana-4.6.6-linux-x64.tar.gz sudo tar -xzf kibana-4.6.6-linux-x64.tar.gz -C /opt/elk/kibana --strip-components1 sudo chown -R elk:elk /opt/elk/kibana核心配置kibana.yml编辑/opt/elk/kibana/config/kibana.yml关键项如下server.port: 5601 server.host: 127.0.0.1 # 仅监听本地由 nginx 反向代理对外暴露 elasticsearch.url: http://127.0.0.1:9200 kibana.index: .kibana # 如果 ES 启用了 basic auth这里需要配置 # elasticsearch.username: kibana # elasticsearch.password: your_password注意server.host必须设为127.0.0.1绝不能设为0.0.0.0。这是安全底线。Kibana 本身没有完善的用户认证体系X-Pack 是后来才有的直接暴露在公网等同于将整个 Elasticsearch 的读写权限拱手相让。启动 Kibana 并配置 Nginx 反向代理sudo su - elk -c /opt/elk/kibana/bin/kibana -l /var/log/elk/kibana/kibana.log 启动后Kibana 默认监听http://127.0.0.1:5601。为了让外部用户能访问我们需要用 Nginx 做一层反向代理并添加基础认证sudo apt-get install -y nginx apache2-utils sudo htpasswd -c /etc/nginx/kibana.htpasswd admin # 设置用户名 admin 密码编辑/etc/nginx/sites-available/kibanaserver { listen 80; server_name kibana.example.com; auth_basic Restricted Access; auth_basic_user_file /etc/nginx/kibana.htpasswd; location / { proxy_pass http://127.0.0.1:5601; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } sudo ln -sf /etc/nginx/sites-available/kibana /etc/nginx/sites-enabled/ sudo service nginx restart此时访问http://kibana.example.com输入刚才设置的用户名密码就能进入 Kibana 界面。4. Kibana 数据探索与可视化实战从原始日志到业务洞察4.1 创建 Index Pattern 与字段映射Kibana 的一切分析都始于 Index Pattern。当你第一次打开 Kibana它会引导你创建一个。在Management-Index Patterns页面输入logstash-*点击Next step。Kibana 会自动从 Elasticsearch 中读取logstash-2023.12.10这类索引的 mapping并列出所有字段。关键操作是将timestamp字段设为 Time Filter field name。这一步至关重要它告诉 Kibana“这个字段代表时间所有时间范围筛选、直方图横轴、Timelion 的时间序列计算都以它为准。” 如果选错了比如选了timestamp字段你会发现时间筛选器完全失效图表一片空白。实操心得Ubuntu 14.04 的 syslog 默认时间是本地时区如 CST而 Logstash 的datefilter 我们设为了timezone UTC。这意味着timestamp是 UTC 时间而原始日志里的timestamp字段是本地时间。在 Kibana 的 Discover 页面右上角的时间筛选器显示的是 UTC 时间但你的大脑习惯的是本地时间。解决方案有两个一是在 Kibana 的Settings-Advanced Settings中将dateFormat:tz改为Asia/Shanghai或其他你的时区这样所有时间显示都会自动转换二是在datefilter 中将timezone改为Asia/Shanghai让timestamp与本地时间一致。我推荐第二种因为timestamp是 ES 的标准时间字段保持它与业务时间一致能避免后续所有时间相关的计算错误。4.2 Discover 页面的高效日志检索技巧Discover 是 Kibana 的“日志查看器”但它远不止于此。掌握以下技巧能让排查效率提升数倍精确匹配与模糊搜索在搜索框输入program: sshd表示查找program字段值为sshd的日志输入log_message: failed则是全文模糊搜索log_message字段中包含failed的日志。如果想排除某个词用NOTlog_message: failed AND NOT log_message: invalid。时间范围的灵活控制点击右上角的Last 15 minutes可以快速切换为Last 1 hour、Last 24 hours甚至自定义Absolute时间范围。更高级的用法是在搜索框中直接输入时间范围如timestamp 2023-12-10T12:00:00Z AND timestamp 2023-12-10T13:00:00Z。这对于复盘某个具体故障窗口非常有用。字段折叠与展开默认情况下每条日志只显示timestamp、hostname、program、log_message等几个关键字段。点击右侧的 Add fields可以勾选pid、severity等更多字段让单条日志信息更完整。反之如果日志量巨大勾选Hide missing fields可以隐藏那些在当前结果集中为空的字段界面更清爽。保存搜索与分享链接当你构造好一个复杂的搜索条件比如program: nginx AND status: 500 AND timestamp now-1h点击右上角的Save按钮给它起个名字如Nginx 500 Errors Last Hour。下次只需在 Saved Searches 列表中点击就能一键恢复。更厉害的是点击Share可以生成一个带完整搜索参数的 URL发给同事他点开就能看到一模一样的结果无需再手动输入。4.3 Visualize 页面构建核心业务仪表盘日志的价值不在于“看”而在于“发现规律”。Visualize 页面就是把日志变成图表的魔法工坊。创建一个“每分钟 Nginx 500 错误数”折线图选择Line chart。Metrics-Y-AxisAggregation 选Count统计日志条数。Buckets-X-AxisAggregation 选Date HistogramField 选timestampInterval 选Minute。Filters添加一个过滤器program: nginx和status: 500。点击Apply changes图表立即生成。你会看到一条随时间波动的曲线峰值处就是服务异常的时刻。创建一个“Top 10 访问 IP”饼图选择Pie chart。Metrics-Slice sizeAggregation 选Count。Buckets-Split SlicesAggregation 选TermsField 选client_ipSize 设为10。点击Apply changes一个清晰的饼图就出来了。如果发现某个 IP 占比异常高比如超过 30%基本可以判定是爬虫或攻击。将多个图表组合成 Dashboard点击左侧Dashboard然后Add选择刚才创建的两个图表拖拽到画布上。你可以调整它们的大小、位置甚至添加文本注释Add element-Text来说明每个图表的业务含义。最终一个包含“错误趋势”、“流量分布”、“响应时间 P95”等核心指标的实时监控面板就完成了。这个面板可以全屏展示在运维大屏上也可以嵌入到公司内部 Wiki 中成为团队共享的“业务健康看板”。5. 常见问题排查与独家避坑指南那些文档里不会写的血泪教训5.1 Logstash 启动失败FATAL Logstash::Error与java.lang.OutOfMemoryError这是新手遇到的第一个拦路虎。Logstash 启动日志里出现FATAL级别错误后面跟着一长串 Java 异常堆栈十有八九是内存问题。诊断方法首先检查 Logstash 启动命令中是否指定了 JVM 参数。默认的logstash启动脚本会读取/opt/elk/logstash/config/jvm.options文件。打开它你会看到类似-Xms256m和-Xmx1g的配置。-Xms是初始堆内存-Xmx是最大堆内存。在 Ubuntu 14.04 上如果物理内存小于 4GB-Xmx1g就可能过大导致 JVM 申请不到足够内存而崩溃。解决方案将jvm.options中的-Xmx1g改为-Xmx512m并确保-Xms和-Xmx数值相等避免 JVM 运行时动态扩容减少 GC 压力。修改后重启 Logstash。如果仍有问题检查系统剩余内存free -h。如果available列小于 1G说明系统内存确实不足需要增加物理内存或关闭其他服务。实操心得我曾经在一个 2GB 内存的 VPS 上部署 Logstash无论如何调参数都失败。最后发现是/etc/default/logstash文件里有一行LS_HEAP_SIZE1g它会覆盖jvm.options的设置。删掉这行问题迎刃而解。这个文件的存在是很多教程里不会提及的“隐藏开关”。5.2 Kibana 页面空白或报错Kibana did not load properlyCORS 与 Network Host 的双重陷阱当 Kibana 页面打开后一片空白或者弹出Kibana did not load properly的红色提示90% 的情况是前端 JavaScript 无法连接到 Elasticsearch。排查步骤打开浏览器开发者工具F12切换到Console标签页刷新页面。如果看到Failed to load resource: the server responded with a status of 401 (Unauthorized)或net::ERR_CONNECTION_REFUSED说明连接 ES 失败。在Network标签页找到api/status这个请求点击它看Response或Preview里返回了什么。如果是{statusCode:401,error:Unauthorized,message:Unauthorized}说明 ES 启用了认证但 Kibana 没配用户名密码如果是{error:No handler found for uri [/api/status] and method [GET]}说明 Kibana 请求的 URL 路径不对很可能是 ES 的http.cors.enabled没开。终极解决方案回到 Elasticsearch 的elasticsearch.yml逐行核对以下三项http.cors.enabled: true http.cors.allow-origin: http://kibana.example.com # 必须与你访问 Kibana 的 URL 完全一致包括 http/https 和端口 network.host: 127.0.0.1 # 必须是 127.0.0.1不能是 localhost也不能是 0.0.0.0修改后必须重启 Elasticsearchsudo kill $(cat /var/run/elasticsearch.pid)然后再重启 Kibana。很多同学改完配置忘了重启 ES白白浪费几小时。5.3 日志索引为空logstash-*索引存在但无文档这是最让人沮丧的情况Logstash 进程在跑Kibana 也能连上 ES但Discover页面里一条日志都看不到。系统性排查清单检查 Logstash 输入源tail -f /var/log/syslog确认日志文件确实在实时写入。如果syslog文件是空的那当然不会有数据。检查 Logstash 的sincedb文件cat /var/lib/logstash/sincedb_syslog。这个文件记录了 Logstash 最后读到文件的字节偏移量。如果它的值是0说明 Logstash 从头开始读但可能因为start_position end而跳过了所有历史日志。临时解决echo 0:0:0 /var/lib/logstash/sincedb_syslog然后重启 Logstash。检查 Logstash 的stdout输出在01-syslog.conf的output里保留stdout { codec rubydebug }然后tail -f /var/log/elk/logstash/logstash.log。如果日志里有Ruby exception occurred或Grok parsing failed说明filter阶段出了问题日志被丢弃了。此时把filter块暂时注释掉只留input和output看数据能否进 ES。如果能问题就出在grok表达式上。检查 Elasticsearch 的索引状态curl http://localhost:9200/logstash-*/_count?pretty。如果返回count:0说明数据根本没进来如果返回count:1000但 Kibana 看不到那就是 Index Pattern 或时间筛选器的问题。实操心得有一次我发现logstash-*索引里有数据但 Kibana 的 Discover 页面始终为空。折腾半天最后发现是 Kibana 的Time Filter被我无意中设成了Last 15 minutes而日志是昨天产生的。我把时间筛选器改成Last 24 hours数据瞬间就出来了。这个坑我踩了三次每次都花半小时才想起来。5.4 性能瓶颈预警kibana显示 es 写入延时