写在前面
由于公司项目较多,所部署服务产生的日志也较多,以往查看服务器日志只能通过xshell、putty等SSH工具分别连接每台服务器,然后进入到各个服务器,执行Linux命令查看日志,这样可能会带来以下问题:
- 类似xshell等工具需要购买或破解才能长期使用
- 若服务器无法直连、需要跳板机跳转的情况下,连接多台服务器需要在xshell工具配置代理,配置过程较为繁琐
- 若居家办公或在家中临时定位紧急bug,同样需要安装工具和配置一套代理用于连接到服务器查看日志
- 不同的服务部署在不同的服务器上,需要在Xshell等工具上打开多个窗口来回切换查看
- 查看日志需要会一些的常用的Linux命令
刚好前段时间学习和研究过ELK日志分析系统的相关知识,不仅可以用来分析Nginx、Apache、MySQL等工具和服务的日志,还可以用于分析Springboot项目生成的服务日志,另外结合Metricbeat工具也可以用来监控服务器内存、CPU、磁盘等相关指标。于是在公司测试环境的服务器上尝试搭建了一套ELK,探索能否解决以上日志查看面临的痛点问题。
在正式开始前,先简单介绍一下本篇文章大纲:
- 什么是ELK
- ELK收集Springboot日志的实现原理
- 部署方案介绍
- Elasticsearch、Logstash、Kibana、Filebeat的部署过程,创建索引
- Kibana日志面板使用
一、什么是ELK
ELK 是elastic公司提供的一套完整的日志收集、展示解决方案,是三个产品的首字母缩写,分别是ElasticSearch、Logstash 和 Kibana:
- ElasticSearch简称ES,由Java 语言编写,它是一个建立在全文搜索引擎Apache Lucene基础上的、实时的、分布式的搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析;
- Logstash是一个具有实时传输能力的数据收集引擎,用来进行数据收集(如:读取文本文件)、解析,并将数据发送给ES;
- Kibana为Elasticsearch提供了分析和可视化的Web平台。它可以在Elasticsearch的索引中查找,交互数据,并生成各种维度表格、图形;
在ELK中beats是用于数据采集的工具,相较于logstash,beats是更轻量级的工具。Beats 平台集合了多种单一用途数据采集器,这些采集器安装后可用作轻量型代理,从成百上千或成千上万台机器向 Logstash 或 Elasticsearch 发送数据。Beats平台提供了如下的几种常见的具体收集日志的工具:
工具名称 | 对应解释 |
---|---|
Filebeat | 日志文件 |
Metricbeat | 指标 |
Packetbeat | 网络数据 |
Winlogbeat | windows事件日志 |
Auditbeat | 审计数据 |
Heartbeat | 运行心跳监控 |
二、ELK收集Springboot项目日志的实现原理
Springboot服务产生的日志,会将日志数据保存到磁盘中的.log文件中,因此需要在各个服务所在的服务器上分别部署轻量级的日志收集工具filebeat,实现原理如下:
- filebeat:部署在需要采集日志的各个服务器上,负责监听log文件,Filebeat会将日志数据收集并结构化后传输到Logstash上;
- Logstash:负责将日志进行过滤、收集,再传输到Elasticsearch上;
- Elasticsearch:负责把日志作为索引进行存储并且构造对应倒排索引;
- Kibana:负责可视化呈现日志,需要查询时Kibana调用Elasticsearch进行日志数据的查询;
当然,也可以直接将日志传输给ES,但是会面临以下弊端:
- 当需要收集的节点较多时,传输的log量和次数就会大量增加,如果filebeat直接传输给es,就会占用掉es的大量资源。应该让es专注于数据查询和处理,让数据发给logstash,以此作一层缓冲;
- logstash有多种过滤器可以使用,通过logstash做一些过滤,可以过滤掉无效的日志;
三、部署方案
注意事项:
- Elasticsearch、Logstash、Kibana、Filebeat 版本需保持一致
- ELK需部署在和被监控的服务同一套内网环境下
- 若部署在云服务上,需在云服务器所在的安全组设置中,将ELK各个组件所用到的端口号一一放开
- 如有防火墙,需将ELK各个组件所用到的端口号一一加到防火墙安全策略中
服务器 | 服务 | 默认端口号 | 作用 | 备注 |
---|---|---|---|---|
192.168.16.21 | Elasticsearch | 9200 | 日志存储、日志查询、日志解析 | |
192.168.16.22 | Logstash | 5044 | 日志收集、日志过滤 | |
192.168.16.4(外网地址:xx.xxx.xx.xx) | Kibana | 5601 | 可视化展示 | 如需外网访问,Kibana需部署在外网可以访问的服务器上 |
192.168.16.6192.168.16.11...... | Filebeat | 日志收集 | 各个需要采集日志的服务器上都部署 |
四、部署过程
1.安装elasticsearch
1)创建elk用户
elasticsearch无法在root用户下运行,因此需要创建一个新用户
代码语言:javascript复制useradd elk
passwd elk
2)更改elasticsearch目录所属用户
代码语言:javascript复制chown -R elk:elk elasticsearch-7.8.0 # -R 参数表示递归子目录
3)配置elasticsearch
编辑config目录下的配置文件:vi elasticsearch.yml
代码语言:javascript复制# 按照如下内容放开注释或修改
cluster.name: my-application
node.name: node-1
path.data: /home/ELK/elasticsearch-7.8.0/data
path.logs: /home/ELK/elasticsearch-7.8.0/logs
bootstrap.memory_lock: false
network.host: 192.168.16.21
http.port: 9200
# 末尾增加两行内容,否则会报错
bootstrap.system_call_filter: false
cluster.initial_master_nodes: ["node-1"]
4)常见报错及解决
- vm.max_map_count 数量太小
报错如上图所示,解决办法:
① 切换到root用户,修改配置文件sysctl.conf:vi /etc/sysctl.conf,在末尾行添加内容:
代码语言:javascript复制vm.max_map_count=262144
② 保存后执行命令:sysctl -p,使配置生效
- bootstrap checks failed 问题
报错如上图所示,解决办法:
①切换到root用户,修改配置文件limits.conf:vi /etc/security/limits.conf,在末尾行添加内容:
代码语言:javascript复制* soft nofile 65536
* hard nofile 131072
② 再次启动后,浏览器访问:http://ip:9200/ 出现以下页面返回则表示启动成功
- 启动时报错提示“org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: failed to obtain node locks”
原因:(重复启动)线程被占用,已存在es线程,且正在运行中
- 通过启动脚本启动后不加载任何模块
如上图所示,脚本启动后只有如上提示,不加载任何模块,解决办法:
① 再次新建一个用户,如elastic:useradd elastic
② 将elasticsearch-7.8.0更改属组:chown -R elastic:elastic elasticsearch-7.8.0
③ 切换至elastic用户:su elastic
④ 启动elasticsearch
5)配置脚本启动方式
① 确认启动无问题后,先暂时Ctrl c关闭服务,创建后台启动脚本:startup.sh,内容如下:
代码语言:javascript复制/home/ELK/elasticsearch-7.8.0/bin/elasticsearch -d # -d 参数为后台启动
② 赋予startup.sh执行权限:chmod x startup.sh
2.安装logstash
logstash可以用root用户运行,logstash也是需要在jdk1.8以上版本运行,所以可以不用像elasticsearch那样必须用新建一个elk用户
① 将logstash-7.8.0.tar.gz通过xftp等工具复制到指定服务器
② 解压logstash-7.8.0.tar.gz:tar -xvf logstash-7.8.0.tar.gz
③ 创建启动脚本:startup.sh,内容如下:
代码语言:javascript复制nohup /home/ELK/logstash-7.8.0/bin/logstash -f config.conf >/dev/null 2>&1 &
④ 赋予脚本执行权限:chmod x startup.sh
⑤ 通过脚本启动:./startup.sh
出现如下图所示提示,表示启动成功:
3.安装Kibana
1)修改配置文件kibana.yml
代码语言:javascript复制server.port: 5601
server.host: "192.168.16.4"
elasticsearch.hosts: ["http://192.168.16.21:9200"]
kibana.index: ".kibana"
i18n.locale: "zh-CN"
2)创建启动脚本startup.sh
startup.sh内容如下,注意事项:
① 一定要加 --allow-root参数,允许root用户允许,否则会报错
② 创建完赋予用户执行权限:chmod u x startup.sh
代码语言:javascript复制# startup.sh
nohup /home/ELK/kibana-7.8.0/bin/kibana --allow-root
3)启动kibana
使用./startup.sh启动
4)浏览器访问
http://ip:5601
5.部署并配置Filebeat
① 将filebeat-7.8.0-linux-x86_64.tar.gz文件复制到需要采集日志的各个服务器上
② 解压缩文件:tar -xvf filebeat-7.8.0-linux-x86_64.tar.gz
③ 进入解压后的目录,编辑filebeat.yml,内容如下
代码语言:javascript复制# ============================== Filebeat inputs ===============================
filebeat.inputs:
# ==========RS log==========
# 定义要采集项目的log标签,如rs项目debug类型的日志,标签可以设为:rs_debug,并声明log路径
- type: log
enabled: true
tags: ["rs_debug"]
paths:
- /home/rs/logs/debug.log
# 采集同一台服务器上的多个服务,使用 - 进行分隔,如mn项目的error类型的日志
- type: log
enabled: true
tags: ["mn_error"]
paths:
- /home/mn/logs/error.log
# ============================== Filebeat modules ==============================
filebeat.config.modules:
# Glob pattern for configuration loading
path: ${path.config}/modules.d/*.yml
# Set to true to enable config reloading
reload.enabled: false
# ======================= Elasticsearch template setting =======================
setup.template.settings:
index.number_of_shards: 1
index.number_of_replicas: 0
# Kibana 配置,Kibana所在服务器的内网地址
setup.kibana:
host: "192.168.16.4:5601"
# ================================== Outputs ===================================
# Logstash Output 注意:Logstash和Elasticsearch选择一个作为日志输出即可,不能同时选择
output.logstash:
hosts: ["192.168.16.22:5044"]
# Processors 配置,保持默认
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
6.配置Logstash
新建一个config.conf文件,主要逻辑:先从logstash中检索日志是否存在指定的标签名(前面在Filebeat中定义的标签名,与此处对应),若存在,则将日志进行重新命名再传递给下一个环节ES
具体内容如下:
代码语言:javascript复制input {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}"}
}
geoip {
source => "clientip"
}
}
output {
if "rs_debug" in [tags] {
elasticsearch {
hosts => [ "192.168.16.21:9200" ]
index => "[test_rs_debug_log]"
}
}
if "mn_error" in [tags] {
elasticsearch {
hosts => [ "192.168.16.21:9200" ]
index => "[mn_error_log]"
}
}
}
7.Kibana中创建索引
① 打开索引模式
左上角菜单--Management--Stack Management--Kibana--索引模式
② 输入索引名称,匹配具体日志
输入具体的名称后,可以匹配到某个日志,注意:输入的名称需与中括号及中括号内的内容完全匹配,“下一步”按钮才能被点亮,否则无法进入下一步,后半部分日期部分可以不用输入
③ 配置索引
选择一个时间字段,如果日志数据中本身没有,可以使用@timestamp
④ 进入日志面板
左上角菜单-Kibana-Discover,进入Kibana日志面板
五、Kibana日志面板使用
左上角菜单--Kibana--Discover,日志面板中:
- 可以切换索引来查看不同服务的日志
- 可以根据时间段筛选日志
- 可以自定义日志列表字段
- 可以通过Kibana特有的KSQL检索日志
1.定制列表字段
默认的日志中有大量字段信息是冗余的,可以通过左侧添加message字段来进行过滤
2.KSQL语句筛选
语法:
- 冒号表示 等于
- 冒号 星号表示任意匹配
- and表示两个参数必须同时满足
- or表示一个或多个参数满足一个即可
例如:我想筛选指定时间段内的冒烟测试执行的相关接口日志,那么就可以通过【message: * 冒烟测试】来进行筛选:
3.切换项目日志
点开索引列表,在列表中手动切换索引即可查看对应项目的日志:
六、ELK日志监控平台优缺点分析
优点:
- 同时监控多套环境、多个项目的日志:由于我们的测试环境和开发环境内网在同一个网段下,因此我基于多个(dev test)环境创建了多个项目的索引,以dev、test开头作为索引的名称,以此区分环境类型,在索引列表中可手动切换索引查看对应项目的日志,无需像往常一样登录多台服务器、打开多个窗口;
- 不占用服务器资源:Elasticsearch、Logstash、Kibana分别部署在多台服务器上,Filebeat仅部署在需要采集日志的服务器上,它们彼此通过内外相互联通,因此并不会集中占用内存、CPU等资源;
- 外网访问,通过浏览器即可随时随地访问,无需任何工具:另由于Kibana所在的服务器可以通过外网IP访问,因此,即使回到家中,也能通过浏览器实时访问到各个环境下各个项目的日志信息;
缺点:
- 搭建过程较为繁琐:Elasticsearch、Logstash、Kibana、Filebeat等多个服务需要分别部署,在此过程中可能遇到各种问题;
- 日志访问有延时:由于日志的收集、过滤、解析需要一定的时间,因此,当发起请求后,并不能像命令行或浏览器的F12工具一样,在ELK实时看到响应日志信息,会带有5-10s左右的延时;
七、小结
- ELK是一套完整的日志收集、展示解决方案,由ElasticSearch、Logstash 和 Kibana三个单词首字母拼接而成。其中:Logstash负责将日志进行过滤、收集,再传输到Elasticsearch上;Elasticsearch负责把日志作为索引进行存储并且构造对应倒排索引;Kibana负责可视化呈现日志,需要查询时Kibana调用Elasticsearch进行日志数据的查询;
- ELK Filebeat可用于Springboot及微服务日志的监控,Filebeat部署在需要采集日志的各个服务器上,负责监听指定log文件;
- Kibana日志面板创建索引后能够监控和分析指定服务的指定日志文件;
- Linux常用命令是一切服务部署的基础,本次用到的命令有:cp(复制)、tar(解压文件)、chown(改变文件属组)、chmod(更改文件权限)、vim命令(插入模式、命令模式、末行模式之间的来回切换,快捷操作)、nohup(不挂起运行)......
- 本篇内容仅列举了ELK日志监控的相关内容,其实ELK的用途远不止这些,它还可以用来监控服务器内存、CPU、磁盘、MySQL数据库、Nginx、RabbitMQ中间件,添加可视化报表等,感兴趣的可自行研究;