java util记录多个处理程序导致重复的日志消息

时间:2013-09-06 05:57:42

标签: java java.util.logging

我的情况是多个处理程序被设置到一个记录器中。每个处理程序都会替换记录的敏感信息。

请参阅以下SSCCE

import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.Logger;


public class TestLogging {

    public static void main(String[] args) {
        Logger logger=Logger.getLogger(A.class.getName());
        logger.addHandler(new ConsoleHandler(){
            {
                setFormatter(new Formatter() {
                    @Override
                    public String format(LogRecord record) {
                        return record.getMessage().replaceAll("method","replacing method");
                    }
                });
            }
        });
        logger.addHandler(new ConsoleHandler(){
            {
                setFormatter(new Formatter() {
                    @Override
                    public String format(LogRecord record) {
                        return record.getMessage().replaceAll("Logging","replacing logging");
                    }
                });
            }
        });
        logger.setUseParentHandlers(false);

        A a =new A();
        a.method();
    }


    public static class A{

        private static final Logger LOGGER=Logger.getLogger(A.class.getName());

        public void method(){
            LOGGER.info("\nLogging from inside method");
        }
    }
}

我希望输出“从替换方法内部替换日志记录”,但我得到这样的输出

Logging from inside replacing method
replacing logging from inside method

如果我发现另一个处理程序已被设置,如何将这两个处理程序合并为一个?

1 个答案:

答案 0 :(得分:1)

设计处理程序不应该被链接或合并,因为它们的主要目的是执行最终的LogRecord处理,比如写入文件。我建议稍微改变一下方法并合并格式化程序而不是处理程序。请看下面的例子:

public class TestLogging {

public static void main(String[] args) {
    Logger logger = Logger.getLogger(A.class.getName());
    FormatHandler handler = new FormatHandler();
    logger.addHandler(handler);

    handler.addFormatter(new Formatter() {
        @Override
        public String format(LogRecord record) {
            return record.getMessage().replaceAll("method", "replacing method");
        }
    });

    handler.addFormatter(new Formatter() {
        @Override
        public String format(LogRecord record) {
            return record.getMessage().replaceAll("Logging", "replacing logging");
        }
    });
    logger.setUseParentHandlers(false);

    A a = new A();
    a.method();
}

public static class FormatHandler extends ConsoleHandler {

    private List<Formatter> formatters = new ArrayList<>();

    public FormatHandler() {
        setFormatter(new CompositeFormatter());
    }

    public void addFormatter(Formatter f) {
        formatters.add(f);
    }

    class CompositeFormatter extends Formatter {
        @Override
        public synchronized String format(LogRecord record) {
            String modifiedMessage;
            for(Formatter formatter : formatters){
                modifiedMessage = formatter.format(record);
                record.setMessage(modifiedMessage);
            }
            return record.getMessage();
        }
    }
}

public static class A {

    private static final Logger LOGGER = Logger.getLogger(A.class.getName());

    public void method() {
        LOGGER.info("\nLogging from inside method");
    }
    }
}

它执行您想要的输出。