使用log4j將資料流入flume

upupfeng發表於2020-08-23

最近做了一個log抽取的專案,採用log4j+flume實現,在此分享記錄一下。

準備

什麼是flume?

flume是一個提供高可用的,高可靠的,分散式的海量日誌採集、聚合和傳輸的系統。

flume提供了source、channel、sink三個元件,實現資料的抽取載入。一組source、channel、sink組成一個agent同步資料,可以通過並聯、串聯agent的方式來靈活的實現資料抽取。

更多flume的文章可參考:Flume系列文章

log4j+flume

log4j和flume整合,官方提供了兩種appender將log4j的日誌寫入flume,分別是Log4J AppenderLoad Balancing Log4J Appender

Log4J Appender

Log4J Appender將log資料傳送到flume的一個avro source中,在flume中可以根據需求在下游接不同的sink。

Log4j Appender使用時,有以下的配置引數(加粗的是必須的):

引數名 預設值 描述
Hostname source的host地址,如:110.110.110.100
Port source的監聽埠,如:9999
UnsafeMode false 如果為true,則新增程式不會在傳送事件失敗時引發異常。
AvroReflectionEnabled false 使用Avro Reflection序列化Log4j事件。
AvroSchemaUrl avro schema的url地址

Load Balancing Log4J Appender

將log資料傳送到flume的多個avro source中。實現負載均衡。

使用時,有以下的配置引數(加粗的是必須的):

引數名 預設值 描述
Hosts sources的host:port。是以空格分隔的。如:10.10.10.10:9999 10.10.10.11:9999
Selector ROUND_ROBIN 選擇機制。必須為ROUND_ROBIN,RANDOM或自定義FQDN。
MaxBackoff 表示負載均衡客戶端將從未能消耗事件的節點退出的最長時間(以毫秒為單位)。
UnsafeMode false 如果為true,則新增程式不會在傳送事件失敗時引發異常。
AvroReflectionEnabled false 使用Avro Reflection序列化Log4j事件。.
AvroSchemaUrl avro schema的url地址

Load Balancing Log4J Appender相當於是實現了多個Log4J Appender來實現負載均衡。在flume端,
Load Balancing Log4J Appender需要配置多個avro source來監聽輸入。

具體實現

pom依賴

<!-- https://mvnrepository.com/artifact/org.apache.flume.flume-ng-clients/flume-ng-log4jappender -->
<dependency>
    <groupId>org.apache.flume.flume-ng-clients</groupId>
    <artifactId>flume-ng-log4jappender</artifactId>
    <version>1.9.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.flume/flume-ng-sdk -->
<dependency>
    <groupId>org.apache.flume</groupId>
    <artifactId>flume-ng-sdk</artifactId>
    <version>1.9.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
    <scope>test</scope>
</dependency>

測試類

package com.upupfeng;

import org.apache.log4j.Logger;

public class Log4j2Flume {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger(Log4j2Flume.class);
        logger.info("test");
    }
}

log4j.properties

log4j.rootLogger=debug,stdout,flume

# 輸出到控制檯
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern =[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] %-5p %l - %m%n

# Log4j Appender
log4j.appender.flume=org.apache.flume.clients.log4jappender.Log4jAppender
log4j.appender.flume.Hostname=192.168.168.200
log4j.appender.flume.Port=41414
log4j.appender.flume.UnsafeMode=true
log4j.appender.flume.layout=org.apache.log4j.PatternLayout
log4j.appender.flume.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] %-5p %l - %m%n

# Load Balancing Log4J Appender
log4j.appender.flume2 = org.apache.flume.clients.log4jappender.LoadBalancingLog4jAppender
log4j.appender.flume2.Hosts = 192.168.168.200:9001 192.168.168.200:9002 192.168.168.200:9003
log4j.appender.flume2.Selector = ROUND_ROBIN
log4j.appender.flume2.MaxBackoff = 30000
log4j.appender.flume2.UnsafeMode = true
log4j.appender.flume2.Threshold=ERROR
log4j.appender.flume2.layout=org.apache.log4j.PatternLayout
log4j.appender.flume2.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] %-5p %l - %m%n

flume-conf.properties

agent的配置。Log4J Appender只需要配置一個agent;Load Balancing Log4J Appender要配置多個。

# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = avro
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 41414

# Describe the sink
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
## 事件容量
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1


對於Log4j Appender的方式,啟動一個agent等待接收,執行程式碼即可在flume的sink端獲得資料。

對於Load Balancing Log4J Appender的方式,啟動多個agent等待接收,進行負載均衡的接收資料。

參考

http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html#log4j-appender

相關文章