对于 Java 中的同一语句,处理不同文件的自定义日志消息的好方法是什么?

What would be a good way to handle custom log messages for different files for the same statement in Java?

不确定这个问题是否发布在正确的论坛上。

如果设计类型的问题应该张贴在其他地方,请将我指向正确的论坛。

背景: Java 项目。使用 log4j.xml。行家。 TestNG.

每个测试将语句打印到两个日志文件 - 未过滤的日志文件和过滤的日志文件。 两个文件中的所有消息都应该按原样打印。除了少数消息,需要将修改后的消息(删除变量值)打印到第二个日志文件(过滤后的日志文件)。

带有打印语句的示例测试代码:

1. printInfo("Login completed");
2. printInfo("Home page displayed");
// Here the value of accountNumber variable is random and changes with each run.
3. printInfo("Account number " + accountNumber + " created", "printUnfilteredMessageOnlyForUnfilteredLog");
4. printInfo("Account number created", "replaceMessageForFilteredLog");

想法是两个日志文件都包含第 1 行和第 2 行。 第 3 行将仅转到未过滤的日志文件。第 4 行只会转到过滤后的日志文件。

方法代码:

Logger unfilteredLogFile = Logger.getLogger("unfilteredLogFileLogger");
Logger filteredLogFile = Logger.getLogger("filteredLogFileLogger");

public void printInfo(String message, String level) {
    if (level.equalsIgnoreCase("")) {
            //Print the same message in both the log files
            unfilteredLogFile.info("Unfiltered Log :"+message);
            filteredLogFile.debug("Filtered Log :"+message);
        } else if (level.equalsIgnoreCase("printUnfilteredMessageOnlyForUnfilteredLog")) {
            unfilteredLogFile.info("Unfiltered Log :"+message);
        } else if (level.equalsIgnoreCase("replaceMessageForFilteredLog")) {
            filteredLogFile.debug("Filtered Log :"+message);
        }
    }

此代码按照我的要求成功运行。

正确输出:

unfilteredLogFile.log:

Unfiltered Log :Login completed
Unfiltered Log :Home page displayed
Unfiltered Log :Account number 4876 created


filteredLogFile.log:

Filtered Log :Login completed
Filtered Log :Home page displayed
Filtered Log :Account number created

Log4j.xml:

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
                     debug="false">
    <appender name="fileAppender" class="org.apache.log4j.FileAppender">
        <param  name="File" value="./log/unfilteredLogFile.log" />
        <param name="append" value="false" />
        <param name="Threshold" value="INFO"/>
    </appender>
    <appender name="unfilteredLog" class="org.apache.log4j.FileAppender">
        <param name="File" value="./log/filteredLogFile.log" />
        <param name="append" value="false" />
        <param name="Threshold" value="DEBUG"/>
    </appender>


    <logger name="unfilteredLogFileLogger" additivity="false">
        <appender-ref ref="fileAppender"/>
    </logger>
    <logger name="filteredLogFileLogger" additivity="false">
        <appender-ref ref="filteredLog"/>
    </logger>

    <root>
        <level value="DEBUG" />
        <appender-ref ref="fileAppender"/>
        <appender-ref ref="filteredLog"/>
    </root>
</log4j:configuration>

此代码按照我的要求成功运行。 但是,这意味着对于代码中需要进行替换的每个 printInfo 语句,我需要编写两行代码,每个日志文件一行,这听起来不像是最佳方式或干净的代码。

是否有不同的设计来处理这种情况,但实现相同的输出?或者这是满足此要求的最佳选择?

我想到了一个可以是键值对列表的文本文件。 键是未过滤的消息,值是过滤后的消息。但是,无法实现这一点,因为列表中无法包含要与之比较的随机值。

请告诉我你的想法。

您可以做的是,创建 3 个自定义日志级别 - 未过滤、已过滤和常见 - 如所示 here. Then make the log-level COMMON a descendant logger (check here and here) 未过滤和已过滤日志级别,以便记录到常见的任何内容都可以给他们两个。这应该可以解决您想要实现的目标。

但是,这可能是对日志级别的误用。它将消除使用预定义日志级别(信息、调试、错误等)的灵活性。