日常开发需求中,为了更好排查问题,我们常常需要把多台服务器的日志数据进行集中式收集,一来这样便于集中查看处理日志打印,也更方便我们排查问题,定位问题点。
今天我们主要聊聊如何从Kids到ELK的集中式日志收集方法。
谈谈Kids
首先我们来谈谈Kids是什么?Kids是知乎14年开源的日志收集系统,采用Scribe的消息聚合模型和Redis的pub/sub模型。特点:无第三方依赖,实时订阅,使用Redis协议等。
因为上面这些原因,团队在一开始就把Kids作为主要的集中式日志收集管理平台。
下面是主要的配置步骤:
- 用docker进行安装(也可以源码安装)客户端及服务端
- 在客户端应用App代码配置logging handler,配置好对应的应用的日志level,topic。(通过topic配置可以把应用日志各种状态都分类收集起来)
- 应用App的logging日志打印到kids服务端得到日志文件,实现统一收集
上图来自官方架构图,更多参考:
https://github.com/zhihu/kids/blob/master/README.zh_CN.md
最后上一张日志效果图,其中日志的压缩是运行了自动化shell加密脚本与kids本身无关。
使用ELK+Filebeat收集日志
通过kids配置使用,就能把各个应用日志统一进行收集分析了,但是随着需求越来越多,对日志要求也越来越高,需要各种类型日志来源,需要可视化,需要集中挖掘各个日志数据信息,比如数据库慢查询日志,nginx请求日志,错误日志。这个时候轻量级的Kids系统就有些力不从心了。
这个时候就需要用到ELK+Filebeat这种重量级装备了。
ELK是一个软件集合,由Elasticsearch(简称ES 负责存储搜索聚合),Logstash(数据收集过滤), Kibana(数据分析及可视化)三款开源软件组成,现在已成为目前最为流行的日志解决方案。
而Filebeat是ELK 家族新成员Beats下面分支,一个更轻量级的日志文件收集器,用来替换Logstash,通过Filebeat收集数据更加节约服务器资源。
Filebeat主要场景是在需要采集日志的服务器上面安装服务,指定好对应的日志文件,读取文件数据发送到Logstash解析或者发送到ES,Redis进行存储。
上图是整个日志的流转过程,首先通过从各个服务器收集到的数据发送到logstash集中处理,存储到ES,最后再通过Kibana进行数据展示,生成图表。
知道整个数据流转情况,下面简要讲下Filebeat及Logstash下安装配置过程:
- 安装配置步骤如下:
- 使用docker安装指定版本的镜像
- 配置对应的配置命令挂载指定的路径
- 使用docker-compose up -d 启动管理容器
# docker-compose.yml version: '2' services: logstash: image: docker.elastic.co/logstash/logstash:5.6.10 hostname: logstash container_name: logstash restart: always ports: - "5044:5044" volumes: - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf filebeat: image: docker.elastic.co/beats/filebeat:5.6.10 hostname: filebeat container_name: filebeat command: filebeat -e -strict.perms=false # 其中strict.perms=false 表示filebeat忽略权限 restart: always volumes: - ./settings/filebeat.yml:/usr/share/filebeat/filebeat.yml - ./yourselfdir:/usr/share/filebeat/yourselfdir
# 下面是filebeat.yml配置 filebeat.prospectors: - input_type: log paths: - /usr/share/filebeat/yourselfdir/*/*.log #document_type: 'test1' # 在5.X版本用document_type区分不同日志来源6.0被废弃,使用fields #fields: # 这里是在6.0版本使用 fields来自定义进行区分来源 #type: test1 #fields_under_root:true #如果自定义字段和原有字段重名,是否覆盖原有字段 #output.elasticsearch: # hosts: ['xx':9200'] output.logstash: hosts: ["xx:5044"] #tail_files: true 默认为false从文件末尾开始读取而不是开始,适用大文件日志读取 ------------- # 下面是 logstash.yml配置 input { beats { port => 5044 codec => "json" add_field => {"myid"=>"nginx"} # 通过logstash特定端口add_field也能区分不同日志来源,相对来说不够优雅 } } filter { if [myid] == "nginx" { grok { match => ["message", "%{HTTPDATE:logdate}"] } } date { match => ["@timestamp", "yyyy-MM-dd HH:mm:ss"] } } output { if [myid] == "nginx" { elasticsearch { hosts => "XX:9200" manage_template => false index => "nginx-log-%{+YYYY.MM.dd}" document_type => "nginx-log" } } }
其中注意的是:ducument_type参数已经在5.5版本建议丢弃,6.0中彻底废弃,使用fields代替,通过fields_under_root属性,替换原始type属性,上面演示了其实通过logstash端口号也能区分不同日志来源。
由于笔者已经装好ES及Kibana,这里就简单罗列了基本日志配置文件(实际生产环境较为复杂),需要注意事项较多,尤其是安全相关认证,数据加密等这些都是重点需要关注的。
通过把不同来源的数据日志进行集中整合及可视化操作,让我们对我们的应用服务了解的更为透彻。
写在后面
开发技术都是在不断变化迭代的,Kids简单方便但功能较单一,ELK复杂臃肿但是功能强大,每个时间点都有适合自己的技术,不是越时髦越好,而是最适合团队业务场景和技术水平。
由于篇幅有限,大家如果有问题可以微信留言或者加我微信pengtaotalk,大家一起探讨。