ELK企业日志分析系统

作者@小郭

ELK企业日志分析系统

一、工作原理

日志/数据源 → Logstash(收集、处理) → Elasticsearch(存储、索引、搜索) → Kibana(可视 化、分析)

Logstash:服务器端数据处理管道

核心角色:搬运工和预处理车间 - 负责收集、解析、转换和输送数据。

作用:

Logstash 的工作流程被划分为三个阶段:Input → Filter → Output。

1.Input(输入):数据收集

  • 从各种来源实时地收集数据和日志。它拥有大量的插件,支持极其丰富的输入源,例如:

1.文件(如 *.log )

2.系统日志(Syslog)

3.监控数据(如 Beats、JMX)

4.消息队列(如 Kafka, Redis, RabbitMQ)

5.数据库(如 MySQL)

2.Filter(过滤):数据解析与 enrichment

  • 这是 Logstash 最强大的部分。原始日志(比如一行文本)通常是非结构化的,Filter 插件将其 解析成结构化的、有意义的字段,以便于在 Elasticsearch 中高效查询。常见操作包括:

​ **1.Grok:**使用正则模式匹配来解析复杂的文本行。

​ 例如,从日志127.0.0.1 - - [10/Oct/2023:14:16:39 +0000] \"GET / HTTP/1.1\" 200 3574 中解析出 client_ip , timestamp , http_method , response_code 等字段。

​ **2.Mutate:**对字段进行修改,如重命名、删除、替换、转换数据类型。

​ **3.Date:**解析时间戳,并设置为事件的正式 @timestamp 字段。

​ **4.GeoIP:**根据 IP 地址查询出对应的国家、城市和经纬度信息,极大地丰富了数据维度。

​ **5. KV:**解析 key=value 这样的数据。

3.Output(输出):数据发送

  • 将处理好的数据发送到指定的**目的地。**最常用的输出就是 **Elasticsearch。**但它也支持输出 到:

​ 1.其他数据库(如 MongoDB)

​ 2.消息队列(如 Kafka)

​ 3.文件系统

​ 4.监控系统(如 Nagios)

​ 5.电子邮件等

==注意:==在需要轻量级数据收集的场景下,Elastic 提供了 Beats(如 Filebeat, Metricbeat)来替 代 Logstash 的 Input 功能,它们更轻量、更专一,通常将数据直接发送给 Logstash 做进一步处理或直接发送给 Elasticsearch。

简单总结:Logstash 是一个数据流引擎,负责将杂乱无章的原始数据"加工"成干净、结构化的数据,然 后喂给 Elasticsearch。它是一个重量级工具,功能全面但资源消耗相对较高。

Elasticsearch:分布式搜索和分析引擎

核心角色:大脑和心脏 - 负责海量数据的存储、检索和分析。

作用:

1.分布式存储与高可用性:

  • Elasticsearch 是一个分布式数据库 。数据会被分散存储 across 多个服务器(节点)上。这意 味着它可以处理PB级别的海量数据,并且通过副本(replicas)机制,即使某个硬件发生故 障,数据也不会丢失,服务也不会中断,实现了高可用性。

2.近乎实时的搜索:

  • 这是它最核心的能力。数据从被写入到可以被搜索,只有毫秒级的延迟(约1秒内)。这对于 需要实时监控和告警的场景至关重要。

3.强大的全文搜索引擎:

  • 基于 Apache Lucene 构建,提供了无比强大和灵活的全文搜索功能。它不仅仅是简单的关键 字匹配,还支持:
  1. 模糊搜索:即使拼写错误也能找到结果。
  2. 同义词处理:搜索"手机"也能找到包含"电话"的结果。
  3. 相关性评分:根据多种因素对搜索结果进行排序,将最相关的结果排在前面。

4.先进的索引技术:

  • 数据在存储时会被倒排索引(Inverted Index)。这是一种类似书籍最后"索引"页的技术(例 如,提到"数据库"这个词的页面是 10, 23, 45)。这使得它的查询速度极快,远远优于传统的 逐行扫描数据库。

5.丰富的 RESTful API:

  • 几乎所有操作,如数据的写入、查询、集群管理,都可以通过简单的 HTTP REST API 进行,这 使得它非常容易与其他系统集成和开发。

