Java开发-JDK原生日志工具java.util.logging包的使用

程序开发中,我们不可避免的要使用日志,它对我们的开发和调试,修改都具有重要作用。

我们可以使用专业的日志工具,框架来记录日志,对于小项目,也可以使用JDK自带的日志记录工具,使用简单,效率高。

这里只介绍简单的使用方法,便于快速使用,JDK的日志系统相当复杂,有兴趣的可以参阅API帮助文档。

建议单独编写一个类来配置日志工具,避免和其他业务代码相互干扰。

1:获取日志工具对象

public static final Logger logger = Logger.getLogger("system");

调用Logger类的静态方法getLogger,传入一个名字,名字可以任意取,对程序无影响。

2:指定日志级别

日志分为多个级别,存储在Level类中,有

SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST,ALL(所有级别)9种级别,调用setLevel(Level level)方法为日志对象设置级别

如果是小项目,可以不考虑级别,指定INFO即可,需要注意的是,指定级别和使用日志时的级别不同有可能会导致日志消息不被记录。

3:指定日志输出方式

日志工具使用Handler输出日志,常用的有ConsoleHandler(控制台输出),FileHandler(文件输出)。

创建一个控制台Handler

ConsoleHandler consoleHandler = new ConsoleHandler();
//Handler也要设置等级,和日志对象保持一致即可
consoleHandler.setLevel(Level.ALL);
//设置格式化对象,请见下文
consoleHandler.setFormatter(mmf);
//将该Handler添加到日志对象中,一个日志对象可以有多个Handler
logger.addHandler(consoleHandler);

创建一个文件Handler

 try {
     //需要指定输出文件路径
     FileHandler fileHandler = new FileHandler(Content.LOG_FILE_CONTENT,false);
     fileHandler.setLevel(Level.ALL);
     fileHandler.setFormatter(mmf);
     logger.addHandler(fileHandler);
} catch (IOException e) {
     e.printStackTrace();
}

FileHandler需要指定一个输出路径,有关文件路径处理,可以参照我的文章:Java开发-制作一个可随意移植的文件路径获取类

可以将以上内容打包为一个方法:

/**
* 初始化日志工具的方法
 */
private static void initializeLogger(){
    //设置记录级别
    logger.setLevel(Level.ALL);

    //不使用自带的父Handler,新建ConsoleHandler
    logger.setUseParentHandlers(false);

    //创建Handler对象,指定输出方式,设置Handler的级别
    ConsoleHandler consoleHandler = new ConsoleHandler();
    consoleHandler.setLevel(Level.ALL);
    consoleHandler.setFormatter(mmf);
    logger.addHandler(consoleHandler);

    try {
        FileHandler fileHandler = new FileHandler(Content.LOG_FILE_CONTENT,false);
        fileHandler.setLevel(Level.ALL);
        fileHandler.setFormatter(mmf);
        logger.addHandler(fileHandler);
    } catch (IOException e) {
        e.printStackTrace();
    }
        
}

然后在日志类的静态代码块中调用此方法即可。

这些工作完成后,日志对象就可以使用了,但是如果我们直接使用,在输出时就会按照默认的格式输出,可读性较差,故我们可以自定义一个格式化类,指定输出格式。

4:自定义格式化类

