前言
我的上一个项目特别惨,因为服务器不稳定,发行不敢给量,直接就死掉了。
我们的服务端主程,没有搭建任何的预警系统、日志分析。甚至连关服都是手动操作。个中无语,一言难尽。
我首先帮助解决了无法一键关服的问题,主程的代码中,没有排除grep本身的进程,导致grep被杀,因此不能保证关闭全部的进程。
后来,我使用开源的运维平台Spug配置了一键操作,也接入了钉钉机器人用于预警。
最后,统一了服务器日志格式,搭建了这套EFK日志分析系统,来分析日志和错误。
作为一个游戏客户端,我已经仁至义尽了。只可惜,天命难违,这项目还是死了。
废话不多说,下面是介绍和搭建过程
搭建
介绍与优势
EFK 是三个开源软件的缩写,Elasticsearch,FileBeat,Kibana。其中 ELasticsearch 负责日志分析和存储,FileBeat 负责日志收集,Kibana 负责界面展示。它们之间互相配合使用,完美衔接,高效的满足了很多场合的应用,是目前主流的一种日志分析系统解决方案。
EFK 和 ELK 只有一个区别, 收集日志的组件由 Logstash 替换成了 FileBeat,因为 Filebeat 相对于 Logstash 来说有2个好处:
- 侵入低,无需修改 elasticsearch 和 kibana 的配置;
- 性能高,IO 占用率比 logstash 小太多
当然 Logstash 相比于 FileBeat 也有一定的优势,比如 Logstash 对于日志的格式化处理能力,FileBeat 只是将日志从日志文件中读取出来,当然如果收集的日志本身是有一定格式的,FileBeat 也可以格式化,但是相对于Logstash 来说,效果差很多。
部署步骤
- 安装Docker
- 下载所需镜像
# 请去官网查询最新版本
docker pull elasticsearch:7.12.0
docker pull kibana:7.12.0
docker pull store/elastic/filebeat:7.12.0
- 创建自定义网络
docker network create elk_net
- 启动Elasticsearch和Kibana
docker run -d --name elasticsearch --net elk_net -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.12.0
docker run -d --name kibana --net elk_net -p 5601:5601 kibana:7.12.0
如果希望使用中文界面(中文化不完全,不推荐使用),可以进入kibana的容器里,修改配置文件,在现有配置文件中加一行中文相关的配置即可:
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
monitoring.ui.container.elasticsearch.enabled: true
// 设置语言为中文↓
i18n.locale: "zh-CN"
进入docker容器的指令为:
docker exec -it kibana /bin/bash
- 配置日志解析规则
日志解析的规则,是存放在Elasticsearch中的。只要通过curl命令即可实现向es中插入数据。
新建json文件:
{
"grok": {
"field": "message",
"patterns": [
"%{TIMESTAMP_ISO8601:Time}\\s\\s*\\[%{DATA:ServerType}\\]*\\[%{DATA:ServerID}\\]*\\[%{LOGLEVEL:Level}\\s+\\]*\\[%{DATA:Func}\\]%{GREEDYDATA:Log}"
],
"pattern_definitions": {
"ALL_CODE": "(.|\\n)*"
}
}
},
{
"date": {
"field": "Time",
"formats": [
"ISO8601"
],
"target_field": "@timestamp",
"timezone": "Asia/Shanghai"
}
},
{
"remove": {
"field": "message"
}
},
{
"remove": {
"field": "Time"
}
}
patterns部分为解析每行日志的正则表达式,pattern_definitions是处理换行标志。
测试过程,可以使用kibana自带的grok测试工具,在设置界面会有。
下方的date部分,是通过对上方产生的Time字段,存放到默认的时间戳上,用于处理排序。
处理完成后,把多余的字段删除,特别是输入的message,有利于缩减入库数据的量。
需要注意的是,json文件里的反斜杠一定要进行转义。
执行命令:
curl -H "Content-Type: application/json" -XPUT 'http://192.168.3.67:9200/_ingest/pipeline/lmyzpip' -d@/home/docker/pipline/pip.json
除此之外,可以登录Kibana界面,通过可视化界面配置解析。
- 点击左侧的三条线按钮,进入Stack Management->Ingest Node Pipelines->Create a pipeline
- 输入名称和描述
- 点击下方Add a processor,增加处理方式
- 填写相关参数,点击Add保存
右侧Add documents可以填写测试用例,测试相关配置是否正确(通过直接写入ES的配置也可以在此测试)。
测试数据的格式为:
[
{"_index":"index",
"_id":"id",
"_source":{"message":"2021-04-29T15:42:05.000000 [Game][4][DEBUG ][CNetManager::_SendServerConfigRequest]Request for server-config, Stream-{Game: 4-0}. ServerConfig<2> DBConfig<0> RedisConfig<0>"}
}
]
- 安装filebeat
新增配置文件filebeat.docker.yml:
#=========================== Filebeat inputs ==============
filebeat.inputs:
- type: log
enabled: true
##配置你要收集的日志目录,可以配置多个目录
paths:
- /home/docker/logs/*.log
## 设置kibana的地址,开始filebeat的可视化
setup.kibana.host: "http://kibana:5601"
setup.dashboards.enabled: true
#-------------------------- Elasticsearch output ---------
output.elasticsearch:
hosts: ["elasticsearch:9200"]
pipeline: "lmyzpip"
setup.template.name: "my-log"
setup.template.pattern: "my-log-*"
json.keys_under_root: false
json.overwrite_keys: true
其中需要注意的是,如果filebeat和前面的EK两个东西,没有部署在同一台机器上,需要把容器名改成对应的ip地址。运行Filebeat:
docker run -d --net elk_net -v /home/docker/filebeat/filebeat.docker.yml:/usr/share/filebeat/filebeat.yml -v /home/docker/logs/:/home/docker/logs/ --link elasticsearch:elasticsearch --link kibana:kibana --name filebeat docker.io/store/elastic/filebeat:7.12.0