山寨版Log4j
 
手动实现log4j类似的功能,使用方式、配置和log4j基本一样,原因是不想依赖第三方包,超轻量级的日志工具。
 
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* 日志工厂
*
* @author: leizhimin 2010-5-27 10:01:47
*/

public class LogFactory {
        public static final String ROOT_LOGGER_NAME = "root";
        private static Map<String, Logger> reg = new HashMap<String, Logger>();
        private static Logger rootLogger = Logger.getLogger("rootlogger");
        private static String level = "INFO";
        private static String logFilePath = "log%g.log";
        private static int max_size = 1;
        private static int max_number = 10;
        private static Level logLevel = Level.ALL;
        private static Handler logHandler = null;

        static {
                rootLogger.setLevel(Level.ALL);
                InputStream in = LogFactory.class.getResourceAsStream("/logger.properties");
                Properties prop = new Properties();
                try {
                        prop.load(in);
                        level = prop.getProperty("logger.level", "INFO");
                        logFilePath = prop.getProperty("logger.dir.file", "log%g.log");
                        max_size = Integer.parseInt(prop.getProperty("logger.file.maxsize", "1"));
                        max_number = Integer.parseInt(prop.getProperty("logger.file.maxnumber", "10"));
                        initLevel();
                        initFileHandler();
                        rootLogger.setLevel(logLevel);
                        setLogHandler(rootLogger);
                } catch (IOException e) {
                        rootLogger.severe("系统找不到指定的日志配置文件logger.properties");
                        e.printStackTrace();
                }
                reg.put("root", rootLogger);
        }

        /**
         * 根据类类型对象获取Logger,与Log4j保持一致
         *
         * @param clazz 类类型对象
         * @return 一个Logger对象
         */

        public static Logger getLog(Class clazz) {
                Logger log = null;
                String name = "root";
                if (clazz != null) {
                        Package pkg = clazz.getPackage();
                        if (pkg != null) name = pkg.getName();
                }
                if (reg.containsKey(name)) return reg.get(name);
                else {
                        log = Logger.getLogger(name);
                        log.setLevel(logLevel);
                        setLogHandler(log);
                        reg.put(name, log);
                }
                return Logger.getLogger(name);
        }

        /**
         * 获取根Logger对象,不建议使用,主要用于测试
         *
         * @return 根Logger对象
         */

        public static Logger getRootLogger() {
                return rootLogger;
        }

        private static void initLevel() {
                Level lev = Level.ALL;
                if (level.equalsIgnoreCase("ERROR")) logLevel = Level.SEVERE;
                else if (level.equalsIgnoreCase("WARN")) logLevel = Level.WARNING;
                else if (level.equalsIgnoreCase("INFO")) logLevel = Level.INFO;
                else if (level.equalsIgnoreCase("DEBUG")) logLevel = Level.ALL;
        }

        private static Logger setLogHandler(Logger logger) {
                for (Handler h : logger.getHandlers()) {
                        logger.removeHandler(h);
                }
                logger.addHandler(logHandler);
                return logger;
        }

        private static void initFileHandler() {
                try {
                        logHandler = new FileHandler(logFilePath, 1024 * max_size, max_number, true);
                } catch (IOException e) {
                        rootLogger.severe("日志文件路径" + logFilePath + "错误,请检查!");
                        e.printStackTrace();
                }
                logHandler.setLevel(Level.INFO);
                logHandler.setFormatter(LogFormatter.instance());
        }
}
 
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.Date;
import java.text.SimpleDateFormat;

/**
* 日志格式
*
* @author: leizhimin 2010-5-27 11:43:47
*/

public class LogFormatter extends Formatter {
        public static SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
        private static LogFormatter instance    = new LogFormatter();

        @Override
        public String format(LogRecord record) {
                String logname = record.getLoggerName();
                if (logname.equalsIgnoreCase(LogFactory.ROOT_LOGGER_NAME)) logname = "";
                return sf.format(new Date()) + " " + record.getLevel() + ": " + record.getLoggerName() + "    " + record.getMessage() + "\n";
        }
        public static LogFormatter instance(){
                return instance;
        }
}
 
logger.properties
#日志级别
logger.dir.filelogger.level=INFO
#日志文件名称
logger.dir.file=C:\\log\\log%g.log
#日志文件最大尺尺寸(单位:MB)
logger.file.maxsize=5
#日志文件的最大数量
logger.file.maxnumber=10
 
测试后打开输出的日志文件:
2010-05-28 10:56:45 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 1 次扫描开始,开始时间:2010-05-28 10:56:45 --------------
2010-05-28 10:56:45 INFO: com.lavasoft.commons.logger.Test     第 1次扫描执行失败,扫描彩信0条!耗时0秒!
2010-05-28 10:56:45 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 1 次扫描结束,结束时间:2010-05-28 10:56:45 --------------
2010-05-28 10:56:45 INFO: com.lavasoft.commons.logger.Test    因为本次没有扫描到可执行的任务,程序即将休眠10秒!
2010-05-28 11:04:33 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 1 次扫描开始,开始时间:2010-05-28 11:04:33 --------------
2010-05-28 11:04:33 INFO: com.lavasoft.commons.logger.Test     第 1次扫描执行失败,扫描彩信0条!耗时0秒!
2010-05-28 11:04:33 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 1 次扫描结束,结束时间:2010-05-28 11:04:33 --------------
2010-05-28 11:04:33 INFO: com.lavasoft.commons.logger.Test    因为本次没有扫描到可执行的任务,程序即将休眠10秒!
2010-05-28 11:04:43 INFO: com.lavasoft.commons.logger.Test    因为执行过程出错,程序即将休眠5秒!
2010-05-28 11:04:48 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 2 次扫描开始,开始时间:2010-05-28 11:04:48 --------------
2010-05-28 11:04:48 INFO: com.lavasoft.commons.logger.Test     第 2次扫描执行失败,扫描彩信0条!耗时0秒!
2010-05-28 11:04:48 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 2 次扫描结束,结束时间:2010-05-28 11:04:48 --------------
2010-05-28 11:04:48 INFO: com.lavasoft.commons.logger.Test    因为本次没有扫描到可执行的任务,程序即将休眠10秒!
2010-05-28 11:04:58 INFO: com.lavasoft.commons.logger.Test    因为执行过程出错,程序即将休眠5秒!
2010-05-28 11:05:03 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 3 次扫描开始,开始时间:2010-05-28 11:05:03 --------------
2010-05-28 11:05:03 INFO: com.lavasoft.commons.logger.Test     第 3次扫描执行失败,扫描彩信0条!耗时0秒!
2010-05-28 11:05:03 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 3 次扫描结束,结束时间:2010-05-28 11:05:03 --------------
2010-05-28 11:05:03 INFO: com.lavasoft.commons.logger.Test    因为本次没有扫描到可执行的任务,程序即将休眠10秒!
2010-05-28 11:05:26 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 1 次扫描开始,开始时间:2010-05-28 11:05:26 --------------
2010-05-28 11:05:26 INFO: com.lavasoft.commons.logger.Test     第 1次扫描执行失败,扫描彩信0条!耗时0秒!
2010-05-28 11:05:26 INFO: com.lavasoft.commons.logger.Test    >>>>>> 第 1 次扫描结束,结束时间:2010-05-28 11:05:26 --------------
2010-05-28 11:05:26 INFO: com.lavasoft.commons.logger.Test    因为本次没有扫描到可执行的任务,程序即将休眠10秒!
 
截图:
 
呵呵,和log4j输出的一样吧!
 
实现很简单,功能也满足日常需要,欢迎交流