概述
监控预警平台, eagle + eye (鹰眼)的合体词, 寓意可以快速发现问题, 并及时作出响应,Eagleye整个分为:
- eagleye-java-client: 针对java程序进行日志收集
- eagleye-alerter: 根据控制台设置的预警规则, 对匹配日志进行实时预警.
- eagleye-admin: eagleye管理界面,可以看到各个app的接入情况,设置预警规则,进行日志检索等.
- eagleye-collector: eagleye日志收集器, 该收集器主要是从kafka中收集日志病存储到Elasticsearch中, 也可以用logstash替代.
- eagleye-task: eagleye的定时监听组建, 如果下游其他系统需要某个app日志,可以直接通过该组建发送.
核心功能说明
首页客户端感知
首页所有接入eagleye-java-client的应用每分钟都会通过redis发送心跳数据, 这里面包括应用所在机器的IP, PID, 每分钟日志的生产力, 应用最近一次启动到现在日志总量.如果应用进程被kill,则首页上相应的节点会消失.
应用管理
应用管理在这里进行app管理, 应用在发送日志之前, 需要在log4j配置文件中配置应用的名称, eagleye最终会根据这个配置名称来匹配预警规则. 所以这里的名称需要在应用程序中的log4j配置中的名称一致.
规则管理
规则管理我们可以通过预警管理设置具体的预警规则, 可以通过正则表达式来匹配日志中的内容, 提示中给出来比较常规的预警规则设置.
预警设置
预警设置-
针对某一个应用里面的某一个预警规则,我们可以设置给谁发送短信预警, 给谁发送邮件预警.
-
我们通过预警设置的管理将具体的应用和预警规则进行挂钩.
Zookeeper监控
ZK监控这里我们借鉴了阿里巴巴的Taokeeper监控软件, 开发了部署更加方便的zookeeper监控, 可以针对每一个集群中的每一个zk实例进行每分钟自检, 如果超出我们设定的预警阈值, 则会进行实时报警.
日志概览
日志概览我们前期通过Kibana的简单统计页面可以了解各个应用日志的大致情况. 只需要简单的配置即可实现.
日志检索
日志检索全量日志收集进来之后, 我们需要对它们进行精确检索. 这里我们提供了针对时间区间, IP, PID,线程ID, 应用名称, 日志关键字等的联合检索功能
日志上下文
日志上下文有些时候我们只检索出满足条件的日志还不能帮助我们快速定位问题, 我们还需要查看日志的上下文, 那么我们可以双击某一条日志, 则可以查看该条日志的前200条和后200条日志.
ES监控
HEAD可以查看ES集群中详细的Sharding信息.
BIGDESK可以查看某一个ES实例所在机器的JVM, CPU, 内存等详情.
Zipkin监控
ZIPKIN可以根据服务名称查看具体的RPC调用链详情.
详细设计
Eagleye整体架构图
eagleye,整体架构图eagleye作为所有服务的日志监控预警平台, 需要收集所有后台服务的全量日志,主要分成如下几个部分:
- 各个java服务需要接入的基于log4j appender的日志收集客户端(eagleye-java-client).
- 我们统一通过Kafka作为日志传输通道, 因为要收集的是所有服务的全量日志,日志量庞大,Kafka非常适合这种分布式收集的场景, 并且可以很容易的进行水平拓展.
- 我们通过eagleye-alert 从kafka中获取日志, 并根据eagleye-admin中设置的预警规则进行实时预警, eagleye-alert支持水平拓展,并可以做到高可用.
- 通过logstash进行全量日志的收集并存储到elasticsearch中进行存储, 最终用kibana进行快速的检索和统计.
- eagleye-admin是eagleye架构的管理控制台, 从这可以进行各种预警规则的配置, 监控各个client, alerter的心跳, es的存储状态, 提供日志检索,统计界面.eagleye-admin作为一个管理控制台,并不需要高可用,所以只需要部署一个实例, 即使admin不可用也不会影响所有日志的收集预警功能.
- 所有服务器的心跳, 预警规则, 都是通过redis进行通信.
日志收集,存储架构图
日志收集,存储架构图日志可靠性说明
因为将来会涉及到交易流程的日志跟踪, 所以日志的可靠性需要保证.鉴于之前推动zookeeper的dns设置过程(运维人员需要每台服务器去修改,推动时,不是这台服务器没有设置,就是那台服务器没有设置), 日志收集任务前期在服务端进行日志采集的过程, 并没有引入第三方的收集工具(鉴于logstash的部署问题,我们在后期引入了自己写的eagleye-collector来进行日志中继).在服务端进行日志采集方式, 采用自定义log4j的appdender方式接入采集点.通过kafka作为日志传输通道.当然, 采用这种方式有一个风险点是,假如kafka不可用时,日志将采集不到. 但是会记录到本地log日志中,并不会丢失. 服务端进行日志采集,也有高可用方案,可以每台部署服务的机器都部署logstash进行收集,即使logstash不可用,日志也不会丢失,并且,logstash启动时会将丢失收集的日志重新采集.但是logstash部署在服务端所在的机器,对前期日志采集工作量比较大,并不适合我们前期小步迭代推动eagleye项目.所以我们前期约定,在极端情况下,我们允许小概率收集日志失败的可能.因为采用的是Kafka的队列方式进行传输,所以并不影响我们将来更替高可用的日志采集方案.
日志中继说明
日志中继器的存在,有利于我们水平拓展日志收集,并灵活指定存储媒介.Logstash可以灵活的接入es, hdfs, mysql, cvs, local file 等存储媒介, 并可以灵活的对日志内容进行过滤.Logstash相比flume会更轻量一些,并且是elasticsearch的同源产品.
如果觉得logstash部署麻烦, 可以直接采用后续开发的eagleye-collector进行日志中继.
日志存储
我们选择Elasticsearch进行存储, 当然也可以随时切换成hdfs进行存储, elasticsearch提供了丰富的RESTFul风格的api,和语言无关.ES的集群搭建成本非常低,每一个ES服务会自动发现集群并加入进去.
日志检索, 统计
因为有Kibana的存在, 我们可以很轻易并且快速的从es中检索出我们想要的日志. 可以从多维度进行日志的统计.关键是这些功能的提供, 我们不需要写任何一行代码,后续我们又开发了自定义检索,可以查看某一条日志的上下文.
备注
上图中的channel, relayer, es 可以部署在相同的机器中,也可以进行拆分. 每一层都可以选用其他方案进行替代,并不影响整个系统的运转.
测试
功能测试
性能测试
-
logstash 性能测试:
单台服务器的单个logstash实例
内存:500m
input consumers : 1
output workers : 2
机器内存: 4G, 其中2个G被es消耗, 1个多G被日志mock程序占用
机器8核,普通pc机在output配置中
workers => 2 # 如果这个配置开太大容易内存溢出, 需要根据机器配置进行调整, 在测试环境logstash 内存500m时,2个线程效率最高
flush_size => 1000 #该配置配合workers进行调整, 如果太大, 也容易内存溢出, 或者增加gc次数.目前这个配置可以达到单台logstash可以20000/s的日志写入gc观察
在bin/logstash.lib.sh 文件中 logstash 采用了 如下gc方式JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC" JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"
观察曲线如下图:
logstash采用自己默认gc
老年代gc会比较频繁,增加了stop the world的时间,会影响性能.注释掉之后的曲线老年代很少出现回收现象, 不会造成stop the world 现象
logstash采用jvm默认gc
但是采用jvm默认gc方式后运行了1个小时之后出现了频繁的老年代gc, 如下图:
logstash采用jvm默认gc简单的测试观察之后, 还是建议使用logstash默认的gc
JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC" JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"
-
eagleye-java-client 性能测试
client往kafka中发送日志可以80000/s, 这取决与网络速度和硬盘速度
运行时通过jmx观察内存,如下图: 没有一次老年代回收
eagleye-java-client gc图 -
eagleye-alert 性能测试
-
单服务, 单机器(244)压力测试:
cpu使用如下图:
kibana -
配置discover:配置各种查询数据,进行条件筛选
kibana
kibana
(1). 点击discover菜单,点击搜索口后面的添加按钮(加号),在左侧Field项下会列出所有的字段信息,鼠标移到字段上面,会出现add按钮,点击添加,该字段会出现在上方的select field项下.
(2). 配置完成后,右边会出现选择的列和数据.
(3). 点击apply应用所选的配值
(4). 点击保存,在页面的右上方,有个保存的图标.填写保存的名字 -
配置visualize:visualize是对discover数据表的各种汇总信息,并以各种个图表显示.
kibana
kibana
(1). 点击visualize菜单,点击搜索口后面的添加按钮(加号).
(2). 选择样式
(3). 选择基础数据(discover保存的基础数据)
(4). 在左侧选择自己需要的统计数据,Metric选项卡中选择统计结果如(count,avg,sum等).buckets下面的选项可以选择如何分组,相当于group by 后面的字段
(5). 点击apply应用所选的配值,点击右上角保存按钮,然后输入名字保存. -
配置dashboard:将discover和visualize保存的各种表格和报表集中在一起显示
kibana
kibana
(1). 点击上图添加按钮,跳转到选择discover和visualize页面.
(2). 选择需要的discover和visualize页面.此时会在下放显示.
(3). 拖动改变位置和大小.
(4). 保存设置好的面板. -
搜索框简易使用说明
(1). 在特定的字段里搜索,例如:line_id:86169
(2). 可以用 AND/OR 来组合复杂的搜索,AND/OR必须大写,例如:food AND love
(3). 括号的使用:("played upon" OR "every man") AND stage
(4). 数值类型的数据可以直接搜索范围:line_id:[30000 TO 80000] AND havoc
(5). 搜索所有:*
(6). 如果输入 where1 where2 两个单词,实际搜索的是where1 OR where2 如果要搜索where1 where2,请用双引号引起来"where1 where2"
alerter 部署和配置
-
部署:
(1). 获取代码git clone git@git.xxx.com:trade_architect/eagleye.git
(2). 进入在eagleye-alerter程序根目录
cd eagleye/eagleye-alerter
(3). 在eagleye-alerter程序根目录执行
git -pull && mvn clean package -Dmaven.test.skip=true -U
完成后进入文件夹得到 项目压缩包 eagleye-alerter-1.0.0-all.tar.gz
(4). 解压项目包
(5). 执行启动
nohup ./start.sh > /data/applogs/eagleye/service.log 2>&1 &
-
关闭:
需要手动kill掉程序进程,可以执行以下命令:ps -ef | grep 'com.xxx.eagleye.alerter.App' | grep -v 'grep' | awk '{print $2}' | xargs kill
-
配置说明:
由于alerter程序会和kafka,zookeeper集群进行通信, 所以程序运行前需要配置相关host, 配置如下:#kakfa cluster 192.168.1.43 xx-xx-1 192.168.1.46 xx-xx-2 192.168.1.60 xx-xx-3 192.168.1.67 xx-xx-4 192.168.1.73 xx-xx-5
loomContext.xml 中可以配置日志toipc kafka消费者的消费线程数(alerterConsumerThreadNum),alerter程序可以部署的最大实例数为 kafka日志topic分区数/alerterConsumerThreadNum.如果部署的程序实例数超过了最大实例数, 新的程序实例将会得消费不到得到topic分区, 不产生吞吐量.
-
需要注意:
(1). 需要替换conf/log4j.xml 中的日志文件目录 , 和命令输出日志目录
(2). 需要修改run.sh 中的变量IP 为服务器IP , HEAP_DUMP_PATH 为日志目录的文件
(3). 由于alerter即是kafka消费者, 又是kafka生产者, 为了避免死循环, 程序在打印描述性日志前都都加了'~', 创建alerter程序的预警规则时, 应当在规则中过滤日志内容第一个字符为'~'的情况
eagleye-admin部署
-
执行附件脚本,初始化表.
-
获取代码
git clone git@git.xxx.com:trade_architect/eagleye.git
-
cd eagleye/
-
编译
mvn clean; mvn -DskipTests package
-
在tomcat中部署eagleye-admin/target/eagleye-admin.war包。
-
初始用户名密码:admin/test
非java项目对接
如果非java服务想对接到该预警平台, 请按照如下json格式:
{ "body": "日志内容", "head": { "app": "eagleye-test", "ip": "192.168.1.100", "level": "WARN", "pid": "3817" }, "timestamp": 1426216784971 } 发送到kafka的 名为:EAGLEYE_LOG_CHANNEL 的topic中 如果是直接接入其他非java的日志, 并且还不想格式化上述json,可以直接开启一个logstash实例, 配置文件如下: input { file { path => ["/home/zhejava/logstash/logstash-1.4.2/temp/*.log"] # type => "system" # start_position => "beginning" } } filter { grok { match => { "message" => "" } add_field => { "head.app" => "logstash-test" "head.ip" => "192.168.5.177" "head.level" => "WARN" #"timestamp" => 1426237376377 #"head" => "{'app' : 'eagleye-test-b','ip' : '192.168.5.244','level' : 'ERROR','pid' : '9744'}" } remove_field => [ "message" ] } } # 如果是入kafka请这么写 output { #stdout { # codec => rubydebug # #codec => plain #} kafka { #codec => plain { # format => "%{body}" #} broker_list => "witgo:9092,spark:9092" topic_id => "EAGLEYE_LOG_CHANNEL" } } # 如果是入es 请这么写,不推荐直接入es, 这样就不能设置实时预警了 output { elasticsearch { cluster => "eagleye_es" host => "localhost" port => "9301" protocol => "transport" index => "eagleye-log-%{+YYYY.MM.dd}" index_type => "log" workers => 2 flush_size => 1000 template_overwrite => true } }
其他
ES自定义检索功能说明
- elastic search建立索引时, 会使用现有词典进行分词, 如果用户输入的关键词不在当前词库中, 将不会搜索到结果, 遇到这种情况, 建议用户缩小关键词粒度, 并使用多个关键词进行查询
- 多个关键词可以用空格分开
ES index template功能简介
- ES可用通过预先设置的template来指定即将创建索引的setting 和 mapping 设置
- 使用方式:
(1). 使用命令添加
(2). 将 template模板 添加到 config/templates/ 目录
-
网友评论