实现一个简单的Log框架

实际上算不上框架,只是自己对日志框架的一点理解。

 

核心接口:Logger,供调用者完成不同等级的日志输出

package com.lichmama.log.service;

public interface Logger
{
    public void debug(String msg);
    
    public void debug(String format, Object... args);
    
    public void info(String msg);
    
    public void info(String format, Object... args);
    
    public void warn(String msg);
    
    public void warn(String format, Object... args);
    
    public void error(String msg);
    
    public void error(String format, Object... args);
    
    public void fatal(String msg);
    
    public void fatal(String format, Object... args);
}

 

核心接口:LogWriter,内部使用,完成日志输出到文件或控制台的过程

package com.lichmama.log.service;

public interface LogWriter
{
    public void log(String log);
}

 

核心接口:LoggerBuilder,日志实例的生成器,提供对不同类型的日志实例的生成接口

package com.lichmama.log.service;

public interface LoggerBuilder
{
    //运行时日志
    public Logger getRunLogger(Class<?> T);
    
    //命令行日志
    public Logger getConLogger(Class<?> T);
}

 

日志类型枚举:LogType

package com.lichmama.log.service;

public enum LogType 
{
    RUNTIME, CONSOLE
}

 

接口实现类:LogWriterImpl,具体实现日志输出行为

package com.lichmama.log.service.impl;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import com.lichmama.log.service.LogType;
import com.lichmama.log.service.LogWriter;

public class LogWriterImpl implements LogWriter
{
    private Writer logWriter;

    public LogWriterImpl(LogType logType)
    {
        try 
        {
            switch (logType)
            {
                case RUNTIME:
                    logWriter = new OutputStreamWriter(new FileOutputStream("D:\\log\\test\\runtime.log", true));
                    break;
                case CONSOLE:
                    logWriter = new OutputStreamWriter(System.out);
                    break;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        
    }
    
    @Override
    public void log(String log)
    {
        try
        {
            logWriter.write(log);
            logWriter.flush();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

}

 

接口实现类:LoggerFactory,日志工厂类,用来生成不同类型的日志示例

package com.lichmama.log.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.lichmama.log.service.LogType;
import com.lichmama.log.service.LogWriter;
import com.lichmama.log.service.Logger;
import com.lichmama.log.service.LoggerBuilder;

public class LoggerFactory implements LoggerBuilder
{
    private LoggerFactory(){}
    
    private static class SingletonHolder
    {
        private static final LoggerFactory instance = new LoggerFactory();
    }
    
    public static final LoggerFactory getInstance()
    {
        return SingletonHolder.instance;
    }
    
    private static ThreadLocal<Map<String, Logger>> loggers = new ThreadLocal<Map<String, Logger>>() {
        @Override
        public Map<String, Logger> initialValue()
        {
            return new HashMap<String, Logger>();
        }
    };
    
    @Override
    public Logger getRunLogger(Class<?> T)
    {
        return getLogger(T, LogType.RUNTIME);
    }

    @Override
    public Logger getConLogger(Class<?> T)
    {
        return getLogger(T, LogType.CONSOLE);
    }
    
    private Logger getLogger(Class<?> T, LogType logType)
    {
        String tagName = T.getName() + "@" + logType;
        Logger logger = loggers.get().get(tagName);
        if (logger == null)
        {
            logger = new LoggerInstance(T.getName(), new LogWriterImpl(logType));
            loggers.get().put(tagName, logger);
        }
        return logger;
    }
    
    private class LoggerInstance implements Logger
    {
        private LogWriter logWriter;
        private String module;
        private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        
        public LoggerInstance(String module, LogWriter logWriter)
        {
            this.module = module;
            this.logWriter = logWriter;
        }
        
        @Override
        public void debug(String msg)
        {
            log(msg, "DEBUG");
        }

        @Override
        public void info(String msg)
        {
            log(msg, "INFO");
        }

        @Override
        public void warn(String msg)
        {
            log(msg, "WARN");
        }

        @Override
        public void error(String msg)
        {
            log(msg, "ERROR");
        }

        @Override
        public void fatal(String msg)
        {
            log(msg, "FATAL");
        }
        
        private void log(String msg, String logLevel)
        {
            String logText = String.format("%s-[%s] [%s] %s\r\n", sdf.format(new Date()), module, logLevel, msg);
            logWriter.log(logText);
        }

        @Override
        public void debug(String format, Object... args)
        {
            String logText = String.format(format, args);
            debug(logText);
        }

        @Override
        public void info(String format, Object... args)
        {
            String logText = String.format(format, args);
            info(logText);
        }

        @Override
        public void warn(String format, Object... args)
        {
            String logText = String.format(format, args);
            warn(logText);
        }

        @Override
        public void error(String format, Object... args)
        {
            String logText = String.format(format, args);
            error(logText);
        }

        @Override
        public void fatal(String format, Object... args)
        {
            String logText = String.format(format, args);
            fatal(logText);
        }
    }
}

 

使用:

public class Test
{
    public static void main(String[] args)
    {
        Logger logger = LoggerFactory.getInstance().getConLogger(Test.class);
        logger.warn("winter is coming");
        logger.debug("%s said, 'valar morghulis'", "Jaqen H'ghar");
        logger.info("%s answered: %s", "Arya", "Valar Dohaeris");
    }
}
#################################################################################### CONSOLE OUTPUT: ####################################################################################
20160728171925-[com.lichmama.log.service.test.Test] [WARN] winter is coming 20160728171925-[com.lichmama.log.service.test.Test] [DEBUG] Jaqen H'ghar said, 'valar morghulis' 20160728171925-[com.lichmama.log.service.test.Test] [INFO] Arya answered: Valar Dohaeris

 

posted @ 2016-07-26 17:15  lichmama  阅读(807)  评论(0编辑  收藏  举报