本文將會介紹如何使用 Flume乃沙、log4j展辞、Kafka進行規(guī)范的日志采集铅鲤。
Flume 基本概念
Flume是一個完善划提、強大的日志采集工具,關(guān)于它的配置邢享,在網(wǎng)上有很多現(xiàn)成的例子和資料鹏往,這里僅做簡單說明不再詳細贅述。
Flume包含Source骇塘、Channel伊履、Sink三個最基本的概念:
Source——日志來源,其中包括:Avro Source款违、Thrift Source唐瀑、Exec Source、JMS Source插爹、Spooling Directory Source哄辣、Kafka Source、NetCat Source赠尾、Sequence Generator Source力穗、Syslog Source、HTTP Source气嫁、Stress Source当窗、Legacy Source、Custom Source寸宵、Scribe Source以及Twitter 1% firehose Source崖面。
Channel——日志管道,所有從Source過來的日志數(shù)據(jù)都會以隊列的形式存放在里面梯影,它包括:Memory Channel巫员、JDBC Channel、Kafka Channel甲棍、File Channel疏遏、Spillable Memory Channel、Pseudo Transaction Channel、Custom Channel财异。
Sink——日志出口,日志將通過Sink向外發(fā)射唱遭,它包括:HDFS Sink戳寸、Hive Sink、Logger Sink拷泽、Avro Sink疫鹊、Thrift Sink、IRC Sink司致、File Roll Sink拆吆、Null Sink、HBase Sink脂矫、Async HBase Sink枣耀、Morphline Solr Sink、Elastic Search Sink庭再、Kite Dataset Sink捞奕、Kafka Sink、Custom Sink拄轻。
基于Flume的日志采集是靈活的颅围,我們可以看到既有Avro Sink也有Avro Source,既有Thrift Sink也有Thrift Source恨搓,這意味著我們可以將多個管道處理串聯(lián)起來院促,如下圖所示:
串聯(lián)的意義在于,我們可以將多個管道合并到一個管道中最終輸出到同一個Sink中去斧抱,如下圖:
上面講述了Source和Sink的作用常拓,而Channel的作用在于處理不同的Sink,假設(shè)我們一個Source要對應(yīng)多個Sink夺姑,則只需要為一個Source建立多個Channel即可墩邀,如下所示:
rce如果想要輸出到多個Sink中去,就需要建立多個Channel進行介入并最終輸出盏浙,通過上面這幾張圖眉睹,我們可以很好的理解Flume的運行機制,我們在這里也就點到為止废膘,詳細的配置可以在官網(wǎng)或者在網(wǎng)上搜索到竹海、查看到。
一般情況下丐黄,我們使用 Exec Source對log文件進行監(jiān)控斋配,這樣做確實是比較簡單,但是并不方便,我們需要在每一臺要監(jiān)控的服務(wù)器上部署Flume艰争,對運維來講萬一目標日志文件發(fā)生IO異常(例如格式改變坏瞄、文件名改變、文件被鎖)甩卓,也是很痛苦的鸠匀,因此我們最好能讓日志直接通過Socket發(fā)送出去,而不是存放在本地逾柿,這樣一來缀棍,不僅降低了目標服務(wù)器的磁盤占用,還能夠有效的防止文件IO異常机错,而Kafka就是一個比較好的解決方案爬范,具體的架構(gòu)如下圖所示:
由上圖可以看到,日志最終流向了兩個地方:HBase Persistence和Realtime Processor弱匪,而至于為什么不用Kafka直接與Storm進行通信的原因是為了將Sotrm邏輯和日志源通過Flume進行隔離青瀑,在Storm中對日志進行簡單的分析后,將結(jié)果扔進 Rabbit MQ 中供 WEB APP消費痢法。
HBase Persistence就是將原始的日志記錄在HBase中以便回檔查詢狱窘,而Realtime Processor則包含了實時的日志統(tǒng)計以及錯誤異常郵件提醒等功能。
為了能夠準確的捕獲到異常數(shù)據(jù)财搁,我們還需要對程序進行一些規(guī)范化的改造蘸炸,例如提供統(tǒng)一的異常處理句柄等等。
日志輸出格式
{"timeMillis" : 1462712870612,"thread" : "main","level" : "FATAL","loggerName" : "com.banksteel.log.demo.log4j2.Demo","message" : "發(fā)生了一個可能會影響程序繼續(xù)運行下去的異常尖奔!","thrown": {"commonElementCount" : 0,"localizedMessage" : "錯誤消息啊","message" : "錯誤消息啊","name" : "java.lang.Exception","extendedStackTrace": [ {"class" : "com.banksteel.log.demo.log4j2.Demo","method" : "main","file" : "Demo.java","line" : 20,"exact" :true,"location" : "classes/","version" : "?"}, {"class" : "sun.reflect.NativeMethodAccessorImpl","method" : "invoke0","file" : "NativeMethodAccessorImpl.java","line" : -2,"exact" :false,"location" : "?","version" : "1.7.0_80"}, {"class" : "sun.reflect.NativeMethodAccessorImpl","method" : "invoke","file" : "NativeMethodAccessorImpl.java","line" : 57,"exact" :false,"location" : "?","version" : "1.7.0_80"}, {"class" : "sun.reflect.DelegatingMethodAccessorImpl","method" : "invoke","file" : "DelegatingMethodAccessorImpl.java","line" : 43,"exact" :false,"location" : "?","version" : "1.7.0_80"}, {"class" : "java.lang.reflect.Method","method" : "invoke","file" : "Method.java","line" : 606,"exact" :false,"location" : "?","version" : "1.7.0_80"}, {"class" : "com.intellij.rt.execution.application.AppMain","method" : "main","file" : "AppMain.java","line" : 144,"exact" :true,"location" : "idea_rt.jar","version" : "?"} ]
},"endOfBatch" :false,"loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger","source": {"class" : "com.banksteel.log.demo.log4j2.Demo","method" : "main","file" : "Demo.java","line" : 23}
}
我們看到搭儒,這種格式,無論用什么語言都能輕松解析了提茁。
日志框架的Kafka集成
我們這里只用log4j 1.x 和 log4j 2.x 進行示例淹禾。
http://www.linuxidc.com/Linux/2016-05/131402.htm