记录日志时为该类动态创建日志文件,并仅在log4j中登录该文件

时间:2018-04-19 15:23:56

标签: java logging log4j2

我在我的项目中使用log4j进行日志记录。我有一个包,它包含50多个java类。从这些日志记录日志时,如果日志语句来自A类,则它应该放在A.log文件中,等等用于其他类。 我想在运行时执行此操作。不想在log4j.xml中为所有类编写appender。在运行时,它应该能够识别该日志来自A类,因此它将其记录到A.log文件中。我希望通过在已经实现的java文件中进行最小化或无变化来实现此目的。我可以通过仅在该包的log4j.xml文件中进行更改来实现。 System.setProperty(" logfilename"," className")对我没用。任何帮助赞赏。

1 个答案:

答案 0 :(得分:0)

在此之前,我觉得我应该指出这似乎是一种非常不寻常的日志记录策略。通常,您希望看到特定用户与您的程序交互过程中发生的事情的整体视图,而不是必须引用几十个尝试跟踪逻辑流程的日志文件。例如,如果用户通过调用A类来运行您的程序,然后A类使用B类,则您必须查看2个日志才能跟踪用户体验。想象一下,必须为复杂的用户交互执行此操作,这些交互流入更多类,并且还想象当执行从A到B到A到B到C到B到A时的跟踪是多么困难。就在这个小例子中你必须查看A的日志,并以某种方式认识到执行将转到B类,然后查看B的日志,依此类推。

如上所述,如果您仍然想要走这条路线,那么我不相信您可以通过配置更改来实现您想要的功能,但是可以使用最少的代码除了配置更改。

如果您查看有关log4j2 manual的部分中的Extending Log4j2 Lookups,您会看到有关如何实施查找的示例。您可以按如下方式为记录器名称创建自己的查找:

package example;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;

@Plugin(name = "logger", category = "Lookup")
public class LoggerLookup implements StrLookup{
    /**
     * Lookup the value for the key.
     * @param key  the key to be looked up, may be null
     * @return The value for the key.
     */
    public String lookup(String key) {
        return null;
    }


    /**
     * Lookup the value for the key using the data in the LogEvent.
     * @param event The current LogEvent.
     * @param key  the key to be looked up, may be null
     * @return The value associated with the key.
     */
    public String lookup(LogEvent event, String key) {
        if("name".equals(key)){
            return event.getLoggerName();
        }
        return null;
    }
}

现在,使用Routing Appender根据需要在运行时根据记录器名称动态创建appender,方法与以下示例类似:

    <Routing name="MyRoutingAppender">
        <Routes pattern="$${logger:name}">
            <Route>
                <File
                    fileName="logs/${logger:name}.txt"
                    name="appender-${logger:name}">
                    <PatternLayout>
                        <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level ${logger:name} - %msg%n</Pattern>
                    </PatternLayout>
                </File>
            </Route>
        </Routes>
    </Routing>

以下是两个生成一些日志记录的示例类。

首先是主要课程:

package example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SomeClass {

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

    public static void main(String[] args){
        log.info("Here's some info!");
        log.error("Some erorr happened!");

        AnotherClass ac = new AnotherClass();
        ac.logSomething();
    }
}

第二课:

package example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class AnotherClass {
    private static final Logger log = LogManager.getLogger();   

    public void logSomething(){
        log.info("This is yet another info message");
    }
}

下面是我用来测试的配置文件(log4j2.xml)。请注意,我首先使用了控制台appender来验证新的查找是否正常工作,并决定将其保留,因为它可能对阅读此答案的人有所帮助。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level ${logger:name} - %msg%n" />
        </Console>

        <Routing name="MyRoutingAppender">
            <Routes pattern="$${logger:name}">
                <Route>
                    <File
                        fileName="logs/${logger:name}.txt"
                        name="appender-${logger:name}">
                        <PatternLayout>
                            <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level ${logger:name} - %msg%n</Pattern>
                        </PatternLayout>
                    </File>
                </Route>
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" level="info" />          
            <AppenderRef ref="MyRoutingAppender" level="info" />
        </Root>
    </Loggers>
</Configuration>

运行SomeClass会在名为“logs”的目录中生成两个名为“example.AnotherClass.txt”和“example.SomeClass.txt”的日志文件。第一个文件中的日志由AnotherClass生成,第二个文件中的日志由SomeClass生成

Log files generated by the sample code

所有这些只是概念验证,因此您需要对其进行修改以满足您的需求。希望它能说明你实现目标的一般方式。

相关问题