简单的ELK部署学习
1. 需求
我们公司现在使用的是ELK日志跟踪,在出现问题的时候,我们可以快速定为到问题,并且可以对日志进行分类检索,比如对服务名称,ip , 级别等信息进行分类检索。此文章为本人学习了解我们公司的整体服务架构整理的文档,方便日后学习与复习。部分内容本人以前博文已经有所提及,此处则不再详细赘述了,简单记录一下。
2. 整体架构
我本次建立的主要是进行测试学习使用,所以大部分服务都是单体架构,只有kafka以及zookeeper为集群服务。本次本地部署也参考了公司的架构,我简单的整理了一下公司的架构图,公司简略架构图如下所示:
我们测试环境系统,简单配置架构图如下,我们服务都使用单体项目:
3. 本地部署步骤
本地部署相对简单,仅仅是测试使用,具体部署的应用以及各种中间件整理如下:
- 准备运行的spring boot jar包[
配置好日志格式
],启动服务生成日志文件 - 准备服务需要启动运行的环境,包含redis以及mysql服务
- 安装kafka以及zookeeper集群启动
- 安装配置filebeat,采集日志文件,并且作为生产者生产日志消息
- 安装ES环境,测试我们使用单点服务即可
- 安装logstash,作为消费者消费kafka日志消息,并且过滤日志信息,发送到ES进行存储
- 配置kibana服务,进行可视化页面配置,提供可视化操作页面
我具体的服务器安装软件配置信息如下:
服务器ip | 配置 | hostname | 安装服务信息 |
---|---|---|---|
192.168.138.129 | 8c 16G | docker1 | jdk1.8,kafka_2.12-2.4.1,apache-zookeeper-3.5.8,cerebro-0.9.4,elasticsearch-7.13.4,filebeat-6.6.0-linux-x86_64,logstash-6.6.0,spring boot jar |
192.168.138.130 | 2c 4G | docker2 | jdk1.8,kafka_2.12-2.4.1,apache-zookeeper-3.5.8 |
192.168.138.131 | 2c 4G | docker3 | jdk1.8,kafka_2.12-2.4.1,apache-zookeeper-3.5.8 |
192.168.138.133 | 2c 4G | docker5 | jdk11, kibana-7.13.1-linux-x86_64 |
3.1 准备运行的jar
我们的jar包非常简单,就是一个标准的spring boot程序jar包,我使用了一个我的测试服务包,此处为包地址进行测试,里面已经配置好了log4j2的日志文件,具体配置信息可以参考我的另一篇日志配置博文。
日志配置文件内容信息参考人如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration schema="Log4J-V2.0.xsd" monitorInterval="600">
<Properties>
<!-- 日志生成目录 -->
<Property name="LOG_HOME">logs</Property>
<!-- 日志生系统名称 -->
<property name="FILE_NAME">docker-hello</property>
<!-- elk日志展示 -->
<property name="patternLayout">[%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZ}] [%level{length=5}] [%traceId] [%logger] [${sys:hostName}] [${sys:ip}] [${sys:applicationName}] [%F,%L,%C,%M] [%m] ## '%ex'%n</property>
</Properties>
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="${patternLayout}"/>
<!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Console>
<!-- 文件按照格式要求在固定目录下生成文件 "app-${FILE_NAME}.log" -->
<RollingRandomAccessFile name="appAppender" fileName="${LOG_HOME}/app-${FILE_NAME}.log" filePattern="${LOG_HOME}/app-${FILE_NAME}-%d{yyyy-MM-dd}-%i.log" >
<PatternLayout pattern="${patternLayout}" />
<Policies>
<!--
根据当前filePattern配置"%d{yyyy-MM-dd}",每interval天滚动一次
"%d{yyyy-MM-dd HH-mm}" 则为每interval分钟滚动一次
-->
<TimeBasedTriggeringPolicy interval="1"/>
<!--日志文件大于500MB 滚动一次-->
<SizeBasedTriggeringPolicy size="500MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖 -->
<DefaultRolloverStrategy max="20"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<!-- 业务相关 异步logger 不影响系统性能 -->
<AsyncLogger name="cn.git.*" level="info" includeLocation="true">
<AppenderRef ref="appAppender"/>
</AsyncLogger>
<root level="info">
<AppenderRef ref="CONSOLE"/>
<Appender-Ref ref="appAppender"/>
</root>
</Loggers>
</Configuration>
将服务上传到我的本地虚拟机docker1
3.2 准备spring boot项目需要环境
项目启动需要mysql以及redis信息,我本地使用docker进行了两个环境的简单部署,测试我就简单使用了单体环境即可,自己可以随意设置或者删除也可以,我的启动脚本如下:
# mysql 启动脚本
docker run --name mysql -e MYSQL_ROOT_PASSWORD=101022 -v /root/mysql/data:/var/lib/mysql -v /root/mysql/log:/var/log/mysql -v /root/mysql/conf:/etc/mysql/conf.d -dp 3306:3306 mysql:5.7
# redis 启动脚本
docker run --name myredis --network host -v /root/redis/redis.conf:/etc/redis/redis.conf -v /root/redis/data:/data -dp 6379:6379 redis:latest redis-server /etc/redis/redis.conf
本地执行启动脚本发现服务已经起来了:
之后在启动spring boot jar包,服务启动脚本如下,执行后可以观察log日志,此日志为项目中的定时任务打印,包含业务日志以及error日志
# 启动脚本
nohup java -jar docker-hello-1.0-SNAPSHOT.jar >> app-server.log 2>&1 &
# 观察日志脚本
tail -f app-server.log
服务生成日志path路径地址:
3.3 安装kafka以及zookeeper集群
kafka与zookeeper作为ELK的日志传输中间件,需要进行部署使用,具体的操作步骤可以参考此篇文档,此处便不多赘述了。
3.4 安装配置filebeat
首先我们需要有filebeat安装包,如果没有则去官网下载即可,我本地有一个远古包,就直接使用了,不去官网下载了。上传并且解压包,然后配置filebeat.yml配置文件
tar -zxvf filebeat-6.6.0-linux-x86_64.tar.gz
cd filebeat-6.6.0-linux-x86_64
vim filebeat.yml
配置文件内容如下:
###################### Filebeat Configuration Example #########################
filebeat.prospectors:
- input_type: log
paths:
## app-服务名称.log, 为什么写死,防止发生轮转抓取历史数据,此路径位置也是我们jar包生成日志文件位置
- /usr/local/soft/springboot_jar/logs/app-docker-hello.log
#定义写入 ES 时的 _type 值
document_type: "app-log"
multiline:
pattern: '^\s*(\d{4}|\d{2})\-(\d{2}|[a-zA-Z]{3})\-(\d{2}|\d{4})' # 指定匹配的表达式(匹配以 2017-11-15 08:04:23:889 时间格式开头的字符串)
pattern: '^\[' # 指定匹配的表达式(匹配以 "{ 开头的字符串)
negate: true # 是否匹配到
match: after # 合并到上一行的末尾
max_lines: 2000 # 最大的行数
timeout: 2s # 如果在规定时间没有新的日志事件就不等待后面的日志
fields:
logbiz: collector ## 自定义字段 区分业务类型
logtopic: app-log-docker-hello-collector ## 按服务划分用作kafka topic,会在logstash filter 过滤数据时候作为 判断参数 [fields][logtopic]
evn: dev
logging.to_files: true
# 输出到控制台
output.console:
pretty: true
enable: true
# 启用 Kafka 输出模块
output.kafka:
enabled: true # 是否启用 Kafka 输出
hosts: ["192.168.138.129:9092"] # Kafka 服务器地址列表
topic: '%{[fields.logtopic]}' # 日志消息的主题名称,支持动态字段
partition.hash: # 分区哈希配置
reachable_only: true # 只在可用的分区上进行哈希计算
compression: gzip # 压缩算法,这里使用 gzip 压缩
max_message_bytes: 1000000 # 单条消息的最大字节数
required_acks: 1 # 生产者所需的确认数,1 表示只需要 leader 确认
logging.to_files: true # 启用日志文件输出
注意:在测试的时候,我们有时候需要观察日志是否正确获取,那我们则使用output.console输出到控制台,kafka部分进行注释,后期使用则将控制台输出注释,只写kafka输出即可。
启动服务,执行启动脚本,使用如下命令查看服务是否启动以及观察日志信息
# 校验配置文件是否正确
./filebeat -c filebeat.yml -configtest
# 启动服务
nohup ./filebeat -e -c filebeat.yml > filebeat.log &
3.5 Elasticsearch环境准备
es我们测试环境使用单点环境即可,也无需设置用户名以及密码信息,具体的步骤可以参考我之前Elastic学习的博文单点安装即可。
安装完毕后,我们访问 http://192.168.138.129:9200/ 地址,确定服务启动
我们使用 cerebro-0.9.4 连接ES,进行测试,输入页面进行登录
观察ES基本信息页面
也可以使用 REST 调用api 进行接口数据查询
调用参数如下:
{
"query": {
"query_string": {
"fields": ["messageInfo"],
"query": "定时任务执行开始"
}
}
}
除此之外,也可以使用elasticvue
插件进行连接,方便查询ES文档数据信息
3.6 logstash安装配置
Logstash是一个开源数据收集引擎,具有实时管道功能。Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地。我本地有一个上古版本 logstash-6.6.0,就没有下载新版本的logstash了,推荐使用新版本进行测试,版本问题不好解决
他的主要功能如下:
- 集中、转换和存储你的数据:
Logstash是一个开源的服务器端数据处理管道,可以同时从多个数据源获取数据,并对其进行转换,然后将其发送到你最喜欢的“存储”。(当然,我们最喜欢的是Elasticsearch) - 输入:
采集各种样式、大小和来源的数据,数据往往以各种各样的形式,或分散或集中地存在于很多系统中。Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件。能够以连续的流式传输方式,轻松地从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。 - 输出处理后的数据:
输出:选择你的存储,导出你的数据,尽管 Elasticsearch 是我们的首选输出方向,能够为我们的搜索和分析带来无限可能,但它并非唯一选择。 Logstash 提供众多输出选择,您可以将数据发送到您要指定的地方,并且能够灵活地解锁众多下游用例。
安装过程:
-
上传解压包,配置对应配置文件
tar -zxvf logstash-6.6.0.tar.gz cd /logstash-6.6.0/ mkdir custom-config # 修改配置文件 vim logstash-simple.conf
配置文件具体内容如下:
## multiline 插件也可以用于其他类似的堆栈式信息,比如 linux 的内核日志。 ## 可以作为kafka消费者角色 input { kafka { ## app-log-服务名称 topics_pattern => "app-log-.*" bootstrap_servers => "192.168.138.129:9092" codec => json consumer_threads => 1 ## 增加consumer的并行消费线程数,对应 partition数量 decorate_events => true #auto_offset_rest => "latest" group_id => "app-log-group" ## 组id } } filter { ## 数据过滤 ## 时区转换 ruby { ## 当前时间 定位到天 elk 时间是 东八区的 比北京时间慢8小时,此处转换回来。 code => "event.set('index_time',event.timestamp.time.localtime.strftime('%Y.%m.%d'))" } if "app-log" in [fields][logtopic]{ grok { ## 表达式,对应的内容是在app中设置 log4j2.xml 中定义的 partten格式,notspace 没有空格, currentDateTime等字段为key,value 是打印的日志信息,名称是自定义的 match => ["message", "\[%{NOTSPACE:currentDateTime}\] \[%{NOTSPACE:level}\] \[%{NOTSPACE:traceId}\] \[%{NOTSPACE:class}\] \[%{DATA:hostName}\] \[%{DATA:ip}\] \[%{DATA:applicationName}\] \[%{DATA:location}\] \[%{DATA:messageInfo}\] ## (\'\'|%{QUOTEDSTRING:throwable})"] } } } ## 测试输出到控制台: #output { # stdout { codec => rubydebug } #} ## elasticsearch: output { elasticsearch { ## es服务地址 hosts => ["192.168.138.129:9200"] ## 用户名密码,没有可以不填写 ## user => "elastic" ## password => "123456" ## 索引名,+ 号开头的,就会自动认为后面是时间格式: ## javalog-app-service-2019.01.23 ## index => "app-log-%{[fields][logbiz]}-%{index_time}" index => "index-elk-topic-%{index_time}" ## 通过嗅探机制进行es集群负载均衡发日志消息 sniffing => true ## logstash默认自带一个mapping模板,进行模板覆盖 template_overwrite => true } }
-
启动服务
cd /usr/local/soft/logstash-6.6.0/bin ./logstash -f ../custom-config/logstash-simple.conf > logstash.log 2>&1 &
-
查看服务运行状态
ps -ef | grep logstash tail -f logstash.log
注意:我们可以测试logstash是否好用,消费了kafka数据信息,那么我们暂时不需要向ES发送信息,那么我们可以放开
output> stdout { codec => rubydebug }
,进行控制台打印测试,后期使用ES再注释即可。es运行时候的情况如下所示
3.7 kibana服务安装
Kibana 是一个开源的数据分析和可视化平台,它是 Elastic Stack(包括 Elasticsearch、Logstash、Kibana 和 Beats)的一部分,主要用于对 Elasticsearch 中的数据进行搜索、查看、交互操作。
Kibana 的主要功能和用途包括:
-
数据可视化:
Kibana 提供了丰富的数据可视化选项,如柱状图、线图、饼图、地图等,帮助用户以图形化的方式理解数据。 -
数据探索:
Kibana 提供了强大的数据探索功能,用户可以使用 Elasticsearch 的查询语言进行数据查询,也可以通过 Kibana 的界面进行数据筛选和排序。 -
仪表盘:
用户可以将多个可视化组件组合在一起,创建交互式的仪表盘,用于实时监控数据。 -
机器学习:
Kibana 还集成了 Elasticsearch 的机器学习功能,可以用于异常检测、预测等任务。 -
定制和扩展:
Kibana 提供了丰富的 API 和插件系统,用户可以根据自己的需求定制和扩展 Kibana。
注意,kibana也是不能使用root用户进行部署的,所以我们需要新建一个用户进行操作,这里我们使用新建的es用户即可:
useradd -d /home/es -m es
passwd es
su - es
我本地没有kibana包,所以下载了一个包,推荐使用新版本,具体的下载地址。或者在服务器上使用wget进行下载,具体脚本如下:
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.13.1-linux-x86_64.tar.gz
# 解压
tar -zxvf kibana-7.13.1-linux-x86_64.tar.gz
修改配置文件内容,具体内容修改如下:
cd /usr/local/soft/kibana-7.13.1-linux-x86_64/config
vim kibana.yml
# 最后文件新增如下内容,我们使用的ES为单机节点,所以设置单机即可
server.name: ccms-kibana # Kibana 服务名称
server.port: 5601 # Kibana 服务监听的端口号
server.host: "0" # Kibana 服务监听的主机地址,"0" 表示监听所有可用的网络接口
elasticsearch.hosts: [ "http://192.168.138.129:9200" ] # Elasticsearch 集群的地址列表,Kibana 将连接到这些地址
monitoring.ui.container.elasticsearch.enabled: true # 是否启用 Kibana 监控界面中的 Elasticsearch 容器监控功能
i18n.locale: "zh-CN" # 设置 Kibana 界面的语言,这里设置为中文
服务启动命令为 :
nohup ./kibana > kibana.log 2>&1 &
服务启动后,我们可以使用 http://192.168.138.133:5601/ 访问kiban,可以进入到我们的访问首页,我们主要使用的是日志的查找以及部分统计功能,那么下面我们便开始配置日志的查找页面,首先点击我们的添加数据
进行索引添加
- 添加ES对应索引信息
- 创建搜索字段信息
如果没有数据,我们可以将时间跨度选择的大一些,我们是测试环境,数据很少,所以选择了两周时间跨度
点击刷新按钮,发现数据已经出现了
出现之后,我们开始建立搜索字段信息,这样重复添加多个,主要有applicationName,level,ip, traceId等等,最终选定字段信息如下点击保存即可。
- 添加搜索过滤框信息
此处我们添加服务名称,日志级别以及ip地址信息,因为这几个是查询常用字段,我们特别进行筛选展示
- 开始dashboard展示面板配置
我们先新增一个条状图,用于展示随着时间日志数据量的变化趋势图信息
设置水平轴为时间,垂直轴为日志数量取和,具体配置如下
将面板排班整理下,我们再新增一个服务占比的条形图,水平轴为日志数量,垂直轴为服务名称
我们整理下展示面板的排版然后我们再次新增一个扇形统计图,用于统计服务日志占比,切片依据applicationName服务名称,占比使用日志数量
再次整理下我们的dashboard面板,最后我们再加入查询的信息展示信息即可,点击从库中添加按钮
最后我们再整理下我们的dashboard布局信息,整理好之后我们便可以进行保存了
- 进行查询测试
以上我们便配置好了我们的ELK kibana查询面板,我们使用dashboard进行查询测试,首先我们使用搜索框进行搜索,里面可以任意搜索全部定义字段信息
再使用服务名称搜索,发现只搜索出自定义服务名称日志信息
使用ip进行搜索
使用日志级别搜索
至此,我们的ELK简单部署就完成了,并且进行了简单的测试,对ELK整体的运行逻辑有了简单的了解。