1

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

请参阅以下 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

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

4

1 回答 1

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");
    }
    }
}

它执行您想要的输出。

于 2013-09-06T06:26:41.210 回答