写在前面
由于使用分布式部署线上服务的原因,我们在查看日志的时候往往优化恩达的困难,尤其是在定位错误的时候无法找到对应错误所在的服务器,这时我们需要将所有的错误日志统一的收集起来进行集中查询.
技术栈
- elasticsearch:用来存储日志,进行日志查询
- logstash:用来处理日志,将日志格式调整存入es
- filebeat:将对应服务器上的日志收集起来发送到logstash
- kibana:用来进行日志查询
- kafka:用来缓存日志消息,减少logsatsh的压力
- python:服务器定时任务,设定日志自动清除计划
接入指南
为了方便日志的解析,我们首先需要同一所有服务的日志格式,本地技术栈使用的是log4j2日志收集器,所以只需要更改日志的打印格式即可
替换日志内容
java项目替换到conf目录下的日志格式文件中的内容
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} ${LOG_LEVEL_PATTERN} [%t] %C.%M(%L) --> %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
安装filebeat
对应服务器部署filebeat(消耗性能极小),使用rpm包安装即可
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.3.2-x86_64.rpm
rpm -vi filebeat-6.3.2-x86_64.rpm
下图是filebeat通过rpm安装的目录格式
启动filebeat
再启动fielbeat之前我们需要做一些准备工作
准备filebeat.yml配置文件
filebeat.yml主要配置了日志在服务器上的位置,日志采集方式,和一些自定义的变量.
filebeat.prospectors:
#base-search
- type: log
#开关
enabled: true
#扫描包路径
paths:
- /app/logs/ic-course-server/ic-course-server_inf.log # 日志地址
#日志多行处理
multiline:
pattern: ([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))
negate: true
match: after
#自定义变量
fields:
service_name: ic-course-server # 服务名
log_type: info
data_type: log
host: 192.168.100.53 # 直接指定服务器ip
#输出
output.logstash:
hosts: ["192.168.100.110:9600"]
这里制定了服务器的ip用来当做自定义变量,在我们之后查询日志时方便定位服务器.
执行命令
将更改好的配置文件直接上传到服务器中filebeat的配置文件夹,然后执行命令
sudo service filebeat start
确认运行
通过查看日志确认文件已经发送到logstash
tail -100f /var/log/filebeat/filebeat
查看日志方法
经过以上的操作我们已经把所有的服务器日志上传到了es中进行保存,现在需要做的事使用kibana进行简单的查询
设置指定字段
在存储日志的时候为了方便展示,在后台我使用logstash将日志内容进行解析拆分成了多个字段,在查询的时候可以指定需要的内容进行展示.
日志清除策略
由于防止日志在服务器中大量堆积目前的服务器只保存7天日志,超过七天的日志自动清除.
清除的方法通过python编写es的HttpAPI调用Delete方法删除索引,然后在服务器上设置定时任务执行python脚本
import requests
import datetime
saveTime = 7
newDay = datetime.datetime.now().strftime('%d') # define new day
newTime = datetime.datetime.now().strftime('%Y.%m.')
maxDay = str(int(newDay) - saveTime)
request = "http://192.168.100.110:9400/"
def deleteOne(day):
return requests.delete(url=request + '*' + day + '*')
if __name__ == "__main__":
if len(maxDay) < 2:
maxDay = '0' + maxDay
delete = deleteOne(day=newTime + maxDay)
print(delete.text)
这里直接附上python源码仅供参考件.
- 根据时间维度进行查询
- 根据特定条件进行查询
- 搜索相关接口
- 根据日志输出进行查询
…功能持续开发中
下期内容:
consul+consul-template+Nginx实现服务自动注册
技术栈
- elasticsearch
- skywarking
- java-agent
- springcloud-gateway
- consul