咱們的日誌收集系統使用Filebeat來收集日誌文件,部署時並無多想,只配置了一下監控的日誌文件名。上線幾個月,日誌監控從沒出過問題。後來想一想其實這裏面有不少點須要考慮的,沒出問題真是感謝Filebeat默認配置下想的就很周全。node
業務系統使用logback做爲日誌框架。經過查看源碼,發現logback日誌切割用的是JDK裏File#renameTo()方法。若是該方法失敗,就再嘗試使用複製數據的方式切割日誌。查找該方法相關資料得知,只有當源文件和目標目錄處於同一個文件系統、同volumn(即windows下的C, D盤)下該方法纔會成功,切不會爲重命名的後的文件分配新的inode值。也就是說,若是程序裏一直保存着該文件的描述符,那麼當程序再寫日誌時,就會向重命名後的文件中寫。那麼問題來了,filebeat是會一直打開並保存文件描述符的,那麼它是怎麼得知日誌被切割這件事的呢?windows
若是隻用當前文件描述符一路監控到天黑的話,那麼當logback把日誌重命名後,filebeat仍然會監控重命名後的日誌,新建立的日誌文件就看不到了。實際上,filebeat是經過close_inactive和scan_frequency兩個參數(機制)來應對這種狀況的:框架
close_inactive
該參數指定當被監控的文件多長時間沒有變化後就關閉文件句柄(file handle)。官方建議將這個參數設置爲一個比文件最大更新間隔大的值。好比文件最長5s更新一次,那就設置成1min。默認值爲5min.日誌
scan_frequency
該參數指定Filebeat搜索新文件的頻率(時間間隔)。當發現新的文件被建立時, Filebeat會爲它再啓動一個 harvester 進行監控。默認爲10s。部署
綜合以上兩個機制,當logback完成日誌切割後(即重命名),此時老的harvester仍然在監控重命名後的日誌文件,可是因爲該文件不會再更新,所以會在close_inactive時間後關閉這個文件的 harvester。當scan_frequency時間事後,Filebeat會發現目錄中出現了新文件,因而爲該文件啓動 harvester 進行監控。這樣就保證了切割日誌時也能不丟不重的傳輸數據。(不重是經過爲每一個日誌文件保存offset實現的)
————————————————
源碼