搞定這個(gè)日志智能分析設(shè)計(jì),大小故障都無處可逃
?一、背景
隨著系統(tǒng)的日益復(fù)雜,生成的日志是海量的。當(dāng)發(fā)生故障時(shí),人工從海量錯(cuò)誤日志中定位異常的成本非常高,主要原因:
- 日志格式繁多,難以依靠人工劃分,而傳統(tǒng)的日志規(guī)則分類需要配置復(fù)雜的規(guī)則和正則,難以通用化;
- 日志量級(jí)大,報(bào)警多,難以定位需要關(guān)注的異常,一些無關(guān)的錯(cuò)誤日志容易掩蓋真正的問題。
日志智能分類算法可以自動(dòng)根據(jù)日志的相似性對(duì)日志進(jìn)行流式聚類,并提取其中的關(guān)鍵信息——日志模版,有效避免相似日志的無效查看,大幅節(jié)省排查時(shí)間。并且日志異常檢測(cè)可以從海量日志中發(fā)現(xiàn)潛在的異常日志模式,幫助程序快速定位異常。
二、日志智能分類
1、設(shè)計(jì)方案
最初的日志分類服務(wù)在具體的算法選用上選擇了 Drain 算法來對(duì)日志模板進(jìn)行提取。隨著業(yè)務(wù)經(jīng)驗(yàn)的累積,為了提高日志分類的準(zhǔn)確性,用兩級(jí)模型對(duì)日志進(jìn)行流式分類并生成日志模版。其中一次分類相當(dāng)于是預(yù)分類,然后把預(yù)分類結(jié)果再進(jìn)行二次分類,將預(yù)分類沒有分好的日志進(jìn)行融合,形成最終滿足預(yù)期的分類結(jié)果。
2、一次分類
一次分類使用的是一種改進(jìn)的前綴樹。
從根節(jié)點(diǎn)開始,第一層為長(zhǎng)度層,同樣長(zhǎng)度的日志進(jìn)到同一個(gè)結(jié)點(diǎn),接下來的節(jié)點(diǎn)就是根據(jù)token進(jìn)行判別,只有匹配了同樣的token的日志,才往對(duì)應(yīng)的路徑分。此外,還會(huì)設(shè)置一個(gè)閾值,當(dāng)葉子結(jié)點(diǎn)到達(dá)閾值后,會(huì)增加一個(gè)<*>結(jié)點(diǎn),用于匹配所有未成功匹配的日志。由于樹深是提前設(shè)定的,一般會(huì)設(shè)得比較小,因此匹配的速度會(huì)非???。整個(gè)樹生成和匹配的過程實(shí)際上就是一個(gè)加入長(zhǎng)度層的前綴樹。
算法流程如下:
- 預(yù)處理,以分隔符/空格為單位將日志切分為一個(gè)個(gè)的token;
- 根據(jù)日志token長(zhǎng)度去第二層(每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一個(gè)長(zhǎng)度)尋找對(duì)應(yīng)節(jié)點(diǎn),比如Receive from node 4匹配的節(jié)點(diǎn)對(duì)應(yīng)日志token長(zhǎng)度為4;
- 根據(jù)日志token按順序去進(jìn)行分裂,這里受到depth限制,分裂樹深為depth-2(去除root和length層);
- 分裂到葉子節(jié)點(diǎn)后,計(jì)算日志與各個(gè)模板的相似度simSeq,返回simSeq大于閾值st并且相似度最高的模板;
- 更新Parsetree,當(dāng)日志在葉子節(jié)點(diǎn)匹配到了模板,并且部分token有差異,則用<*>替換;當(dāng)沒有匹配到模板時(shí),則將新的日志加入到該葉子節(jié)點(diǎn)的模板列表,作為新的模版。
3、二次分類
二次分類使用的是基于最長(zhǎng)公共子序列匹配的算法。
一次分類第一層會(huì)有一個(gè)長(zhǎng)度匹配,那不同長(zhǎng)度的日志必然不會(huì)被分到一類;而且一次分類是根據(jù)token的順序一個(gè)個(gè)匹配的,計(jì)算相似度也是順序計(jì)算的,兩條很像的日志,如果僅中間某些token劃分不能對(duì)齊,就會(huì)導(dǎo)致無法分到同一類。為了克服上述問題,引入了基于最長(zhǎng)公共子序列的匹配算法,將一次分類獲得的模版進(jìn)行二次合并,獲得聚類效果更佳的模版。同時(shí),由于最長(zhǎng)公共子序列的時(shí)間復(fù)雜度較高,因此設(shè)計(jì)了前綴樹、簡(jiǎn)單循環(huán)等兩種前置預(yù)匹配方法,減少部分LCS的匹配,提升算法整體的效率。
算法流程如下:
1)預(yù)處理,以分隔符/空格為單位將日志切分為一個(gè)個(gè)的token。
2)前綴樹預(yù)匹配,可以匹配到則返回匹配的分類和模版;匹配不到轉(zhuǎn)到(3)。
3)簡(jiǎn)單循環(huán)匹配,可以匹配到則返回匹配的分類和模版;匹配不到轉(zhuǎn)到(4)。
4)計(jì)算最長(zhǎng)公共子序列,進(jìn)行LCS匹配,可以匹配到則返回匹配的分類和模版,計(jì)算更新后的模版,差異部分用<*>替換;匹配不到則新增分類和模版。
4、traceback日志的處理
traceback日志與普通日志不一樣,普通錯(cuò)誤日志以分隔符/空格來劃分token比較合適,但是traceback錯(cuò)誤日志是一個(gè)trace的結(jié)構(gòu),按行看比較合適,因此把每一行traceback日志作為一個(gè)token,這樣可以把trace類似的錯(cuò)誤聚到一起,方便查找問題。
5、解決冷啟動(dòng)問題
日志智能分類算法會(huì)比較日志和模版,保留相同部分(常量),填充差異部分(變量)為<*>,更新模版,因此天然具有提取日志公共部分的能力。但是如果直接把原始日志輸入到算法中,需要較長(zhǎng)時(shí)間才可以完成模版的收斂;且收斂后的模版與輸入的順序有很大的關(guān)系,無法獲得一個(gè)魯棒的結(jié)果。這樣會(huì)導(dǎo)致新接入的項(xiàng)目無法很好地應(yīng)用日志智能分類。但如果能提前識(shí)別出變量,提前將其填充為<*>,則可極大地提升日志模版的收斂速度,也可以獲得更加魯棒的日志模版。通過正則將數(shù)字、base64編碼和地址編碼提前填充為<*>極大地提升了模版的收斂速度,原來要一周才能穩(wěn)定并可用的模版,現(xiàn)在接入后馬上可用。
三、日志異常檢測(cè)
1、設(shè)計(jì)方案
目前業(yè)界對(duì)日志異常檢測(cè)的研究有很多,總結(jié)來說主要為以下幾類:
我們?nèi)罩井惓z測(cè)算法主要是是基于統(tǒng)計(jì)+無監(jiān)督的日志模版異常檢測(cè)算法,完全沒有人工標(biāo)注成本,計(jì)算簡(jiǎn)單并具有較好的可解釋性。目前日志異常檢測(cè)算法需要依賴日志智能分類算法,需要在獲得日志實(shí)時(shí)分類模版后,根據(jù)各模版的日志量的歷史數(shù)據(jù)進(jìn)行異常判定,從而發(fā)現(xiàn)其中的異常模式,并將對(duì)應(yīng)常通過告警發(fā)送給用戶。
2、具體算法
日志異常檢測(cè)算法設(shè)計(jì)為1min粒度的:
1)按機(jī)器維度獲取該機(jī)器的日志模版以及對(duì)應(yīng)日志量的歷史數(shù)據(jù)。
2)將不同模版的日志量歷史數(shù)據(jù)使用卡方分布進(jìn)行聚合。
3)對(duì)聚合后的數(shù)據(jù)進(jìn)行異常檢測(cè),當(dāng)發(fā)現(xiàn)異常時(shí),觸發(fā)(4),如果未發(fā)現(xiàn)異常,則返回結(jié)果為正常。
4)對(duì)每個(gè)日志模版對(duì)應(yīng)的日志量的歷史數(shù)據(jù)進(jìn)行異常檢測(cè),根據(jù)異常程度,返回Top5的異常模版。
5)如果沒有返回異常模版,則本次檢測(cè)返回結(jié)果為正常;如果返回了異常模版,則本次檢測(cè)返回結(jié)果為異常,并將異常結(jié)果、異常模版告警。
這里的異常檢測(cè)設(shè)計(jì)為兩步主要是因?yàn)椋?/p>
- 每臺(tái)機(jī)器的日志生成的模版數(shù)量都很多,對(duì)應(yīng)日志量歷史數(shù)據(jù)中噪聲也較多,直接進(jìn)行模版的異常檢測(cè)容易產(chǎn)生較多無效的報(bào)警;
- 模版數(shù)量較多,全量進(jìn)行1min粒度的異常檢測(cè)計(jì)算壓力較大,可能不能在1min內(nèi)完成檢測(cè)。因此考慮先從全局的角度設(shè)計(jì)一個(gè)噪聲較少的指標(biāo),先對(duì)該指標(biāo)進(jìn)行異常檢測(cè),當(dāng)異常檢測(cè)結(jié)果為異常后,再下鉆到具體的模版進(jìn)行異常檢測(cè),找到異常模版,既能減少誤報(bào),也可以降低CPU壓力。
設(shè)計(jì)平方和作為全局具有代表性的指標(biāo),采用卡方分布進(jìn)行數(shù)據(jù)聚合,假設(shè)n個(gè)模版的頻率特征符合標(biāo)準(zhǔn)正態(tài)分布,基于此構(gòu)建模版的平方和特征,該特征滿足卡方分布,在n較大時(shí),卡方分布可近似為正態(tài)分布,可以使用3sigma的方式進(jìn)行異常檢測(cè)。
日志異常檢測(cè)使用的異常檢測(cè)算法除了使用3sigma方法外,還使用了箱線圖的方法,將兩者的結(jié)果轉(zhuǎn)換為異常分?jǐn)?shù)后再進(jìn)行融合。
3、減少周期性誤報(bào)
周期性異常是指昨天或者上周出現(xiàn)過的同樣的異常,此類報(bào)警屬于周期性誤報(bào)。此時(shí),昨天或者上周對(duì)應(yīng)時(shí)間點(diǎn)的異常分?jǐn)?shù)也會(huì)較高,可以利用這個(gè)歷史分?jǐn)?shù)對(duì)當(dāng)前分?jǐn)?shù)進(jìn)行抑制,達(dá)到消除周期性誤報(bào)的效果。但是,出現(xiàn)異常的時(shí)間點(diǎn)可能會(huì)有一定的偏移,因此需要對(duì)昨天和上周一定時(shí)間窗口內(nèi)的分?jǐn)?shù)進(jìn)行中心rolling_max操作,再使用當(dāng)前異常分?jǐn)?shù)減去昨天或者上周較大的那個(gè)分?jǐn)?shù),得到抑制后的分?jǐn)?shù)。
4、新日志類別報(bào)警
某些情況下希望當(dāng)出現(xiàn)新的日志模版類的時(shí)候,對(duì)新日志類別進(jìn)行告警。但是當(dāng)日志智能分類結(jié)果尚未穩(wěn)定的時(shí)候,會(huì)經(jīng)常出現(xiàn)新的日志類別,有可能產(chǎn)生很多誤報(bào)。我們?cè)O(shè)計(jì)了自適應(yīng)的新日志類別報(bào)警,當(dāng)一天內(nèi)出現(xiàn)新的日志類別超過一定閾值時(shí),對(duì)新日志類別報(bào)警進(jìn)行抑制;當(dāng)?shù)陀谝欢ㄩ撝禃r(shí),進(jìn)行新日志類別的告警。
四、應(yīng)用效果
當(dāng)日志異常檢測(cè)檢測(cè)到日志異常時(shí),會(huì)告知用戶異常的模版。
進(jìn)入日志計(jì)數(shù)頁(yè)面可以看到,當(dāng)前時(shí)刻確實(shí)出現(xiàn)了異常的日志暴增。?