閱讀306 返回首頁    go 阿裏雲 go 技術社區[雲棲]


修改Flume Log4j Appender

自定義Log4j Appender

要修改Flume Log4j Appender的實現,我們先了解一下Log4j Appender是如何自定義的。

自定義log4j appender需要繼承log4j公共的基類:AppenderSkeleton

  • 打印日誌核心方法:abstract protected void append(LoggingEvent event);
  • 初始化加載資源:public void activateOptions(),默認實現為空
  • 釋放資源:public void close()
  • 是否需要按格式輸出文本:public boolean requiresLayout()
  • 正常情況下我們隻需要覆蓋append方法即可。然後就可以在log4j中使用了

Demo:

1. import org.apache.log4j.AppenderSkeleton;  
2. import org.apache.log4j.spi.LoggingEvent;  
3.   
4. public class HelloAppender extends AppenderSkeleton {  
5.   
6.     private String account ;  
7.       
8.     @Override  
9.     protected void append(LoggingEvent event) {  
10.         System.out.println("Hello, " + account + " : "+ event.getMessage());  
11.     }  
12.   
13.     @Override  
14.     public void close() {  
15.         // TODO Auto-generated method stub  
16.   
17.     }  
18.   
19.     @Override  
20.     public boolean requiresLayout() {  
21.         // TODO Auto-generated method stub  
22.         return false;  
23.     }  
24.   
25.     public String getAccount() {  
26.         return account;  
27.     }  
28.   
29.     public void setAccount(String account) {  
30.         this.account = account;  
31.     }  
32. }  

1. public static void main(String[] args) {  
2.     Log log = LogFactory.getLog("helloLog") ;  
3.     log.info("I am ready.") ;  
4. }  

log4j.properties 配置

1
2
3
4
log4j.logger.helloLog=INFO, hello

log4j.appender.hello=HelloAppender
log4j.appender.hello.account=World

執行main函數,輸出結果 Hello, World : I am ready.

修改FLume Log4j Appender

Event Header加入appname,hostname,logtype

由於hostname,logtype是固定不變的。所以直接寫死在代碼中。appname則用log4j.properties進行配置 – appname在log4j.properties中配置,添加:

1
2
#應用程序名
log4j.appender.flume.Appname = 91pc
  • 在Log4jAppender類中添加:
1
2
3
4
5
6
7
8
9
private String appname;

public String getAppname() {
  return appname;
}

public void setAppname(String appname) {
  this.appname = appname;
}
  • hostname,logtype在Log4jAppender類中添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//author:scy
try {
  hdrs.put("hostname", InetAddress.getLocalHost()+"");
} catch (UnknownHostException e1) {
      String msg = "Cant't get localhost IP";
      LogLog.error(msg);
      if (unsafeMode) {
        return;
      }
      throw new FlumeException(msg + " Exception follows.", e1);
}
//author:scy Need to alarm(>Info)
if(event.getLevel().toInt() > 20000){
  hdrs.put("logtype", "alarm");
}else{
  hdrs.put("logtype", "log4j");
}

Flume Log4j Appender添加log4j的異常詳細信息

由於Flume Log4j Appender並沒有將Log4j的錯誤異常棧詳細信息封裝到Event中,不利於我們的告警係統分析原因。 Log4jAppender.append()中添加如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Event flumeEvent;
Object message = event.getMessage();
if (message instanceof GenericRecord) {
..
} else {
  hdrs.put(Log4jAvroHeaders.MESSAGE_ENCODING.toString(), "UTF8");
  //按照log4j.properties配置格式化日誌
  String msg = layout != null ? layout.format(event) : message.toString();
        
  //author:edwardsbean
  if(layout.ignoresThrowable()) {
      String[] s = event.getThrowableStrRep();
      if (s != null) {
  int len = s.length;
  for(int i = 0; i < len; i++) {
      msg += s[i];
      msg += Layout.LINE_SEP;
  }
    }
  }
  
  flumeEvent = EventBuilder.withBody(msg, Charset.forName("UTF8"), hdrs);
}
try {
  rpcClient.append(flumeEvent);

日誌接收端就可以接受到日誌的詳細信息:

1
2
3
 [x] Received '2013-12-26 10:38:08 user log detail
 [nd-PC2600/192.168.253.126] FATAL [com.xx.test.Main] java.lang.Exception: error detail
  at com.xx.test.Main.main(Main.java:35)

Posted by EdwardsBean Dec 26th, 2013  Flume

最後更新:2017-04-03 12:54:48

  上一篇:go 絕對精彩的馬字成語接龍40龍
  下一篇:go Android實現兩次按下返回鍵退出