日誌收集十大技術細節

本文探討在大規模日誌數據收集過程當中,針對日誌文件的處理須要注意的技術細節。html

1. 通配符和目錄遞歸搜索

大多數場景下,日誌每每被分散在不一樣的目錄中,好比以日期爲名的目錄。所以,工具必需支持對目錄的遞歸搜索和某種模式匹配。java

POSIX標準定義了一組用於通配的特殊符號(Pattern Matching Notation):node

  • *:匹配一個或多個字符linux

  • ?:匹配一個字符shell

  • []:匹配一個在範圍內的字符apache

  • [!]:匹配一個不在範圍內的字符後端

shell中不少常見命令均可以應用這種模式匹配規則,好比:函數

find / -name "*.so"

做爲日誌收集工具,也須要可以作到這種匹配,從而對日誌進行初步篩選。在Unix系統中,可使用fnmatch函數實現。工具

2. 熱日誌分析

日誌的其中一個特色是:每每同時只有少數的日誌文件正在寫入,大部分日誌文件都不是正在寫入狀態。那麼在收集日誌的時候,爲了下降資源的消耗,須要有一種機制來判斷哪些是「熱更新」的日誌,只對熱更新日誌進行讀取。咱們採用的方式是,若是在若干次採樣週期內,發現讀取文件都是EOF,那麼認爲這個文件屬於冷日誌,並將其剔除出熱日誌隊列,並加入一個新的日誌文件做爲熱日誌文件,循環往復。這樣,大多數狀況下,即保證了實時性,又下降了資源的無效損耗。性能

3. 新文件檢測

對於採集一個目錄下的文件這種需求,必須要考慮到新文件增長的狀況。一般設置一個間隔時間(好比2s),對目錄進行一個遍歷,而後對比當前已經被納管的文件,看是否是新文件。若是是新文件,應馬上加入到熱文件隊列,由於新的文件每每會馬上被寫入數據。這裏採用hashmap能提升對比性能。

4. 採集點保存

程序總會由於某種緣由退出,可是採集任務每每並無結束,這個時候,程序就須要有能力記錄下一些信息,以便下一次繼續從結束的點開始工做,以防止重複採集。針對每一個文件,記錄當前讀取到的offset,並在程序退出時,及時刷寫進磁盤。

5. log rotate的探測

log rotate是經常使用的一種日誌策略。當達到rotate的條件時,當前正在寫入的文件會重命名,而且再也不寫入數據;而後建立一個新的文件來繼續寫入。當文件數量超過必定量時,將最先產生的文件刪除,這樣能防止日誌無限制暴漲形成文件系統空間浪費。

基於log rotate的特色(會產生重命名文件的狀況),日誌工具能夠經過記錄並對比inode來判斷文件是不是重命名的。

log rotate

6. 歸檔模式採集

遍歷和watch一個擁有百萬級文件個數的目錄,是件十分浪費資源的事情。由於,實際狀況下,這種目錄的數據都是歷史數據,並且不會發生變化。所以,日誌工具應當可以支持咱們稱爲歸檔模式的工做模式,這種模式下,遍歷和watch目錄將採用極低的頻次,這樣不會浪費資源。

7. 文件狀態異常

文件狀態異常是指下列可能的狀況:

  • 讀取文件的權限發生變化

  • 讀取文件時發生某種錯誤

程序應避免對這種文件「一刀切」,由於可能過一段時間文件又變成正常狀態了。因此,應當按期把有問題的文件再嘗試讀取,這樣不會遺漏。

8. 字符集的探測和轉化

在一些老的系統中,日誌的編碼格式依舊會採用本地編碼。典型的是GBK編碼的日誌。在日誌上報的過程當中,應採用統一的編碼格式。幾乎全部的系統都支持libiconv庫,這是一個可進行編碼轉化的經常使用庫。

9. 多行合併

日誌數據由應用程序生成,許多應用程序在寫入日誌的時候,一條邏輯日誌包含多行。好比下面的java異常日誌,打印出了堆棧的信息:

11 五月 2016 11:35:52,602 ERROR java.lang.IllegalArgumentException: No bean specified
    at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:632)
    at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:715)
    at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:290)
    at lib.util.BeanUtil.getBeanProperty(BeanUtil.java:184)
    at lib.comm.services.CommWebService.getResponse(CommWebService.java:173)
    at lib.comm.services.CommWebService.SendSimplePack(CommWebService.java:307)
    at lib.comm.services.CommWebService.exchange(CommWebService.java:40)
    at lib.comm.CommunicationUtil.exchange(CommunicationUtil.java:46)
    at lib.comm.CommunicationUtil.exchangeFull(CommunicationUtil.java:105)
    at lib.helper.TradeHelper.tellerBasicInfoQuery(TradeHelper.java:1520)

從日誌收集程序的角度,這裏有不少行,可是,此時若是按行來分割是徹底不行的。所以,應當提供一種能夠合併多行日誌爲一行日誌的能力。注意到這個日誌以一個時間爲開始(一般都是這樣),那麼咱們就能夠設置一個正則匹配規則,匹配到就認爲是一個邏輯日誌行的開始:

/\d{2} \S+ \d{4} \d{2}:\d{2}:\d{2},\d{3}/

這樣收集上來的日誌才便於處理和分析。經過靈活的設置正則,極大的下降了後端處理日誌的難度。

10. Follow Symbolic Link

採集器可以支持一個開關,用於設置是否對連接進行跟蹤,即讀取連接實際指向的文件或目錄。

其實,此外還有不少亮點功能值得探討,好比:

  • 對歷史的歸檔日誌(tar包),直接讀取歸檔壓縮文件,從而避免先解壓再讀取的麻煩。

  • 在通配模式下,排除(exclude)或包含(include)某些特殊日誌

相關文章
相關標籤/搜索