格式化类需要继承Formatter类,并且重写public String format(LogRecord record)方法,推荐使用内部类完成

    /**
     * 格式化输出文本的类
     */
    private static class MyMathFormatter extends Formatter {
        //日期格式化工具对象
        private static final SimpleDateFormat dateFormat = 
        new SimpleDateFormat("HH:mm:ss:SSS");

        //添加日志信息是日志对象会自动调用该方法
        @Override
        public String format(LogRecord record) {
            //日期 {类名} [方法名] 日志内容+参数 换行符
            StringBuilder s = new StringBuilder(100);

            //日期
            s.append(dateFormat.format(new Date()));
            //类名
            s.append("{");
            try {
                s.append(Class.forName(record.getSourceClassName()).getSimpleName());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            s.append("}");
            //方法名
            s.append(" [");
            s.append(record.getSourceMethodName());
            //日志内容
            s.append(",");
            s.append(record.getMessage());

            Object[] params = record.getParameters();
            if (params != null) {
                s.append("-");
                //参数
                s.append(Arrays.toString(record.getParameters()));
            }
            s.append("] ");
            s.append("\n");

            return s.toString();
        }
    }

在这个方法中,可以对原始的日志信息进行加工,例如打印时间,类名,方法名,参数等。

日志的类名,方法名这些信息被封装在LogRecord对象中,调用此对象的getxxx方法即可获取到相关信息

***此方法为日志工具对象自动调用,不需要程序员手动调用

5:使用日志工具

这样,日志工具就完全可以使用了,在程序中,调用日志工具对象的info(String message)等方法,传入日志信息,这些日志信息会被送到格式化类中加工,最后通过Handler输出到文件中或控制台。

日志输出示例,格式化类的作用非常明显 

最后附上完成的类供各位参考,内容就是前文已经提到过的:

/**
 * 日志工具类,使用者直接使用常量logger进行日志记录
 */
public final class CoordinateLogger {
    private CoordinateLogger() {
        throw new IllegalAccessError("不能创建CoordinateLogger对象!");
    }

    /**
     * 读取文件的配置
     */
    private static final ResourceBundle bundle = ResourceBundle.getBundle("com.mymath.lib.SystemConfig");

    /**
     * 是否使用控制台输出
     */
    private static final boolean isConsole = Boolean.parseBoolean(bundle.getString("isUseConsoleHandler"));

    /**
     * 是否使用文件输出
     */
    private static final boolean isFile = Boolean.parseBoolean(bundle.getString("isUseFileHandler"));

    /**
     * 格式化对象
     */
    private static final MyMathFormatter mmf = new MyMathFormatter();

    /**
     * 可供使用的日志工具对象
     */
    public static final Logger logger = Logger.getLogger("system");

    static {
        initializeLogger();
    }

    /**
     * 初始化日志工具的方法
     */
    private static void initializeLogger(){
        //设置记录级别
        logger.setLevel(Level.ALL);

        //不使用自带的父Handler,新建ConsoleHandler
        logger.setUseParentHandlers(false);

        if (!isConsole && !isFile){
            throw new ExceptionInInitializerError("没有指定日志输出方式,无法输出日志!");
        }
        //创建Handler对象,指定输出方式,设置Handler的级别
        if (isConsole){
            ConsoleHandler consoleHandler = new ConsoleHandler();
            consoleHandler.setLevel(Level.ALL);
            consoleHandler.setFormatter(mmf);
            logger.addHandler(consoleHandler);
        }

        if (isFile){
            try {
                FileHandler fileHandler = new FileHandler(Content.LOG_FILE_CONTENT,false);
                fileHandler.setLevel(Level.ALL);
                fileHandler.setFormatter(mmf);
                logger.addHandler(fileHandler);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 格式化输出文本的类
     */
    private static class MyMathFormatter extends Formatter {
        //日期格式化工具对象
        private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSS");

        //添加日志信息是日志对象会自动调用该方法
        @Override
        public String format(LogRecord record) {
            //日期 {类名} [方法名] 日志内容+参数 换行符
            StringBuilder s = new StringBuilder(100);

            //日期
            s.append(dateFormat.format(new Date()));
            //类名
            s.append("{");
            try {
                s.append(Class.forName(record.getSourceClassName()).getSimpleName());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            s.append("}");
            //方法名
            s.append(" [");
            s.append(record.getSourceMethodName());
            //日志内容
            s.append(",");
            s.append(record.getMessage());

            Object[] params = record.getParameters();
            if (params != null) {
                s.append("-");
                //参数
                s.append(Arrays.toString(record.getParameters()));
            }
            s.append("] ");
            s.append("\n");

            return s.toString();
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值