6.强大的聚合分析能力:

  • 除了搜索,它还能执行复杂的聚合(Aggregation)操作,相当于 SQL 中的 GROUP BY 再加 上很多数学运算。例如:

​ 1."统计过去5分钟内,错误日志的数量并按应用分组?"

​ 2."计算网站访问量的95百分位延迟?"

​ 3."绘制用户地理位置的分布图?"

简单总结:Elasticsearch 是一个专门为"快速查找"而设计的海量数据存储系统。它不擅长频繁更新事务 (像MySQL那样),但极其擅长快速过滤、查询和分析巨量数据。

Kibana:数据可视化与管理平台

核心角色:窗口和仪表盘 - 用于数据的探索、可视化和交互。

作用:

1.数据探索与发现(Discover):

  • 提供一个交互式界面,让你能够直接查询和浏览存储在 Elasticsearch 中的原始数据。你可以 使用搜索框(支持 Lucene 查询语法或 KQL),添加过滤器来动态地缩小数据范围,并查看匹 配文档的详细内容。

2.可视化(Visualize):

  • 提供丰富的可视化组件,让你可以将数据转化为各种直观的图表,包括:

1.柱状图、折线图、饼图

2.指标看板(显示单个数字,如总错误数)

3.数据表(用于聚合数据)

4.坐标地图(与 GeoIP 结合,在地图上显示数据点)

3.仪表盘(Dashboard):

  • 可以将多个可视化组件拖放组合成一个统一的、综合的仪表盘。这对于构建实时监控大屏非常 有用,运维和开发团队可以在一个屏幕上全局掌握系统的健康状态、性能指标和业务趋势。

4.管理和维护:

  • Kibana 还提供了 Stack Management 界面,用于管理和配置整个 ElasticStack,例如:

​ 1.索引生命周期管理(ILM)

​ 2.用户和角色权限控制

​ 3.导入/导出保存的可视化和仪表盘

​ 4.配置 Kibana 本身

简单总结:Kibana 是 ELK Stack 的"面子",它将 Elasticsearch 中深奥的数据以人类易于理解的图形 方式呈现出来,使得任何人都能轻松地进行数据分析和决策,而无需编写复杂的查询代码。

二、案例环境:配置ELK日志分析系统

实验拓扑图:

配置elasticsearch环境

准备主机名,域名,Java环境
bash 复制代码
[root@node1 ~]# vi /etc/hosts
192.168.108.41   node1
192.168.108.42   node2
[root@node2 ~]# vim /etc/hosts
192.168.108.41   node1
192.168.108.42   node2
部署elasticsearch软件
节点node1部署
bash 复制代码
#官网下载elasticsearch rpm包,上传elasticsearch-5.5.0.rpm到/opt目录下
[root@node1 ~]# cd /opt
[root@node1 ~]#wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.0.rpm
[root@node1 opt]# rpm -ivh elasticsearch-5.5.0.rpm

#加载系统服务
[root@node1 ~]# systemctl daemon-reload    
[root@node1 ~]# systemctl enable elasticsearch.service

#更改elasticsearch主配置文件
root@node1 ~]# cp /etc/elasticsearch/elasticsearch.yml 
/etc/elasticsearch/elasticsearch.yml.bak
[root@node1 ~]# vim /etc/elasticsearch/elasticsearch.yml
17 cluster.name: my-elk-cluster                  #集群名字             
23 node.name: node1                              #节点名字             
33 path.data: /data/elk_data                     #数据存放路径          
37 path.logs: /var/log/elasticsearch/            #日志存放路径   
43 bootstrap.memory_lock: false                  # 不在启动时锁定内存:锁定物理内存地址,防止es内存被交换出去,也就是避免es使用swap交换分区,频繁的交换,会导致IOPS变高。  
55 network.host: 0.0.0.0                      #提供服务绑定的IP地址,0.0.0.0代表所有地址        
59 http.port: 9200                                       # 侦听端口为9200                   
68 discovery.zen.ping.unicast.hosts: ["node1", "node2"]  #集群发现通过单播实现

