首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

仿log4j定做自己的Log工具类

2012-09-10 
仿log4j定制自己的Log工具类原由:log4j是很强大,可每次使用还要加入log4j包,还要使用配置文件。对于一般的

仿log4j定制自己的Log工具类

原由:

log4j是很强大,可每次使用还要加入log4j包,还要使用配置文件。对于一般的小工具或小项目感觉还是有点大动作了。而且在使用log4j时每次还要每取个实例再传个参数来记录,感觉有点麻烦。就自己仿log4j使用jdk logger定制了一个自己的记录工具类。

?

工具类特点:

无配置文件,默认为info级别,控制台输出,无需改动即可满足一般开发需要。。 直接打log,在java文件中直接使用 Log.info("test"); 即可,如果输出到文件,则自动按不同级别生成不同记录文件 使用四个级别的log。分别为 Log.debug(""); Log.info(""); Log.warn(""); Log.error(""); 对于一般项目已经足够。 log输出方式有两种,控制台输出和文件输出。输出格式两者统一。文件输出时的文件路径可定制。默认为class文件夹下,名称格式为 等级_时间.log 如: INFO_2011-10-12.log
工具类的使用:直接默认配置
   Log.debug("debug");        Log.info("info");        Log.info("info1");        Log.warn("warn");        Log.error("error");        try {            throw new Exception("exception");        } catch (Exception e) {            Log.error(e);        }
?结果:2012-03-02 16:25:03 NewClass.java(Line:19): [INFO] info2012-03-02 16:25:03 NewClass.java(Line:20): [INFO] info12012-03-02 16:25:03 NewClass.java(Line:21): [WARN] warn2012-03-02 16:25:03 NewClass.java(Line:22): [ERROR] error2012-03-02 16:25:03 NewClass.java(Line:26):?java.lang.Exception: exceptionat com.dfhstudio.thoughtfly.util.NewClass.main(NewClass.java:24)
要想使用文件记录,要改点代码变量,看javadoc注释


