如何在12個小時,搞定日志監控?
日志監控,是每個公司必須解決的一個問題。創業型公司,如何用半天的時間,搞定一個可擴展,通用的日志監控框架,是今天要聊的話題。
什么是日志監控?
關于日志,不同公司,情況不同:
(1) A類公司:沒有日志;
(2) B類公司:有日志,只有用戶說系統掛了,或者有bug的時候,才會登錄到系統看看日志,大部分日志打印得對心所欲,缺乏組織性和系統性;
畫外音:很多時候,追查bug發現日志信息不全,要先上線一個有日志的版本,以幫助定位bug。
(3) C類公司:有日志,有日志規范,系統性的組織和收集了日志;
對日志進行監控,先于用戶發現系統的故障,實時告警,就是今天要討論的日志監控問題。
日志監控有什么需求?
對于日志的監控,一般有這么幾類需求:
(1) 某種級別的日志(例如FATAL級別,或者ERROR級別的日志)一旦出現,或者超過一定頻率,就告警;
(2) 包含某些特殊含義關鍵字(例如OutOfMemory,或者Exception)的異常日志,一旦出現,或者超過一定頻率,就告警;
(3) 包含某些特殊含義關鍵字(例如Login,或者Click)的正常日志,一旦一定時間周期沒有出現,就告警;
其中,前兩類需求,屬于異常日志監控范疇,出現異常,實施告警。第三類需求,屬于正常日志監控范疇,一定的時間沒有出現“正常”,就默認異常,實施告警。
為什么不是一出現異常日志就告警呢?
避免抖動引起的誤報,一般到達一定頻率才會告警,這屬于告警策略的一部分。
為什么說,目錄與日志的規范化,是通用日志監控的前提?
這是一個線上模塊的目錄示例:
- 有源代碼:hello.c
- 有可執行文件:a.out
- 有配置文件:hello.conf
- 有備份日志:hello.log.2018012812
- 有日志:hello.log
- 有臨時文件:tmp
體會一下,運維同學看到這樣的線上文件部署,是什么感受?
畫外音:沒見過源代碼直接部署到線上的?
有什么常見的目錄規范呢?
目錄規范化不但對日志監控,對自動化運維都極為重要,要是線上目錄都瞎搞,幾乎沒有辦法實現自動化運維。
常見的目錄規范有兩類:
- 模塊優先類目錄規范;
- 功能優先類目錄規范;
什么是模塊優先的目錄規范?
如上圖,以模塊名為優先組織目錄:
- 根目錄下,有das,entry,logic三個模塊目錄;
- 在模塊目錄下,又分別有存放可執行文件,配置文件,日志文件的bin目錄,conf目錄,以及log目錄;
什么是功能優先的目錄規范?
如上圖,以功能為優先組織目錄:
- 根目錄下,二進制目錄bin,配置文件目錄conf,日志目錄log;
- 功能目錄下,有das,entry,logic等不同模塊的目錄;
樓主旗幟鮮明的推薦第二種,功能優先的目錄規范,對二進制備份,配置備份,日志清理都非常方便。
有什么常見的日志規范呢?
日志規范化不但對日志監控,對大數據體系建設都極為重要,需要考慮規范:
(1) 日志分級規范:不同級別的日志理應打到不同的文件中,例如FATAL級,ERROR級,WARM級,LOG級,INFO級,DEBUG級:
- fatal.log
- error.log
- info.log
- debug.log
- …
(2) 日志切分規范:運維應該提供自動化的日志切分工具,支持小時級別,或者天級別的日志切分,曾經看過一個120G的access日志,從日志中grep出某個uid的日志,是極其低效的:
- daojia.log.2018012800
- daojia.log.2018012801
- …
- daojia.log.2018012823
(3) 日志格式規范:日志格式規范是一個可展開的話題,此處不展開;
畫外音:是不是有小伙伴在思考,ca,自己怎么沒有這三類規范呢?
通用可擴展日志監控框架,有什么思路?
制訂了目錄規范,日志規范之后,要建立日志監控框架,實施異常與正常的日志監控,就簡單多了,主要有集中式監控,分散式監控兩類思路。
什么是集中式日志監控?
集中式的日志監控,最流行的莫過于ELK:
- 各個機器節點上部署logstash,收集日志;
- 收集的日志匯總到ES;
- 通過Kibana做統一分析和展現;
運維的同學對這一套集中式日志監控系統非常熟悉。
什么是分散式日志監控?
ELK有點重,三套系統搭建與運維起來比較麻煩,如果只是為了實現ERROR日志的監控,異常關鍵字監控,正常關鍵字監控,有點殺雞用牛刀了。
與集中式的日志監控相比,分散式的日志監控,就顯得輕量級許多,非常適用與早期的創業型公司,其思路為:
- 通過日志監控模塊,對不同集群,進行ERROR日志閾值設置,進行異常關鍵字設置,正常關鍵字設置;
- 日志監控中心模塊,進行統一調度,將配置分發到不同機器的agent節點上;
- agent節點模塊,并不統一收集日志,而是接收到監控中心分發的log監控配置,在各個機器上實施日志監控,如果觸發日志監控策略,立刻發起告警;
與ELK相比,這個日志監控框架會簡單的多,而且擴展性非常好。
如何半天搞定日志監控框架?
整個框架設計如上,大致分為三個部分:
(1)被監控集群;
(2)基礎信息與服務;
- cluster.info.xml:存儲集群信息
- owner.info.xml:存儲集群責任人信息
- mail.service/SM.service:告警基礎服務
(3)日志監控框架; 集群信息與負責人信息,與前文描述的一樣。
集群配置cluster.info.conf
- [daojia_main]
- ip.list : ip1, ip2, ip3
- log.path : /home/work/log/daojia_main/
- owner.list : shenjian, zhangsan
- [daojia_user]
- ip.list : ip4, ip5, ip6
- log.path : /home/work/log/daojia_user/
- owner.list : shenjian
責任人配置owner.info.conf
- [shenjian]
- email : XX@XX.com
- phone :15912345678
- [zhangsan]
- email : YY@YY.com
- phone :18611220099
日志監控框架又分為兩個模塊:
可擴展監控配置文件log.monitor.conf
- [log.monitor.item]
- cluster.name : daojia_main
- # error日志監控,每分鐘超過此閾值就告警
- error.log. threshold : 10
- # 異常關鍵字監控,日志出現這些關鍵字就告警
- bad.key : exeption | timeout | coredump
- # 正常關鍵字監控,日志每分鐘不出現這些關鍵字就告警
- good.key : login | user | click
- [log.monitor.item]
- cluster.name : daojia_user
- error.log.threshold : 10
日志監控調度框架,這里需要編碼啦,偽代碼如下:
- Array[log-monitor] A1= Parse(log.monitor.config);
- Array[cluster-info] A2= Parse(cluster.info.config);
- Array[owner-info] A3= Parse(owner.info.config);
- // 遍歷所有監控項
- for(each item in A1){
- //取出監控項的集群名,閾值,異常/正常關鍵詞
- clusterName= item.clusterName;
- threshold= item.threshold;
- badKey= item.badkey;
- goodKey= item.goodkey;
- //由集群名,獲取集群信息
- clusterInfo= A2[clusterName];
- //獲取日志目錄,集群ip列表,集群負責人列表
- logPath= clusterInfo.path;
- List<String>ips = clusterInfo.ip;
- List<String>owners = clusterinfo.owner;
- //集群內的每一個ip實例,都需要日志監控
- for(each ip in ips){
- //登錄到這一臺機器
- ssh $ip
- //跳到相關的目錄下
- cd $logPath
- //查看近一分鐘error日志數量
- $count= `grep $time error.log | wc -l`
- //查看badkey與goodkey
- $boolBad= `grep $badkey *`
- $boolGood= `grep $goodkey *`
- if($count< threshold &&
- $boolBad==NO &&
- $boolGood==YES){
- //正常,繼續監控
- continue;
- }
- // 否則,對所有集群負責人發送告警
- for(each owner in owners){
- // 略…
- }
- }
- }
一個簡單的調度框架,看明白了嗎?
【本文為51CTO專欄作者“58沈劍”原創稿件,轉載請聯系原作者】