#创建数据存放路径并授权
[root@node1 opt]# mkdir -p /data/elk_data
[root@node1 opt]# chown elasticsearch:elasticsearch /data/elk_data/

#开启服务并验证
[root@node1 opt]# systemctl start elasticsearch.service
[root@node1opt 15:24:27]# netstat -antp |grep 9200
tcp6       0      0 :::9200                 :::*                    LISTEN      53668/java
网页登录查看节点信息:
节点node2部署
bash 复制代码
#官网下载elasticsearch rpm包,上传elasticsearch-5.5.0.rpm到/opt目录下
[root@node2 ~]# cd /opt
[root@node2 opt]# rpm -ivh elasticsearch-5.5.0.rpm 

#加载系统服务
[root@node2 ~]# systemctl daemon-reload
[root@node2 ~]# systemctl enable elasticsearch.service 

#更改elasticsearch主配置文件
[root@node2 ~]# cp /etc/elasticsearch/elasticsearch.yml 
/etc/elasticsearch/elasticsearch.yml.bak
[root@node2 ~]# vim /etc/elasticsearch/elasticsearch.yml
17 cluster.name: my-elk-cluster                   #集群名字
23 node.name: node2                               #节点名字
33 path.data: /data/elk_data                      #数据存放路径
37 path.logs: /var/log/elasticsearch/             #日志存放路径
43 bootstrap.memory_lock: false                   #不在启动的时候锁定内存:锁定物理内存地址,防止es内存被交换出去,也就是避免es使用swap交换分区,频繁的交换,会导致IOPS变高。
55 network.host: 0.0.0.0                          #提供服务绑定的IP地址,0.0.0.0代表所有地址
59 http.port: 9200                                #侦听端口为9200
68 discovery.zen.ping.unicast.hosts: ["node1", "node2"]           #集群发现通过单播实现

#创建数据存放路径并授权
[root@node2 ~]# mkdir -p /data/elk_data
[root@node2 ~]# chown elasticsearch:elasticsearch /data/elk_data/

#开启服务并验证
[root@node2 opt]# systemctl start elasticsearch.service
[root@node2 opt]# netstat -antp |grep 9200
tcp6       0      0 :::9200                 :::*                    LISTEN      53390/java 
网页查看节点信息:
网页界面集群检查健康和状态:
网页界面查看集群信息:
安装elasticsearch-head插件
节点node1部署:
bash 复制代码
#安装依赖包
[root@node1 ~]# yum install gcc gcc-c++ make -y

#官网下载并解压到/opt目录
[root@node1 ~]# cd /opt
[root@localhost opt]# wget https://nodejs.org/dist/v8.2.1/node-v8.2.1.tar.gz
[root@node1 opt]# tar xzvf node-v8.2.1.tar.gz
[root@node1 opt]# cd node-v8.2.1/

#环境检测 + 生成编译规则文件
[root@node1 node-v8.2.1]# ./configure 

#编译源码,生成可执行程序
[root@node1 node-v8.2.1]# make -j4   #等待时间较长

#把编译好的程序安装到系统全局
[root@node1 node-v8.2.1]# make install
安装phantomjs端框架

PhantomJS 是 elasticsearch-head 的依赖组件(无界面浏览器,用于前端渲染 / 测试)

bash 复制代码
#官网下载到指定目录/usr/local/src/
[root@node1opt 15:24:36]# cd /usr/local/src/
[root@node1src 15:25:55]# wget https://npmmirror.com/mirrors/phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2
[root@node1src 15:26:01]# tar xjvf phantomjs-2.1.1-linux-x86_64.tar.bz2 
[root@node1src 15:26:55]# cd phantomjs-2.1.1-linux-x86_64/bin
[root@node1bin 15:26:58]# cp phantomjs /usr/local/bin/
安装elasticsearch-head数据可视化工具
bash 复制代码
#官网下载解压到指定目录
[root@node1bin 15:27:14]# cd /usr/local/src/
[root@node1src 15:28:23]# wget https://github.com/mobz/elasticsearch-head/archive/refs/heads/master.tar.gz -O elasticsearch-head.tar.gz
[root@node1src 15:29:16]# tar xzvf elasticsearch-head.tar.gz 