费话不说,直接上代码
import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import java.io.StringWriter;import java.nio.channels.FileChannel;import java.nio.channels.FileLock;import java.security.AccessController;import java.security.PrivilegedAction;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.logging.ConsoleHandler;import java.util.logging.ErrorManager;import java.util.logging.Formatter;import java.util.logging.Handler;import java.util.logging.Level;import java.util.logging.LogManager;import java.util.logging.LogRecord;import java.util.logging.Logger;import java.util.logging.StreamHandler;/** *  <b>自定义LOG工具,丁风华</b> * <ul> * <b>特点</b> * <li>无配置文件,默认为info级别,控制台输出,无需改动即可满足一般开发需要。。</li> * <li>直接打log,在java文件中直接使用 <code>Log.info("test");</code> 即可,如果输出到文件,则自动按不同级别生成不同记录文件</li> * <li>使用四个级别的log。分别为 <code>Log.debug(""); Log.info(""); Log.warn(""); Log.error("");</code> 对于一般项目已经足够。</li> * <li>log输出方式有两种,控制台输出和文件输出。输出格式两者统一。文件输出时的文件路径可定制。默认为class文件夹下,名称格式为 等级_时间.log 如: INFO_2011-10-12.log</li> * </ul> * <ul> * <b>输出到文件使用方法</b><br> * 更改构造器方法中的数据. private Log()<br> * 1.设置输出级别: setLogLevel("info");<br> * 2.设置输出到文件: HANDLER_FILE = true;<br> * 3.设置设置文件保存路径: LOG_FILE_PATH = "D:\\log\";<br> * 4.设置每个文件的最大值: FILE_SIZE = 2000000; // *** 每个文件最大2M <br> * 5.设置每天最多生成多少个文件数量: FILE_MAX = 10; // *** 每天最多生成10个文件,最多不可超过100<br> * 6.设置log文件后缀名: LOG_FILE_LASTNAME = ".log"; * </ul> * <ul> * <b>更改记录内容的格式</b><br> * 可更改 dealInfoFormat 方法中的 formatMessage 变量值即可。 * </ul> *  * @author DingFengHua */public class Log {    private Log() {        setLogLevel("INFO");        HANDLER_CONSOLE = true; // *** 控制台输出        HANDLER_FILE = false; // *** 文件输出        // *** 如果不想使用文件打LOG,即 HANDLER_FILE = false;,则不用关心以下数据        // *** 自动创建路径文件夹        if (HANDLER_FILE) {            // *** 1. LOG文件夹在class文件夹目录下            // LOG_FILE_PATH = new File(Log.class.getClassLoader().getResource(".").getFile()).toString() + "/log/";            // *** 2. 如果是web项目,LOG文件夹在项目根目录下            LOG_FILE_PATH = new File(Log.class.getClassLoader().getResource("/").getFile()).toString() + "/../../log/";            FILE_SIZE = 2000000; // *** 每个文件最大2M            FILE_MAX = 10; // *** 每天最多生成10个文件,最多不可超过100            LOG_FILE_LASTNAME = ".log"; // *** 文件后缀名        }    }    /*     * 以下内容不必更改**********************************************************************************************************     */    /* ************************************************************************************************************************* */    private String getLogFileName(String level) {        String firtFileName = LOG_FILE_PATH + level + "_" + getDateFormat("yyyy-MM-dd", new Date()) + LOG_FILE_LASTNAME;        return firtFileName;    }    /**     * 从字符串转换为JDKLOG的LEVEL等级     *      * @param strLevel 自定义的等级字符串     * @return JDKLOG的等级     */    private Level getLogLevelFromString(String strLevel) {        Level l = Level.INFO;        if (LEVEL_DEBUG.equalsIgnoreCase(strLevel)) {            l = Level.FINE;        }        if (LEVEL_WARN.equalsIgnoreCase(strLevel)) {            l = Level.WARNING;        }        if (LEVEL_ERROR.equalsIgnoreCase(strLevel)) {            l = Level.SEVERE;        }        return l;    }    /**     * 低等级记录     *      * @param info 记录信息     */    public static void debug(String info) {        INSTANCE.log(LEVEL_DEBUG, "[" + LEVEL_DEBUG + "] " + info, null);    }    /**     * 普通信息记录     *      * @param info 记录信息     */    public static void info(String info) {        INSTANCE.log(LEVEL_INFO, "[" + LEVEL_INFO + "] " + info, null);    }    /**     * 警告信息记录     *      * @param info 记录信息     */    public static void warn(String info) {        INSTANCE.log(LEVEL_WARN, "[" + LEVEL_WARN + "] " + info, null);    }    /**     * 错误信息记录     *      * @param info 记录信息     */    public static void error(String info) {        INSTANCE.log(LEVEL_ERROR, "[" + LEVEL_ERROR + "] " + info, null);    }    /**     * 错误信息记录     *      * @param info 异常     */    public static void error(Throwable info) {        INSTANCE.log(LEVEL_ERROR, "", info);    }    /**     * 处理记录信息     *      * @param level 信息等级     * @param info  信息内容     * @param exception  异常信息     */    private void log(String level, String info, Throwable exception) {        checkFileDate(level);        Logger logger = Logger.getLogger(level);        if (!logList.contains(level)) {            logList.add(level);            dealHander(logger);            dealInfoFormat(logger);        }        logger.setLevel(logOutPutLevel);        logger.log(getLogLevelFromString(level), info, exception);    }    /**     * 内容格式化,默认内容格式为 时间 文件名(行数):[等级] 内容     *      * @param logger JDK Log     */    private void dealInfoFormat(Logger logger) {        logger.setUseParentHandlers(false);        StackTraceElement[] stackTraceElement = Thread.currentThread().getStackTrace();        final StackTraceElement element = stackTraceElement[stackTraceElement.length - 1];        for (Handler handler : logger.getHandlers()) {            handler.setFormatter(new Formatter() {                @Override                public String format(LogRecord record) {                    StringBuilder formatMessage = new StringBuilder();                    formatMessage.append(getDateFormat("yyyy-MM-dd HH:mm:ss", new Date()));                    formatMessage.append(" ").append(element.getFileName()).append("(Line:")                                    .append(element.getLineNumber()).append("):").append(" ")                                    .append(record.getMessage()).append("\n");                    if (record.getThrown() != null) {                        try {                            StringWriter sw = new StringWriter();                            PrintWriter pw = new PrintWriter(sw);                            record.getThrown().printStackTrace(pw);                            pw.close();                            formatMessage.append(sw.toString());                        } catch (Exception ex) {                        }                    }                    return formatMessage.toString();                }            });        }    }    /**     * 输出处理,控制台和文件,文件输出的文件名格式为 等级_yyyy-MM-dd.log 如果有多个文件,会在文件名后递增数字     *      * @param logger jdk log     */    private void dealHander(Logger logger) {        boolean alreadyHasConsole = false, alreadyHasFile = false;        Handler[] handlers = logger.getHandlers();        for (int i = 0; i < handlers.length; i++) {            if (handlers[i] instanceof ConsoleHandler) {                alreadyHasConsole = true;            } else if (handlers[i] instanceof MyFileHandler) {                alreadyHasFile = true;            }        }        if (HANDLER_CONSOLE && !alreadyHasConsole) {            ConsoleHandler ch = new ConsoleHandler();            ch.setLevel(logOutPutLevel);            logger.addHandler(ch);        }        if (HANDLER_FILE && !alreadyHasFile) {            String file = getLogFileName(logger.getName());            File f = new File(LOG_FILE_PATH);            if (!f.isDirectory()) {                f.mkdirs();                f.mkdir();            }            try {                MyFileHandler fh = new MyFileHandler(file, FILE_SIZE, FILE_MAX, true);                fh.setLevel(logOutPutLevel);                logger.addHandler(fh);            } catch (IOException ex) {                Logger.getLogger(Log.class.getName()).log(Level.SEVERE, null, ex);            } catch (SecurityException ex) {                Logger.getLogger(Log.class.getName()).log(Level.SEVERE, null, ex);            }        }    }    /**     * 格式化时间到字符串     *      * @param pattern 格式     * @param date 时间     * @return 格式化的字符串     */    private String getDateFormat(String pattern, Date date) {        format.applyPattern(pattern);        return format.format(date);    }    /**     * 设置输出等级     *      * @param level 自定义等级,可使用 debug,info,warn,error 忽略大小写     */    public final void setLogLevel(String level) {        logOutPutLevel = getLogLevelFromString(level);    }    private void checkFileDate(String level) {        File f = new File(getLogFileName(level));        if (!f.exists()) {            for (Handler handler : Logger.getLogger(level).getHandlers()) {                handler.close();            }            logList.remove(level);        }    }    private static String LOG_FILE_PATH;    private Level logOutPutLevel;    private int FILE_SIZE;    private int FILE_MAX;    private boolean HANDLER_FILE = false;    private boolean HANDLER_CONSOLE = false;    private static ArrayList<String> logList = new ArrayList<String>();    private String LOG_FILE_LASTNAME;    private static String LEVEL_DEBUG = "DEBUG";    private static String LEVEL_INFO = "INFO";    private static String LEVEL_WARN = "WARN";    private static String LEVEL_ERROR = "ERROR";    private static Log INSTANCE = new Log();    SimpleDateFormat format = new SimpleDateFormat();}/** * 自定义文件输出管理类,参考JDK FileHandler实现 *  * @author DingFengHua */class MyFileHandler extends StreamHandler {    private MeteredStream meter;    private boolean append;    private int limit; // zero => no limit.    private int count;    private String pattern;    private String lockFileName;    private FileOutputStream lockStream;    private File files[];    private static final int MAX_LOCKS = 100;    private static java.util.HashMap<String, String> locks = new java.util.HashMap<String, String>();    private class MeteredStream extends OutputStream {        OutputStream out;        int written;        MeteredStream(OutputStream out, int written) {            this.out = out;            this.written = written;        }        public void write(int b) throws IOException {            out.write(b);            written++;        }        @Override        public void write(byte buff[]) throws IOException {            out.write(buff);            written += buff.length;        }        @Override        public void write(byte buff[], int off, int len) throws IOException {            out.write(buff, off, len);            written += len;        }        @Override        public void flush() throws IOException {            out.flush();        }        @Override        public void close() throws IOException {            out.close();        }    }    private void open(File fname, boolean append) throws IOException {        int len = 0;        if (append) {            len = (int) fname.length();        }        FileOutputStream fout = new FileOutputStream(fname.toString(), append);        BufferedOutputStream bout = new BufferedOutputStream(fout);        meter = new MeteredStream(bout, len);        setOutputStream(meter);    }    public MyFileHandler() throws IOException, SecurityException {        openFiles();    }    public MyFileHandler(String pattern) throws IOException, SecurityException {        if (pattern.length() < 1) {            throw new IllegalArgumentException();        }        this.pattern = pattern;        this.limit = 0;        this.count = 1;        openFiles();    }    public MyFileHandler(String pattern, boolean append) throws IOException, SecurityException {        if (pattern.length() < 1) {            throw new IllegalArgumentException();        }        this.pattern = pattern;        this.limit = 0;        this.count = 1;        this.append = append;        openFiles();    }    public MyFileHandler(String pattern, int limit, int count) throws IOException, SecurityException {        if (limit < 0 || count < 1 || pattern.length() < 1) {            throw new IllegalArgumentException();        }        this.pattern = pattern;        this.limit = limit;        this.count = count;        openFiles();    }    public MyFileHandler(String pattern, int limit, int count, boolean append) throws IOException, SecurityException {        if (limit < 0 || count < 1 || pattern.length() < 1) {            throw new IllegalArgumentException();        }        this.pattern = pattern;        this.limit = limit;        this.count = count;        this.append = append;        openFiles();    }    private void openFiles() throws IOException {        LogManager manager = LogManager.getLogManager();        manager.checkAccess();        if (count < 1) {            throw new IllegalArgumentException("file count = " + count);        }        if (limit < 0) {            limit = 0;        }        InitializationErrorManager em = new InitializationErrorManager();        setErrorManager(em);        int unique = -1;        for (;;) {            unique++;            if (unique > MAX_LOCKS) {                throw new IOException("Couldn't get lock for " + pattern);            }            lockFileName = generate(pattern, 0, unique).toString() + ".lck";            synchronized (locks) {                if (locks.get(lockFileName) != null) {                    continue;                }                FileChannel fc;                try {                    lockStream = new FileOutputStream(lockFileName);                    fc = lockStream.getChannel();                } catch (IOException ix) {                    continue;                }                try {                    FileLock fl = fc.tryLock();                    if (fl == null) {                        continue;                    }                } catch (IOException ix) {                }                locks.put(lockFileName, lockFileName);                break;            }        }        files = new File[count];        for (int i = 0; i < count; i++) {            files[i] = generate(pattern, i, unique);        }        if (append) {            open(files[0], true);        } else {            rotate();        }        Exception ex = em.lastException;        if (ex != null) {            if (ex instanceof IOException) {                throw (IOException) ex;            } else if (ex instanceof SecurityException) {                throw (SecurityException) ex;            } else {                throw new IOException("Exception: " + ex);            }        }        setErrorManager(new ErrorManager());    }    private File generate(String pattern, int generation, int unique) throws IOException {        File file = null;        String word = "";        int ix = 0;        boolean sawg = false;        boolean sawu = false;        while (ix < pattern.length()) {            char ch = pattern.charAt(ix);            ix++;            char ch2 = 0;            if (ix < pattern.length()) {                ch2 = Character.toLowerCase(pattern.charAt(ix));            }            if (ch == '/') {                if (file == null) {                    file = new File(word);                } else {                    file = new File(file, word);                }                word = "";                continue;            } else if (ch == '%') {                if (ch2 == 't') {                    String tmpDir = System.getProperty("java.io.tmpdir");                    if (tmpDir == null) {                        tmpDir = System.getProperty("user.home");                    }                    file = new File(tmpDir);                    ix++;                    word = "";                    continue;                } else if (ch2 == 'h') {                    file = new File(System.getProperty("user.home"));                    if (isSetUID()) {                        throw new IOException("can't use %h in set UID program");                    }                    ix++;                    word = "";                    continue;                } else if (ch2 == 'g') {                    word = word + generation;                    sawg = true;                    ix++;                    continue;                } else if (ch2 == 'u') {                    word = word + unique;                    sawu = true;                    ix++;                    continue;                } else if (ch2 == '%') {                    word = word + "%";                    ix++;                    continue;                }            }            word = word + ch;        }        if (count > 1 && generation > 0 && !sawg) {            word = word + "." + generation;        }        if (unique > 0 && !sawu) {            word = word + "." + unique;        }        if (word.length() > 0) {            if (file == null) {                file = new File(word);            } else {                file = new File(file, word);            }        }        return file;    }    private synchronized void rotate() {        Level oldLevel = getLevel();        setLevel(Level.OFF);        super.close();        for (int i = count - 2; i >= 0; i--) {            File f1 = files[i];            File f2 = files[i + 1];            if (f1.exists()) {                if (f2.exists()) {                    f2.delete();                }                f1.renameTo(f2);            }        }        try {            open(files[0], false);        } catch (IOException ix) {            reportError(null, ix, ErrorManager.OPEN_FAILURE);        }        setLevel(oldLevel);    }    @Override    public synchronized void publish(LogRecord record) {        if (!isLoggable(record)) {            return;        }        super.publish(record);        flush();        if (limit > 0 && meter.written >= limit) {            AccessController.doPrivileged(new PrivilegedAction<Object>() {                public Object run() {                    rotate();                    return null;                }            });        }    }    @Override    public synchronized void close() throws SecurityException {        super.close();        if (lockFileName == null) {            return;        }        try {            lockStream.close();        } catch (Exception ex) {        }        synchronized (locks) {            locks.remove(lockFileName);        }        new File(lockFileName).delete();        lockFileName = null;        lockStream = null;    }    private static class InitializationErrorManager extends ErrorManager {        Exception lastException;        @Override        public void error(String msg, Exception ex, int code) {            lastException = ex;        }    }    private static native boolean isSetUID();}
?

热点排行