由于所在公司去年新产品开始使用微服务架构,每次排查报文日志需要开好几个窗口监控几个日志文件,且不容易快速确定报错位置。费时费力很违背程序员这个职业的本质目的-偷懒。
使用ElasticSearch+LogStash+Kibana+FileBeat 搭建分布式日志集中管理的解决方案。省事省力。有以下几大好处
1、帮助快速分析与调试程序bug;
2、检查系统是否健康;
3、业务层面能做日志大数据过滤分析;
4、遇到错误时第一时间报警,尤其生产环境特别好用。
于是遂决定研究下,做个记录
首先确保xxx.log以正确的格式来进行输出,以logback为例,我们需要在logback.xml中配置日志格式:
%p|%d|%t|%logger|%m%n
这种格式会把日志打出这种效果:
INFO|2022-03-02 09:38:02,443|restartedMain|com.xxx.xxx.XXXApplication|哈哈哈
然后准备一台服务器(生产环境建议准备三台做集群,确保可用性)
本人资源有限只能用一台通过Docker容器化部署
1、安装Docker环境
此步骤忽略,不懂的童鞋可以去网上看下相关资料,建议从现在开始开始尝试把docker用起来;
2、下载ELK的docker镜像
docker pull docker.elastic.co/elasticsearch/elasticsearch:6.6.2
docker pull docker.elastic.co/logstash/logstash:6.6.2
docker pull docker.elastic.co/kibana/kibana:6.6.2
docker pull docker.elastic.co/beats/filebeat:6.6.2
3、ElasticSearch
ES的启动什么都不用改,直接通过docker命令,把镜像文件转化成docker容器,
开放了端口,将宿主机的9200、9300跟容器之间的端口做一个映射。
docker run -it --name elasticsearch -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.6.2
建议在生产环境中将ES做多节点集群,以保证高可用,本例为单节点;
启动完成后,访问localhost:9200会出现类似于下面的内容,则表示启动成功
LogStash可以用来做日志的解析、过滤、邮件报警、输出等操作。所以这个组件确实很繁琐,我从昨天研究到今天,配置的含义我都注释了,因为测试环境服务器资源紧张,此次收集的是另外一台服务器的Nginx的日志。
Logstash的配置文件有三个模块:input,filter,output。表示【输入】->【过滤】->【输出】;实际就是从FileBeat输入->过滤、拆分、报警->输出到ES。这三块来和起来可以组成一个管道。
创建LogStash的配置文件
vim /usr/data/logstash/config/logstash.conf
input {
file { # 数据输入的类型,从文件中输入
path=>"/data/access.log" # 文件所在位置,docker容器中的目录
start_position => "beginning" # 从文件什么地方开始读取,有两个值可以选:end——文件末尾;beginning——从文件首行开始
}
}
output {
elasticsearch{ # 输出数据到es中
hosts =>["118.25.230.159:9200"] # es的位置,这里使用es服务宿主机ip,使用localhost时访问不过去
index => "es-message-%{+YYYY.MM.dd}" # 数据存储到es中时,设置的index名称,格式为`es-message-年.月.日`
codec => json
}
stdout { codec => json } # 设置数据的输出格式
if [log_level] == "ERROR" and [type] == "demo_log" {
email {
port => 465 # 用于与邮件服务器通信的端口
address => "smtp.exmail.qq.com" # 邮件的服务器地址
via => "smtp" # Logstash应如何通过SMTP或通过调用sendmail发送电子邮件
authentication => "login" # 服务器识别身份的方法
use_tls => true # 与服务器通信时启用TLS
username => "[email protected]" # 用来验证服务器的用户名
password => "123456" # 用于验证服务器的密码
from => "[email protected]" # 发件人
to => "[email protected]" # 电子邮件发送目标
subject => "预警提示" # 邮件主题
body => "%{log_date}-%{log_content} 程序出现异常" # 电子邮件正文
}
}
}
接下来进行Settings Configuration类型配置文件的配置,该类型配置文件主要用来控制Logstash的执行的,例如设置Pipleline配置的位置,日志记录选项等其他设置,具体的配置项可以参考:Logstash中的settings documentation
vim /usr/data/logstash/logstash.conf
pipeline.id: main # 配置pipeline的id
path.config: /usr/share/logstash/conf.d/*.conf # 这里是管道的配置文件的地址
path.logs: /var/log/logstash # logstash日志存储的目录
# config.reload.automatic: true # 定期检查配置是否已更改,并在更改后重新加载配置
# config.reload.interval: 5s # Logstash多长时间检查一次配置文件的更改。必须使用单位限定符(s)
以上就是全部配置了,我还加了一个判断,如果搜集到的日志的级别是ERROR,那么就要走邮件报警流程。
关于邮件报警,本例中是使用了LogStash自带的email组件完成,具体每个厂商的邮件服务器、协议跟端口需要自己去找了。尤其是有的邮箱怎么配都成功不了,这里是个坑。
全部配置可以参考官方文档:Logstash配置文件Pipleline configuration
创建LogStash容器
docker run -it -d -p 9600:9600 -p 5044:5044 --name logstash
-v /usr/data/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml # 挂载logstash基本配置
-v /usr/data/logstash/config/:/usr/share/logstash/conf.d/ # 挂载管道信息配置
-v /usr/local/nginx/logs/access.log:/data/access.log # 挂载日志文件地址,要将宿主机的日志数据,与容器内的挂载
docker.elastic.co/logstash/logstash:6.6.2
查看是否创建成功:docker ps
这一步很可能启动失败,若失败排查下日志: docker logs logstash
5、Kibana
与ES的启动类似,也比较简单,开放与映射了5601端口,并指定了ES的访问地址,以便在容器内可以通过域名访问,注意将elasticsearch:9200替换成你实际的ES地址的。
docker run -d --name kibana -p 5601:5601 -e ELASTICSEARCH_URL=http://elasticsearch:9200 docker.elastic.co/kibana/kibana:6.6.2
Kibana容器启动后,稍等半分钟,访问localhost:5601会出现kibana的页面
至此,三个容器全部启动完毕,我们可以通过docker命令来查看四个容器的启动状态:
docker ps
待三容器全部配置成功并启动之后,我们通过localhost:5601来访问Kibana的首页。
然后在Kibana中查看日志是否已经解析到ES中,在Kibana的Dev tools中进行如下操作:
即可看到Nginx中的access.log日志信息已经同步解析到ES中。
然后在Kibana的Discover中添加索引 es-message-*
;即可看到从多个地方收集而来的日志了,右侧还可以自定义展示字段。
这只是一个最简单的能运行的单机版,很多地方都可以完善,比如做集群高可用、比如高并发下日志写入可能会丢失需要结合MQ来进行优化,以及还能收集mysql、mq、syslog、nginx、reids等各个组件的log或其他数据,让遍地开花的的分布式日志,变得井井有条。本文只是记录自己搭建中踩的坑,给其他童鞋一个思路。有啥错误之处,也请多多指正。