#安装
#npm 是 Node Package Manager 的缩写,Node.js 的包管理工具),用npm安装插件的所有依赖(package.json定义的依赖)
[root@node1src 15:29:43]# cd elasticsearch-head-master/
[root@node1elasticsearch-head-master 15:29:54]# npm install
......
added 68 packages in 692.34s

#修改主配置文件
[root@node1elasticsearch-head-master 15:45:42]# cd
[root@node1~ 15:47:36]# vim /etc/elasticsearch/elasticsearch.yml
http.cors.enabled: true   ##开启跨域访问支持,默认为false
http.cors.allow-origin: "*"  ## 跨域访问允许的域名地址

#重启服务加载配置
[root@node1~ 15:48:14]# systemctl restart elasticsearch.service 

#启动elasticsearch-head 启动服务器,并在后台运行
[root@node1~ 15:48:23]# cd /usr/local/src/elasticsearch-head-master/
[root@node1elasticsearch-head-master 15:48:38]# npm run start &
[1] 99903

#验证端口是否被监听
[root@node1elasticsearch-head-master 15:49:04]# netstat -lnupt |grep 9100
tcp        0      0 0.0.0.0:9100            0.0.0.0:*               LISTEN      99913/grunt         
[root@node1elasticsearch-head-master 15:49:23]# netstat -lnupt |grep 9200
tcp6       0      0 :::9200                 :::*                    LISTEN      99817/java 
节点node2部署:
bash 复制代码
#安装依赖包
[root@node2 ~]# yum install gcc gcc-c++ make -y

#官网下载并解压到/opt目录
[root@localhost opt]# cd /opt
[root@localhost opt]# wget https://nodejs.org/dist/v8.2.1/node-v8.2.1.tar.gz
[root@node2 opt]# tar xzvf node-v8.2.1.tar.gz

#
[root@node2 opt]# cd node-v8.2.1/
[root@node2 node-v8.2.1]# ./configure 
[root@node2 node-v8.2.1]# make -j4     #等待时间较长
[root@node2 node-v8.2.1]# make install
安装phantomjs端框架
bash 复制代码
[root@node2opt 15:24:05]# cd /usr/local/src/
[root@node2src 15:39:19]# wget https://npmmirror.com/mirrors/phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2
[root@node2src 15:39:27]# tar xjvf phantomjs-2.1.1-linux-x86_64.tar.bz2 
[root@node2src 15:39:57]# cd phantomjs-2.1.1-linux-x86_64/bin/
[root@node2bin 15:40:03]# cp phantomjs /usr/local/bin/
安装elasticsearch-head数据可视化工具
bash 复制代码
#官网下载解压到指定目录
[root@node2bin 15:40:11]# cd /usr/local/src/
[root@node2src 15:40:17]# wget https://github.com/mobz/elasticsearch-head/archive/refs/heads/master.tar.gz -O elasticsearch-head.tar.gz
[root@node2src 15:41:11]# tar xzvf elasticsearch-head.tar.gz

#安装
#npm 是 Node Package Manager 的缩写,Node.js 的包管理工具),用npm安装插件的所有依赖(package.json定义的依赖)
[root@node2src 15:42:43]# cd elasticsearch-head-master/
[root@node2elasticsearch-head-master 15:42:44]# npm install
.......
added 521 packages in 55.825s
[root@node2elasticsearch-head-master 15:43:46]# cd 

#修改主配置文件
[root@node2~ 15:44:52]# vim /etc/elasticsearch/elasticsearch.yml
http.cors.enabled: true   ##开启跨域访问支持,默认为false
http.cors.allow-origin: "*"  ## 跨域访问允许的域名地址

#重启服务加载配置
[root@node2~ 15:46:23]# systemctl restart elasticsearch.service 

#启动elasticsearch-head 启动服务器,并在后台运行
[root@node2~ 15:46:34]# cd /usr/local/src/elasticsearch-head-master/
[root@node2elasticsearch-head-master 15:46:44]# npm run start &
[1] 99561

#验证端口是否被监听
[root@node2elasticsearch-head-master 15:49:29]# netstat -luntp |grep 9100
tcp        0      0 0.0.0.0:9100            0.0.0.0:*               LISTEN      99571/grunt         
[root@node2elasticsearch-head-master 15:49:38]# netstat -luntp |grep 9200
tcp6       0      0 :::9200 
网页验证结果:

