内蒙古java团队

j2se,j2ee开发组
posts - 139, comments - 212, trackbacks - 0, articles - 65
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

基于Log4j灵活编写日志类

Posted on 2006-12-18 08:59 帅子 阅读(2598) 评论(5)  编辑  收藏 所属分类: j2se技术专区
在进行代码开发的过程中,日志是非常重要的。如果没有日志是难以进行代码调试和排错的。
在开发过程中,我们可以选择适合自己(团队)的日志类来实现日志输出,也可以自己编写日志类来实现(也是有一定工作量的,不推荐),当然也可以选择第三方的日志类来辅助,比如Log4j等。如果开发环境是JDK1.4以上的话,可以利用JDK自带的日志类java.util.logging,也可以使用第三方的日志类;如果开发环境是JDK1.3,那就只能使用第三方的日志类,或者自行编写日志类。
本文主要介绍如何在Log4j的基础上,实现符合自己需要的日志类。
Log4j功能相当完善,一般都通过脚本配置将日志按照一定的规则输出到文件或者console上,这种做法还是比较灵活的。
但现在需求比较特殊:
1、不想把日志输出到一个确定的文件中,而希望是哪个类的日志就输出到以这个类命名的文件中(通过脚本较难实现,如何您能实现的话,请一定要告诉我,呵呵);
2、每天的日志放在以日期命名的文件夹中,比如今天是2006-12-15,那么日志所在的文件夹是061215;
3、对于每天的日志采用循环日志,日志文件最大大小为2M,超过2M就清空重写(这个功能Log4j本身是可以实现的);
4、日志输出应包含时间(这个功能Log4j本身也是可以实现的)。

下面是自行编写的LogBase类,文件名为:LogBase.java
------------------------------------------------------------------------------------------------
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;

public class LogBase {
    private static String PROPERTIES_FILE = "logconf";

    private static String LOG_PATH;

    private static String DATE_LOG_FOLDER;

    private static String LOG_LEVEL;

    private static String PATTERN_LAYOUT;

    private static long MAX_FILE_SIZE;

    private LogBase() {
    }

    public static Logger getLogInstance(String name) {
        Logger logger = Logger.getLogger(name);
        try {
            String pattern = getPatternLayout();
            RollingFileAppender appender = new RollingFileAppender(
                    new PatternLayout(pattern), createClassLogFile(name)
                            .getAbsolutePath());
            long maxfilesize = getMaxFileSize();
            appender.setMaximumFileSize(maxfilesize);
            logger.addAppender(appender);
            String level = getLogLevel();
            logger.setLevel((Level) Level.toLevel(level));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return logger;
    }

    /*
     * 在LOG_PATH下创建以当天日期为名字的文件夹
     */
    private static File createDateLogFolder() {
        LOG_PATH = getLogPath();
        if (LOG_PATH == null) {
            readLogConfigParams();
        }

        String currentdate = getCurrentDate();
        DATE_LOG_FOLDER = LOG_PATH + System.getProperty("file.separator")
                + currentdate;

        File logFolder = new File(DATE_LOG_FOLDER);
        try {
            if (!logFolder.exists()) {
                logFolder.mkdirs();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return logFolder;
    }

    private static File createClassLogFile(String classname) {
        if (DATE_LOG_FOLDER == null) {
            createDateLogFolder();
        }

        String classnameString = DATE_LOG_FOLDER
                + System.getProperty("file.separator") + classname + ".txt";
        File logFile = new File(classnameString);
        try {
            if (!logFile.exists()) {
                logFile.createNewFile();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return logFile;
    }

    private static void readLogConfigParams() {
        ResourceBundle rb = ResourceBundle.getBundle(PROPERTIES_FILE);
        LOG_PATH = rb.getString("LOG_PATH");
        LOG_LEVEL = rb.getString("LOG_LEVEL");
        PATTERN_LAYOUT = rb.getString("PATTERN_LAYOUT");
        MAX_FILE_SIZE = Long.parseLong(rb.getString("MAX_FILE_SIZE"));
    }

    private static String getLogPath() {
        return LOG_PATH;
    }

    private static String getCurrentDate() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        return df.format(new Date());
    }

    private static String getLogLevel() {
        if (LOG_LEVEL == null) {
            readLogConfigParams();
        }
        return LOG_LEVEL;
    }

    private static String getPatternLayout() {
        if (PATTERN_LAYOUT == null) {
            readLogConfigParams();
        }
        return PATTERN_LAYOUT;
    }

    private static long getMaxFileSize() {
        if (!(MAX_FILE_SIZE > 0)) {
            readLogConfigParams();
        }
        return MAX_FILE_SIZE;
    }

    public static void main(String[] args) {
        Logger logger = LogBase.getLogInstance("LogBase");
        logger.info("info");
        logger.error("error");
    }
}
------------------------------------------------------------------------------------------------
LogBase类从配置文件logconf.properties文件中读入日志存放路径,logconf.properties文件内容很简单,如下:
------------------------------------------------------------------------------------------------
LOG_PATH = D:\\logs
LOG_LEVEL = Level.DEBUG
PATTERN_LAYOUT = %-5p %d{yyyy-MM-dd HH:mm:ss} %m%n
#MaxFileSize is set to about 10M
MAX_FILE_SIZE = 10485760
------------------------------------------------------------------------------------------------
注意,LogBase类对外只提供一个public类型的方法getLogInstance(String name),其余类都是private类型的。getLogInstance方法返回的类型是Logger,在getLogInstance方法中通过addAppender指向一个RollingFileAppender类型的文件,并设置日志文件的最大大小,然后通过setLevel方法设置日志级别。LOG_LEVEL,PATTERN_LAYOUT和MAX_FILE_SIZE都从配置文件中取得。
写好这个类后,当需要使用LogBase类的时候,只要在你的源程序中加入:private static Logger logger = LogBase.getLogInstance("XXXXXX");
XXXXXX代表你的类名,然后通过logger.info()之类的进行写日志就可以了。
例如下面的测试
------------------------------------------------------------------------------------------------
import org.apache.log4j.Logger;

public class LogBaseTest {
    private static Logger logger = LogBase.getLogInstance("LogBaseTest");

    public static void main(String[] args) {
        logger.info("LogBaseTest");
    }

}
------------------------------------------------------------------------------------------------
运行结束后,请到日志路径下查找,是否出现以今天日期为名字的文件夹,并检查该文件夹里面是否有一个LogBaseTest.txt文件,看看文件里的内容是什么样子的,日志格式应该如下:
INFO  2006-12-15 13:33:36 LogBaseTest

以上的源程序和配置文件,请下载附件。
如果读者对以上的内容有任何疑问,可以和我联系,jw_ws@163.com 版权所有,严禁转载

评论

# re: 基于Log4j灵活编写日志类  回复  更多评论   

2007-07-23 11:16 by 轮子是圆的
重新发明轮子...多余

# re: 基于Log4j灵活编写日志类[未登录]  回复  更多评论   

2007-08-12 10:58 by z
怎么没有附件啊!!!!!!!!!!!!!!!!!

# re: 基于Log4j灵活编写日志类[未登录]  回复  更多评论   

2009-10-01 00:57 by jake
谢谢分享,很经典!收藏了

# re: 基于Log4j灵活编写日志类[未登录]  回复  更多评论   

2009-11-22 15:30 by cz
hao

# re: 基于Log4j灵活编写日志类  回复  更多评论   

2013-11-22 10:15 by 拆了你的轮子
@轮子是圆的
你的话,多余……

只有注册用户登录后才能发表评论。


网站导航: