Java Logging之JUL系列——Log Levels

JDK自带的日志组件在java.util.logging包中,该组件将日志级别分为如下九种,级别从上到下依次降低,每种级别都对应一个整数值,如下所示:

  • OFF(Integer.MAX_VALUE)
  • SEVERE(1000)
  • WARNING(900)
  • INFO(800)
  • CONFIG(700)
  • FINE(500)
  • FINER(400)
  • FINEST(300)
  • ALL(Integer.MIN_VALUE)

日志级别由java.util.logging.Level类来表示,级别的作用是用来过滤日志输出的,除此之外,过滤器(Filter)也能起到对日志输出进行过滤的作用,我们后文再详细讨论Filter。

首先我们来看一下JUL组件最常见的用法:

package cn.codecrazy.study;

import java.util.logging.Logger;

public class JavaLogging {
    private static final Logger logger = Logger.getLogger(JavaLogging.class.getName());
    public static void main(String[] args) {
        logger.finest("This is a finest message");
        logger.finer("This is a finer message");
        logger.fine("This is a fine message");
        logger.config("This is a config message");
        logger.info("This is an info message");
        logger.warning("This is a warning message");
        logger.severe("This is a severe message");
    }
}

输出如下所示:

八月 08, 2018 9:36:08 下午 cn.codecrazy.study.JavaLogging main 
信息: This is an info message 
八月 08, 2018 9:36:08 下午 cn.codecrazy.study.JavaLogging main 
警告: This is a warning message 
八月 08, 2018 9:36:08 下午 cn.codecrazy.study.JavaLogging main 
严重: This is a severe message

为什么只输出了info以及info级别以上的信息呢?

logger.config("This is a config message")方法为例,该方法内部调用的是logger.log(Level.CONFIG, "This is a config message")方法,其他的方法同理,都是对Logger.log方法的一种封装,只不过不同的方法传入的日志级别不一样。Logger.log(Level level, String msg)该方法的实际含义为:比较参数中传入的level和当前Logger对象的level级别,如果参数中传入的level级别高于或等于当前Logger对象的级别,则将message进行输出。底层调用的方法如下:

public void log(Level level, String msg) {
        if (!isLoggable(level)) {
            return;
        }
        LogRecord lr = new LogRecord(level, msg);
        doLog(lr);
    }

如果isLoggable方法返回false,则直接return.

public boolean isLoggable(Level level) {
        if (level.intValue() < levelValue || levelValue == offValue) {
            return false;
        }
        return true;
    }

如果当前logger对象的levelValue为offValue(即Level.OFF级别对应的整数)说明关闭了日志记录功能,不进行输出,或者是传入的日志级别比当前logger的level低,也不进行输出。换句话说就是日志记录器Logger只对级别高于或者等于它自身日志级别的信息进行输出。那么我们可以推测,当前的logger对象的日志级别默认应该就是INFO级别。

我们可以更改一下logger的级别为WARNING:

logger.setLevel(Level.WARNING);

输出如下:

八月 08, 2018 10:19:07 下午 cn.codecrazy.study.JavaLogging main
警告: This is a warning message
八月 08, 2018 10:19:07 下午 cn.codecrazy.study.JavaLogging main
严重: This is a severe message

这次只输出了WARNING以及SEVERE级别的日志信息。说明Level起到了过滤日志输出的作用。实际应用中,当我们调整日志级别的时候,相同的应用程序代码输出的日志会不同。

我们试着把日志级别设置为更低的CONFIG级别,根据我们前面的论述,最终的输出应该是输出CONFIG及其以上级别的日志信息,但实际的输出结果却是:

八月 08, 2018 9:36:08 下午 cn.codecrazy.study.JavaLogging main
信息: This is an info message
八月 08, 2018 9:36:08 下午 cn.codecrazy.study.JavaLogging main
警告: This is a warning message
八月 08, 2018 9:36:08 下午 cn.codecrazy.study.JavaLogging main
严重: This is a severe message

并没有输出CONFIG级别的日志,还是输出的INFO及其以上级别的日志。为什么会这样呢?这是因为不仅Logger有Level的概念,JUL中的另一组件Handler也有Level的概念,Logger对message的输出最终是通过Handler来进行实际操作的,在输出的过程中,Handler组件依然会判断当前需要输出的日志级别跟Handler自身的级别相比是高还是低,只有当前需要输出的日志级别高于或者等于Handler自身的日志级别才会进行输出。

在这里我们的Logger级别设置为了CONFIG,通过logger.config方法进行输出时,当前需要输出的日志级别为CONFIG,该级别不小于Logger的日志级别,因此不会被过滤,但是该级别小于实际进行输出操作的Handler的级别(默认是INFO),因此不会被该Handler进行实际的输出操作。

关于Handler的详细信息会在后续文章中进行介绍。

你可能感兴趣的:(Java Logging之JUL系列——Log Levels)