node1现象: 打开浏览器输入http://192.168.108.41:9100/ 可以看见集 群健康值:未连接

在Elasticsearch 后面的栏目中输入http://192.168.108.41:9200 然后点连接 会发现: 集群健康值: green (0 of 0)

node2同理。

测试
bash 复制代码
#向 Elasticsearch(本地 9200 端口)手动插入一条文档数据,创建索引 index-demo 并写入一条 id=1 的测试数据。
[root@node1~ 15:51:48]# curl -XPUT 'localhost:9200/index-demo/test/1?pretty&pretty' -H 'content-Type: application/json' -d '{"user":"zhangsan","mesg":"hello world"}'
{
  "_index" : "index-demo",
  "_type" : "test",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "created" : true
}

打开浏览器输入http://192.168100.41:9100/ 查看索引信息,概览信息以及数据浏览。如下图所示:

概览信息中:

可以看见索引默认被分片5个,并且有一个副本 node1信息动作 01234 node2信息动作 01234 node1和node2是平等关系,不是主从关系

数据浏览中:

会发现在node1上创建的索引为index-demo,类型为test, 相关的信息。

部署logstash

用作日志搜集输出到elasticsearch中

安装Apahce服务
bash 复制代码
#安装Apahce服务
[root@apache~ 11:40:10]# yum install -y httpd
[root@apache~ 11:40:12]# systemctl start httpd

#访问下日志
# access_log   访问日志
# error_log   错误日志 
[root@apache~ 11:40:15]#  cd /var/log/httpd/
[root@apache~ 11:40:16]#  ls
access_log error_log
安装logstash
bash 复制代码
#官网下载安装logstash到指定目录/opt下
[root@apache ~]# cd /opt
[root@apache ~]# wget https://artifacts.elastic.co/downloads/logstash/logstash-5.5.1.rpm
[root@apache opt]# rpm -ivh logstash-5.5.1.rpm           

#启动logstash
[root@apache opt]# systemctl start logstash.service       
[root@apache opt]# systemctl enable logstash.service

#建立logstash软连接
[root@apache opt]# ln -s /usr/share/logstash/bin/logstash /usr/local/bin/ 
对接测试

logstash(apache节点)与elasticsearch(node节点)做对接测试

字段描述解释:

● -f 通过这个选项可以指定logstash的配置文件,根据配置文件配置logstash。示例:logstash -f apache_log.conf

● -e 后面跟着字符串 该字符串可以被当做logstash的配置(如果是" ",则默认使用stdin做为输入、 stdout作为输出)

● -t 测试配置文件是否正确,然后退出。示例:logstash -t -f apache_log.conf

bash 复制代码
#方式一:标准控制台输出
[root@apache ~]# logstash -e 'input { stdin{} } output { stdout{} }'
......
15:04:01.581 [Api Webserver] INFO logstash.agent - Successfully started Logstash 
API endpoint {:port=>9600}
www.baidu.com                                     #需要输入www.baidu.com
2025-12-12T07:05:01.001Z apache www.baidu.com
www.sina.com.cn                                   #需要输入www.sina.com.cn
2025-12-12T07:05:08.375Z apache www.sina.com.cn                   #ctrl_c退出
.....

#方式二:结构化格式化输出(rubydebug)
[root@apache ~]# logstash -e 'input { stdin{} } output { stdout{ codec=>rubydebug } }'
......
15:08:06.670 [Api Webserver] INFO logstash.agent - Successfully started Logstash 
API endpoint {:port=>9600}
www.baidu.com                               #需要输入www.baidu.com
{
    "@timestamp" => 2025-12-12T07:08:43.174Z,
      "@version" => "1",
          "host" => "apache",
       "message" => "www.baidu.com"
}                                                  #ctrl_c退出

#方式三:直接输出至 Elasticsearch
[root@apache ~]# logstash -e 'input { stdin{} } output { elasticsearch { hosts=>
["192.168.108.41:9200"] } }'
 ......
