修改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

时间: 2025-01-30 09:16:02

修改Flume Log4j Appender的相关文章

使用Flume Log4j Appender正确的姿势

使用Flume Log4j Appender正确的姿势 我们使用Flume-ng的LoadBalancingLog4jAppender,将线上服务的日志实时传输到日志服务器,转交给告警系统和HDFS做存储. FLume的Log4j Appender必须使用Log4j的异步加载器,否则一旦日志服务器挂掉,将会导致应用服务器宕机. 使用过程中的坑 问题1: Flume Log4j使用异步加载器,日志服务器宕机情况导致业务系统阻塞 在阅读了Flume的RPC源码以及LoadBalancingLog4j

日志服务接入方式之loghub log4j appender

Loghub Log4j Appender介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码. Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输

Flume + Solr + log4j搭建web日志采集系统

前言 很多web应用会选择ELK来做日志采集系统,这里选用Flume,一方面是因为熟悉整个Hadoop框架,另一方面,Flume也有很多的优点. 关于Apache Hadoop Ecosystem 请点击这里. Cloudera 官方的教程也是基于这个例子开始的,get-started-with-hadoop-tutorial 并且假设我们已经了解Flume(agent, Source, Channel, Sink) , Morphline (ETL), Solr (全文检索),如果都没有了解,

log4j直接输出日志到flume

log4j直接输出日志到flume         此jar是由Cloudera的CDH发行版提供的一个工具类,通过配置,可以将log4j的日志直接输出到flume,方便日志的采集.         在CDH5.3.0版本中是:flume-ng-log4jappender-1.5.0-cdh5.3.0-jar-with-dependencies.jar         所在目录是:/opt/cloudera/parcels/CDH/lib/flume-ng/tools/ 具体使用示例 log4j

flume学习(一):log4j直接输出日志到flume

log4j.properties配置: log4j.rootLogger=INFOlog4j.category.com.besttone=INFO,flumelog4j.appender.flume = org.apache.flume.clients.log4jappender.Log4jAppenderlog4j.appender.flume.Hostname = localhostlog4j.appender.flume.Port = 44444 log4j.appender.flume.

flume hdfs-flume1.5.2希望将log4j的日志写入hdfs报错Unexpected exception from downstream.

问题描述 flume1.5.2希望将log4j的日志写入hdfs报错Unexpected exception from downstream. 1.conf文件如下 agent1.sources = source1agent1.channels = channel1agent1.sinks = snik1# sourceagent1.sources.source1.type = avroagent1.sources.source1.bind = nnodeagent1.sources.sourc

应用系统日志采集解决方案(转)

概述 基于Flume + MongoDB,对现有的多个应用系统进行日志采集. 特点 采集范围每一次用户请求的请求信息. 数据量大 尽量减少现有系统的改动 数据流图 说明: 首先考虑的结构体系,是直接在应用系统中,将日志数据写到Flume:但是现有的应用系统都是非Maven的,需要在每一个应用系统中添加20+个jar包.为避免这种情况,抽出了一层日志服务,开放webservice服务给应用系统调用,最终形成上述的体系. 日志存储 1.需要解决的问题 1.1 借助Flume,写日志到MongoDB

flume学习(三):flume将log4j日志数据写入到hdfs

在第一篇文章中我们是将log4j的日志输出到了agent的日志文件当中.配置文件如下: [plain] view plaincopy tier1.sources=source1   tier1.channels=channel1   tier1.sinks=sink1      tier1.sources.source1.type=avro   tier1.sources.source1.bind=0.0.0.0   tier1.sources.source1.port=44444   tier

java中Log4j消息只写入指定的Appender

有如下的log4j.properties配置 log4j.rootLogger=ERROR,STDOUT log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern=%d %-5p [%t] (%F:%L) - %m%n log4j.a