如何自建appender扩展Log4j框架

5 篇文章 0 订阅
  1 log4j 概述
log4j 环境包括三个主要组件:
logger(日志记录器):控制要启用或禁用哪些日志记录语句。可以对日志记录器指定如下级别: ALL  DEBUG INFO  WARN  ERROR , FATAL 
layout(布局):根据用户的愿望格式化日志记录请求。
appender:向目的地发送格式化的输出。
2 .理解 appender
log4j 框架允许向任何日志记录器附加多个 appender。可以在任何时候对某个日子记录器添加(或删除)appender。附随 log4j 分发的 appender 有多个,包括:
ConsoleAppender;FileAppender;SMTPAppender ;JDBCAppender;JMSAppender;NTEventLogAppender;SyslogAppender
也可以创建自己的自定义 appender
3.本工程设计的目标
通过自建appender类,来实现:
[1]在控制台输出日志;
[2]log文件输出日志;
[3]在应用程序中建立日志模块(在UI层表现为建立一个日志面板),输出日志;
[4]对于不同包路径下的日志独立输出(在UI层表现为分不同的面板输出)。
4.预备知识
你可以在下面2篇文章中找到Log4j的相关基础介绍。
5.项目文件分布与效果
文件分布如图一所示。我们对于com.log.one包下的所有java文件中的日志信息输出到log one模块(图二);对于com.log.two包下的所有java文件中的日志信息输出到log two模块(图四)。本文只象征性的建立了两个测试文件,分别放在两个包下。
com.log.one.LogTestOne.java
public   class  LogTestTwo {
     private   final   static  Logger  log  = Logger.getLogger(LogTestTwo. class );
     public   void  doLog() {
        log .debug( "TestTwo debug" );
        log .info( "TestTwo info" );
        log .warn( "TestTwo warn" );
        log .error( "TestTwo error" );
        log .fatal( "TestTwo fatal" );
    }
}
 
图一
 
对于应用程序中的日志模块,提供一些UI层的基本操作,包括清空(图二,图四);变灰(图三);复制到粘贴板。
The Main Text象征性的表示主应用程序的所有操作。
图二
 
图三
 
图四
 
同时在控制台输出所有日志信息。(图五)
图五
 
    同时在文本文件中输出所有日志信息。(图六)
图六
6log4j.xml
本项目使用如下日志配置文件,将其放在项目的classpath下。
public   class  LogOneAppender  extends  AppenderSkeleton{
     public  LogOneAppender() {}
     protected   void  append(LoggingEvent event) {
       LogUI. log(event);
    }
     public   void  close() {}
     public   boolean  requiresLayout() {
        return   false ;
    }
}
 
public   class  LogUI {
     private   static  LogUI  instance ;
     private   static  JFrame  frame ;
     private  Log4JMonitor  logMonitor ;
     private   static  List<Object>  logCache  =  new  ArrayList<Object>();
     public  LogUI() {
        instance  =  this ;
    }
     ///UI
     private   void  buildUI() {
        frame .addWindowListener( new  WindowAdapter() {
            public   void  windowClosing(WindowEvent e) {
              System. exit(0);
           }
       });
        frame .getContentPane().add(buildContentPanel(), BorderLayout. CENTER );
        frame .setDefaultCloseOperation(JFrame. DO_NOTHING_ON_CLOSE );
        frame .setSize(100, 75);
    }
 
     private  Component buildContentPanel() {
       JSplitPane contentSplit =  new  JSplitPane();
       contentSplit.setTopComponent( new  JTextArea( "The Main Text" ));
       contentSplit.setBottomComponent(buildLogPanel());
       contentSplit.setDividerLocation(550);
       contentSplit.setResizeWeight(1);
        return  contentSplit;
    }
 
     private  Component buildLogPanel() {
        logMonitor  =  new  Log4JMonitor();
        logMonitor .addLogArea( "log one" "com.log.one" true ).setLevel(
              Level. DEBUG );
        logMonitor .addLogArea( "log two" "com.log.two" true ).setLevel(
              Level. DEBUG );
        for  (Object message :  logCache ) {
            logMonitor .logEvent(message);
       }
        return   logMonitor ;
    }
 
     public   void  show() {
       buildUI();
        frame .setVisible( true );
    }
     Log
     public   static   synchronized   void  log( final  Object msg) {
        if  ( instance  ==  null  ||  instance . logMonitor  ==  null ) {
            logCache .add(msg);
            return ;
       }
        if  (SwingUtilities.isEventDispatchThread()) {
            instance . logMonitor .logEvent(msg);
       else  {
           SwingUtilities. invokeLater( new  Runnable() {
               public   void  run() {
                   instance . logMonitor .logEvent(msg);
              }
           });
       }
    }
     //Test Cases
     public   void  doTests(){
       LogTestOne one= new  LogTestOne();
       one.doLog();
       LogTestTwo two= new  LogTestTwo();
       two.doLog();
    }
   
     public   static   void  main(String[] args)  throws  Exception {
        frame  =  new  JFrame( "LogUI " );
       LogUI logUi =  new  LogUI();
        logUi.show();
       logUi.doTests();
    }
}
8log类的实体Log4Jmonitor
通过此类来建立日志模块。其中用到的JlogList.java(见附件)提供对日志模块的所有基本功能。addLogArea方法增加日志模块。logEvent方法对输出的日志事件类型做出判断,对该日志所属的日志模块(本实例为com.log.onecom.log.two)做出判断。
<td 230,="" 230)="" none="" repeat="" scroll="" 0%="" 50%;="" -moz-background-clip:="" -moz-initial;="" -moz-background-origin:="" -moz-background-inline-policy:="" width:="" 426.1pt;"="" valign="top" width="568" style="padding: 0cm 5.4pt; margin: 0px; border: 1pt solid windowtext;">
public   class  Log4JMonitor  extends  JTabbedPane {
     private  JLogList  defaultLogArea ;
     public  Log4JMonitor() {
        super (JTabbedPane. BOTTOM , JTabbedPane. SCROLL_TAB_LAYOUT );
    }
     public  JLogList addLogArea(String title, String loggerName,
            boolean  isDefault) {
       JLogList logArea =  new  JLogList(title);
       logArea.addLogger(loggerName, !isDefault);
       addTab(title, logArea);
        if  (isDefault)
            defaultLogArea  = logArea;
        return  logArea;
    }
     public   void  logEvent(Object msg) {
        if  (msg  instanceof  LoggingEvent) {
           LoggingEvent event = (LoggingEvent) msg;
           String loggerName = event.getLoggerName();
            for  ( int  c = 0; c < getTabCount(); c++) {
              Component tabComponent = getComponentAt(c);
               if  (tabComponent  instanceof  JLogList) {
                  JLogList logArea = (JLogList) tabComponent;
                   if  (logArea.monitors(loggerName)) {
                     logArea.addLine(msg);
                  }
              }
           }
       else   if  ( defaultLogArea  !=  null ) {
            defaultLogArea .addLine(msg);
       }
    }
     public   boolean  hasLogArea(String loggerName) {
        for  ( int  c = 0; c < getTabCount(); c++) {
           Component tabComponent = getComponentAt(c);
            if  (tabComponent  instanceof  JLogList) {
              JLogList logArea = (JLogList) tabComponent;
               if  (logArea.monitors(loggerName)) {
                   return   true ;
              }
           }
       }
        return   false ;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值