基于日志,通过ELK、Prometheus等实现日志收集、检索 监控 告警功能。

<>一、前言

      一提到日志收集方案,大家第一个想到的肯定是ELK(Elasticsearch、Logstash、Kibana
),但Logstash依赖于JVM不管是性能还是简洁性,都不是日志收集agent的首选。


      个人感觉一个好的agent应该是资源占用少,性能好,不依赖别的组件,可以独立部署。而Logstash明显不符合这几点要求,也许正是基于这些考虑elastic推出了一个新的组件
Filebeat <https://www.elastic.co/products/beats/filebeat>。

<>二、需求

      我们这边收集日志应对的场景主要是:文本日志、docker日志、k8s日志,恰恰这些EFK全家桶都支持。

      我们希望日志收集产品可以满足以下几个需求:

* 按照项目、应用、实例维度检索日志并支持搜索关键字高亮(因为大家检索日志的时候,肯定是检索某个应用、某个实例的日志)
* 支持检索出某条想要的日志后,可以查看上下文
<https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-after.html>
(查看该日志所在日志文件的前后多少条)
* 支持日志下载(目前支持两种场景:搜索结果下载、上下文下载;支持两种方式:在线下载、离线下载)
* 支持Elasticsearch Query String
<https://www.elastic.co/guide/en/elasticsearch/reference/6.3/query-dsl-query-string-query.html>
查询
* 支持自动化批量部署、卸载Filebeat,部署、卸载过程可视化
* 单实例支持多elasticsearch集群
* 支持文本日志、docker日志、k8s日志并能与将日志与其业务意义对应上。(
即不管是哪种日志形式、来源,最终都需要与业务意义上的项目、应用、实例对应起来,因为对于日志的使用者来说,查询日志的出发点肯定是查询某个项目、某个应用(可以不选)、某个实例(可以不选)、某段时间的日志。

<>三、具体实现

      基于需求及ELK套件,梳理我们场景中特有的东西:

*
docker日志的场景比较单一,都是通过之前一个产品A发布部署的,其docker命名规则比较统一,可以通过截取docker.container.name来获取应用名字;同时在部署的时候,可以知道部署目标机器的ip,这样就可以通过应用+ip来作为实例名称。
*
k8s场景也比较统一,都是通过之前一个产品B发布部署的,其pod命名规则比较统一,可以通过截取kubernetes.pod.name来获取应用名字(但需要通过namespaces关联到tenant,再通过tenant与项目一一对应);k8s中的pod.name就是唯一的,以此来作为实例名称即可。
*
文本日志:因为文本日志主要的场景是已经裸机部署的应用,这种场景下,不存在应用自动迁移的情况,所以文本日志的应用名称、实例名称可以在部署的时候打上标签即可。
具体规则及解析见下图(实例部分处理暂未标注):


其实,我们不太推荐写日志,写到文本文件中,使用标准输出就好。

      到这里可以发现我们可以选择Filebeat来作为日志的收集端,Elasticsearch来存储日志并提供检索能力。

      那么,日志的清洗在哪里做呢?

      日志的清洗一般有两种方式:

* 先把日志收集到kafka,再通过Logstash消费kafka的数据,来清洗数据
* 直接通过Elasticsearch的[Ingest Node]来清洗数据,因为Ingest Node也支持Grok表达式
<https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html>
      对于,我们的场景而言,我们需要清洗数据的要求比较简单,主要是应用、实例名称的截取还有文本日志中日志时间的处理(@timestamp重置,时区处理
<https://blog.csdn.net/jiankunking/article/details/81102856>),所以我们选择了方案2。

其实,选择方案二还有个原因就是:系统在满足需求的同时,尽量保持简单,减少依赖的组件。

<>四、整体架构

      到这里可以,可以看出我们的架构基本如下:


上图只展示了一个elasticsearch集群,提供检索功能的log-search单实例是支持多elasticsearch集群的。

      在我们的方案中,并没有提供Kibana 的界面直接给用户用,而是我们自己根据公司业务独立开发的。

前端界面为什么不采用Kibana,而需要自己开发?
1、kibana对于业务开发人员有一定的学习成本
2、kibana界面没有很好的将日志内容与业务意义关联起来(界面选择总比一次次的输入要好,这也是我们将日志的项目、应用、实例等业务信息解析出来的原因)
3、log-search支持Query String,因此对于熟悉kibana的开发人员来说,在我们自己开发的前端界面检索效果是一样的。

      代码架构:


      log-search提供的功能可以参见github:log-search
<https://github.com/jiankunking/log-search>

      https://github.com/jiankunking/log-search
<https://github.com/jiankunking/log-search>


如果日志需要清洗的比较多,可以采用方案1,或者先不清洗,先把数据落到Elasticsearch,然后在查询的时候,进行处理。比如在我们的场景中,可以先把日志落到Elasticsearch中,然后在需要检索应用名称的时候,通过代码来处理并获取app名字。

<>五、监控、告警

其实基于日志可以做很多事情,比如:

* 基于日志做监控(Google Dapper)
* 基于日志做告警
* 基于日志做Machine Learning
<https://www.elastic.co/products/stack/machine-learning>
具体思路,可以参见下图:


前提:能要求使用方,按照某种规则打印日志。
监控发展:监控基本就是先打通链路trace,然后再在上报信息或者日志信息中,加强业务方面标识,即给监控添加业务维度方面的视角。

<>六、其它

<>1、DaemonSet

以DaemonSet方式部署Filebeat来收集日志,其实收集也是宿主机/var/lib/docker/containers目录下的日志。
Running Filebeat on Kubernetes
<https://www.elastic.co/guide/en/beats/filebeat/current/running-on-kubernetes.html#running-on-kubernetes>

<>2、Sidecar

一个POD中运行一个sidecar的日志agent容器,用于采集该POD主容器产生的日志。

莫名想起了istio <https://github.com/istio/istio>。


Filebeat可以以sidecar模式来进行容器日志的收集,也就是filebeat和具体的服务容器部署在同一个pod内,指定收集日志的路径或文件,即可将日志发送到指定位置或Elasticsearch这类的搜索引擎。
每个pod内部署filebeat的模式,好处是和具体的应用服务低耦合,可扩展性强,不过需要在yaml进行额外配置。

个人微信公众号:


作者:jiankunking 出处:http://blog.csdn.net/jiankunking
<http://blog.csdn.net/jiankunking>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信