首页 > 解决方案 > 日志处理程序的使用

问题描述

我的问题类似于为什么 java.util.logging.Logger 打印到标准错误?邮政。我只想在我的日志记录中使用一个处理程序,因为它应该将 INFO 语句打印到输出流上,并将 WARNING & SEVERE 打印到错误流上。这可能吗 ?例如,如果我采用两个处理程序,一个用于输出流 - 级别为 INFO,另一个用于错误流 - 在这种情况下,级别为 WARNING/SEVERE,应用程序会显示两次消息,一个是输出流,另一个是错误流。那么有什么解决办法吗?

标签: java.util.logging

解决方案


这可以通过一两个处理程序来实现。缺少的部分是您需要为限制最高级别的 OUT 处理程序创建一个过滤器。此外,您需要确保根 logger 上没有其他 ConsoleHandler 会污染您的测试。您可以打印记录器树以查看附加了哪些处理程序。

这是一个概念证明:

import java.io.PrintStream;
import java.util.logging.ConsoleHandler;
import java.util.logging.Filter;
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;

public class OutErrorTest {

    private static final Logger log = Logger.getLogger("");

    public static void main(String[] args) {
        LogManager.getLogManager().reset(); //A quick way to remove all handlers.

        Handler out = newSystemOut();
        Handler err = newSystemErr();

        final Level fence = Level.WARNING;

        out.setLevel(Level.ALL);
        out.setFilter(new LessThanLevelFilter(fence));
        err.setLevel(fence);

        log.addHandler(out);
        log.addHandler(err);
        log.setLevel(Level.ALL);

        log.finest("Finest Log");
        log.finer("Finer Log");
        log.fine("Fine Log");
        log.config("Config Log");
        log.info("Info Log");
        log.warning("Warning Log");
        log.severe("Severe Log");

    }

    private static Handler newSystemErr() {
        return new ConsoleHandler();
    }

    private static Handler newSystemOut() {
        Handler h = null;
        final PrintStream err = System.err;
        System.setErr(System.out);
        try {
            h = new ConsoleHandler(); // Snapshot of System.err
        } finally {
            System.setErr(err);
        }
        return h;
    }

    public static class LessThanLevelFilter implements Filter {

        private final int lvl;

        public LessThanLevelFilter(final Level max) {
            this(max.intValue());
        }

        public LessThanLevelFilter(final int max) {
            this.lvl = max;
        }

        @Override
        public boolean isLoggable(LogRecord r) {
            return r.getLevel().intValue() < lvl;
        }
    }
}

推荐阅读