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

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

1. 项目概述:为什么在 Ubuntu 14.04 上搭建 Logstash + Kibana 日志中枢依然值得深挖

Logstash 和 Kibana 这对组合,哪怕放在今天看,依然是日志处理领域最扎实、最经得起推敲的“老派功夫”。很多人一看到标题里写着 Ubuntu 14.04,第一反应是“太老了,早就该淘汰”,但恰恰是这个看似过时的环境,反而成了理解 ELK 栈底层逻辑的绝佳沙盒。Ubuntu 14.04(Trusty Tahr)发布于 2014 年 4 月,其系统内核、OpenSSL 版本、Java 运行时环境(当时主流是 Java 7/8)、systemd 与 upstart 的过渡状态,全都构成了一个边界清晰、行为可预测的运行基底。它不像现代发行版那样被层层抽象和自动更新裹挟,你改一行配置、启一个服务、查一个端口,每一步反馈都直接、诚实、不藏掖——这对刚上手日志架构的人来说,反而是种保护。

我最早在客户现场部署 ELK 时,用的就是三台 Ubuntu 14.04 虚拟机:一台跑 Elasticsearch(1.7.x),一台跑 Logstash(1.5.x),一台跑 Kibana(4.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 轻量、资源占用低,适合做边缘采集 agent;Fluentd 插件生态丰富,尤其在 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 日志原样扔进 ES,Filebeat 完全够用;但如果你需要把不同来源、不同格式的日志统一打标、清洗、丰富字段(比如根据 client_ip 查 GeoIP 信息,或根据 user_agent 解析浏览器类型),Logstash 就是不可替代的。

2.2 为什么是 Kibana 4.x,而不是 Kibana 5+ 或 OpenSearch Dashboards?

Kibana 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 年了,为什么还要折腾一个 EOL(End of Life)的系统?”答案很简单:稳定性和确定性。Ubuntu 14.04 的 LTS(Long 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,第一步永远不是下载软件,而是确保系统底座干净、可靠。我习惯先执行以下四步标准化操作:

  1. 系统更新与内核加固

    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 的基础)。

  2. 安装 Oracle Java 8(非 OpenJDK)
    Logstash 1.5.x 对 Java 的兼容性有明确要求,官方文档明确推荐使用 Oracle JDK 8(u40-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 的许可协议,避免安装过程卡在交互式提示上。这是我在批量部署几十台服务器时总结出的必填项。

  3. 创建专用用户与目录结构
    绝对不要用 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管理日志轮转。

  4. 配置系统级参数
    Elasticsearch 和 Logstash 都是内存大户,必须调整系统限制:

    # 编辑 /etc/security/limits.conf,追加以下两行 elk soft nofile 65536 elk hard nofile 65536 # 编辑 /etc/sysctl.conf,追加以下两行 vm.max_map_count=262144 fs.file-max=65536 sudo sysctl -p

    vm.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 系列最后一个稳定版。

  1. 下载与解压

    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-components=1 sudo chown -R elk:elk /opt/elk/elasticsearch
  2. 核心配置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 -l,ES 启动时会在日志里反复打印Failed to set mlockall的警告,最终导致频繁 GC 和查询超时。

  3. 启动与验证
    切换到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 是整个流程的“心脏”,它的配置质量直接决定了日志的可用性。

  1. 下载与安装

    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-components=1 sudo chown -R elk:elk /opt/elk/logstash
  2. 编写核心 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:56Dec 5 12:34:56(注意空格数不同)两种格式,这是 Ubuntu syslog 的实际行为。如果写成硬编码的\w{3} \s+\d{1,2} \d{2}:\d{2}:\d{2},就会在日期为个位数(如 Dec 5)时匹配失败,导致整条日志被丢弃。

  3. 启动 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?pretty&q=message:test'查询,应该能看到这条日志已被索引。

3.4 Kibana 4.6.6 的安装与前端配置

Kibana 是用户与日志数据之间的最后一道桥梁,它的配置直接影响使用体验。

  1. 下载与解压

    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-components=1 sudo chown -R elk:elk /opt/elk/kibana
  2. 核心配置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 的读写权限拱手相让。

  3. 启动 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/kibana

    server { 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 hourLast 24 hours,甚至自定义Absolute时间范围。更高级的用法是:在搜索框中直接输入时间范围,如@timestamp >= "2023-12-10T12:00:00Z" AND @timestamp <= "2023-12-10T13:00:00Z"。这对于复盘某个具体故障窗口非常有用。

  • 字段折叠与展开
    默认情况下,每条日志只显示@timestamphostnameprogramlog_message等几个关键字段。点击右侧的> Add fields,可以勾选pidseverity等更多字段,让单条日志信息更完整。反之,如果日志量巨大,勾选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 页面就是把日志变成图表的魔法工坊。

  1. 创建一个“每分钟 Nginx 500 错误数”折线图

    • 选择Line chart
    • Metrics->Y-Axis:Aggregation 选Count(统计日志条数)。
    • Buckets->X-Axis:Aggregation 选Date Histogram,Field 选@timestamp,Interval 选Minute
    • Filters:添加一个过滤器program: "nginx"status: 500
    • 点击Apply changes,图表立即生成。你会看到一条随时间波动的曲线,峰值处就是服务异常的时刻。
  2. 创建一个“Top 10 访问 IP”饼图

    • 选择Pie chart
    • Metrics->Slice size:Aggregation 选Count
    • Buckets->Split Slices:Aggregation 选Terms,Field 选client_ip,Size 设为10
    • 点击Apply changes,一个清晰的饼图就出来了。如果发现某个 IP 占比异常高(比如超过 30%),基本可以判定是爬虫或攻击。
  3. 将多个图表组合成 Dashboard
    点击左侧Dashboard,然后Add,选择刚才创建的两个图表,拖拽到画布上。你可以调整它们的大小、位置,甚至添加文本注释(Add element->Text)来说明每个图表的业务含义。最终,一个包含“错误趋势”、“流量分布”、“响应时间 P95”等核心指标的实时监控面板就完成了。这个面板可以全屏展示在运维大屏上,也可以嵌入到公司内部 Wiki 中,成为团队共享的“业务健康看板”。

5. 常见问题排查与独家避坑指南:那些文档里不会写的血泪教训

5.1 Logstash 启动失败:FATAL Logstash::Errorjava.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_SIZE=1g,它会覆盖jvm.options的设置。删掉这行,问题迎刃而解。这个文件的存在,是很多教程里不会提及的“隐藏开关”。

5.2 Kibana 页面空白或报错Kibana did not load properly:CORS 与 Network Host 的双重陷阱

当 Kibana 页面打开后一片空白,或者弹出Kibana did not load properly的红色提示,90% 的情况是前端 JavaScript 无法连接到 Elasticsearch。

  • 排查步骤

    1. 打开浏览器开发者工具(F12),切换到Console标签页,刷新页面。如果看到Failed to load resource: the server responded with a status of 401 (Unauthorized)net::ERR_CONNECTION_REFUSED,说明连接 ES 失败。
    2. Network标签页,找到api/status这个请求,点击它,看ResponsePreview里返回了什么。如果是{"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页面里一条日志都看不到。

  • 系统性排查清单
    1. 检查 Logstash 输入源tail -f /var/log/syslog,确认日志文件确实在实时写入。如果syslog文件是空的,那当然不会有数据。
    2. 检查 Logstash 的sincedb文件cat /var/lib/logstash/sincedb_syslog。这个文件记录了 Logstash 最后读到文件的字节偏移量。如果它的值是0,说明 Logstash 从头开始读,但可能因为start_position => "end"而跳过了所有历史日志。临时解决:echo "0:0:0" > /var/lib/logstash/sincedb_syslog,然后重启 Logstash。
    3. 检查 Logstash 的stdout输出:在01-syslog.confoutput里保留stdout { codec => rubydebug },然后tail -f /var/log/elk/logstash/logstash.log。如果日志里有Ruby exception occurredGrok parsing failed,说明filter阶段出了问题,日志被丢弃了。此时,把filter块暂时注释掉,只留inputoutput,看数据能否进 ES。如果能,问题就出在grok表达式上。
    4. 检查 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 写入延时