The stdin plugin is now waiting for input:
15:14:21.757 [Api Webserver] INFO logstash.agent - Successfully started Logstash 
API endpoint {:port=>9600}
www.baidu.com                      #输入内容
www.360.cn                         #输入内容
www.qq.com                         #输入内容
# ctrl_c退出
网页登录验证:
配置 Logstash 采集系统日志存入 Elasticsearch
bash 复制代码
#赋予日志文件读取权限,并查看确认
[root@apache ~]# chmod o+r /var/log/messages 
[root@apache ~]# ll /var/log/messages 
-rw----r--. 1 root root 856951 Dec 12 15:51 /var/log/messages

#编辑 logstash 采集管道配置文件:
[root@apache opt]# vim /etc/logstash/conf.d/system.conf 
input {
       file{
       path => "/var/log/messages"
       type => "system"
       start_position => "beginning"
       }
     }
output {
       elasticsearch {
         hosts => ["192.168.108.41:9200"]
         index => "system-%{+YYYY.MM.dd}"
         }
       }

#重启服务生效配置
[root@apache opt]# systemctl restart logstash.service
网页登录查看

会发现信息不够直观所以安装kibana,使数据可视化。

安装Kibana

node1节点安装
bash 复制代码
#官网下载到指定目录
[root@node1~ 16:23:34]# cd /usr/local/src/
[root@node1src 16:23:42]# wget https://artifacts.elastic.co/downloads/kibana/kibana-5.5.1-x86_64.rpm
[root@node1src 16:23:56]# rpm -ivh kibana-5.5.1-x86_64.rpm

#修改配置文件
[root@node1src 16:24:26]# cd /etc/kibana/
[root@node1kibana 16:24:52]# cp kibana.yml kibana.yml.bak
[root@node1kibana 16:25:04]# vim kibana.yml
2 server.port: 5601                                            # kibana打开的端口
7 server.host: "0.0.0.0"                                       #kibana侦听的地址
21 elasticsearch.url: "http://192.168.108.41:9200"             #和elasticsearch建立联系
30 kibana.index: ".kibana"                                     #在elasticsearch中添加.kibana索引

#重启服务
[root@node1kibana 16:26:06]# systemctl start kibana.service 
[root@node1kibana 16:26:14]# systemctl enable kibana.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kibana.service to /etc/systemd/system/kibana.service.

注意:这里的system-*中的system对应elssticsearch中的概览中的名字。

首次登录创建一个索引 名字:system-* (这是对接系统日志文件) 然后点最下面的出面的create 按钮创建

然后点下面的host旁边的add

会发现右面的图只有 Time 和host 选项了 这个比较友好

对接Apache主机的Apache 日志文件(访问的、错误的)
bash 复制代码
[root@apache~ 20:33:21]# cd /etc/logstash/conf.d/
[root@apacheconf.d 20:33:39]# ls
system.conf
[root@apacheconf.d 20:33:45]# touch apache_log.conf
[root@apacheconf.d 20:33:54]# vim apache_log.conf 

#编辑采集逻辑。
[root@apacheconf.d 20:34:24]# cat apache_log.conf 
input {
  file {
    path => "/var/log/httpd/access_log"
    type => "access"
    start_position => "beginning"
  }
  file {
    path => "/var/log/httpd/error_log"
    type => "error"
    start_position => "beginning"
  }
}

output {
  if [type] == "access" {
    elasticsearch {
      hosts => ["192.168.108.41:9200"]
      index => "apache_access-%{+YYYY.MM.dd}"
    }
  }
  if [type] == "error" {
    elasticsearch {
      hosts => ["192.168.108.41:9200"]
      index => "apache_error-%{+YYYY.MM.dd}"
    }
  }
}

#前台单独加载 apache 采集配置运行,实时打印采集日志,用于测试配置是否正常、能否读取日志并推送 ES。
[root@apacheconf.d 20:51:47]# /usr/share/logstash/bin/logstash -f apache_log.conf

[root@apache~ 20:49:56]# echo hello world > /var/www/html/index.html

网页界面会出现对应的网页内容。

网页界面会出现对应的索引信息:apache_error-* apache_access-*

在management选项--->index patterns--->create index pattern

分别创建apache_access-* 和 apache_error-* 的索引 即可

观察他们的日志: