关于多线程:独立登录多个文件夹中的多个文件-log4j JAVA

Logging in multiple files in multiple folders independently - log4j JAVA

我正在开发一个多线程应用程序,其中我想使用log4j在不同的位置进行日志记录。

场景:

Folder1 ---> log1.log
log2.log
log3.log

Folder2 ---> log1.log
log2.log
log3.log

我希望记录器独立登录文件。

到目前为止,我已经创建了3个RollingFileAppenders,它们对应于Folder1的3个记录器,但是问题是"我将有大约100个文件夹,我不想在我的log4j.xml文件中为其编写Appenders和记录器" 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    <param name="File" value="Folder1/log1.log" />
    <param name="Append" value="true" />
    <param name="MaxFileSize" value="10MB" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%m%n" />
    </layout>
</appender>


    <param name="File" value="Folder1/log2.log" />
    <param name="Append" value="true" />
    <param name="MaxFileSize" value="10MB" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%m%n" />
    </layout>
</appender>


    <param name="File" value="Folder1/log3.log" />
    <param name="Append" value="true" />
    <param name="MaxFileSize" value="10MB" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%m%n" />
    </layout>
</appender>

<logger name="Logger1" additivity="false">
    <level value="INFO" />
   
</logger>

<logger name="Logger2" additivity="false">
    <level value="INFO" />
   
</logger>

<logger name="Logger3" additivity="false">
    <level value="INFO" />
   
</logger>

将在运行时创建文件夹

我的方法:
我想根据我的文件夹名称实例化我的记录器,并将其保存在像

这样的哈希图中

1
2
3
4
5
HashMap<FolderName, HashMap<LoggerType, LoggerObject>>

FolderName: String
LoggerType: it will be an Enum of log1, log2 and log3
LoggerObject: It will a log4j Logger object

因此,我将提供一种获取LoggerObject的方法,例如

1
2
3
4
5
6
public Logger getLoggerObject(String folderName, LoggerType loggerType){
     \\\\logic
     return loggerObject;
}

Logging.getLoggerObject("Folder1", LoggerType.log1).info("I am writing to log1.log file in Folder1");

问题:
1.我无法在运行时配置LoggerObjects。帮助我做到这一点!
2.如何为多个文件夹位置和多个日志文件配置我的记录器?


因为您说过您愿意切换到log4j2,所以我建议您这样做,然后使用类似Log4j2 FAQ中有关动态写入单独日志文件的示例的RoutingAppender。

以下示例代码说明了如何使用ThreadContext快速更改文件夹和日志文件:

首先,我们创建2个实现Runnable的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package runners;

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

public class Runner1 implements Runnable{
    private static final Logger log = LogManager.getLogger();

    public void run() {
        //Set up the context before getting logger
        ThreadContext.put("logFolder","Folder1");
        ThreadContext.put("logFileName","log1");

        //Generate some logs
        log.info("here's the first thread");

        //Wait a while so that threads interleave
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //Generate more logs
        log.debug("some debug in first thread");
        log.info("finishing first thread");

    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package runners;

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

public class Runner2 implements Runnable{
    private static final Logger log = LogManager.getLogger();

    public void run() {
        //Set up the context before getting logger
        ThreadContext.put("logFolder","Folder2");
        ThreadContext.put("logFileName","log2");

        //Generate some logs
        log.info("here's the second thread");
        log.debug("some debug in second thread");

    }
}

现在有一个基本的控制器类来创建和启动2个线程:

1
2
3
4
5
6
7
8
9
10
11
12
package runners;

public class Controller {

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runner1());
        Thread t2 = new Thread(new Runner2());
        t1.start();
        t2.start();
    }

}

最后,我们需要配置log4j2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Routing name="MyRoutingAppender">
            <Routes pattern="$${ctx:logFolder}-$${ctx:logFileName}">
                <Route>
                    <File fileName="logs/${ctx:logFolder}/${ctx:logFileName}.log"
                        name="appender-${ctx:logFolder}-${ctx:logFileName}">
                        <PatternLayout>
                            <Pattern>[%date{ISO8601}][%-5level][%t] %m%n</Pattern>
                        </PatternLayout>
                    </File>
                </Route>
            </Routes>
        </Routing>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="[%date{ISO8601}][%-5level][%t] %m%n" />
        </Console>

    </Appenders>
    <Loggers>
        <Logger name="runners" level="TRACE" additivity="false">
            <AppenderRef ref="STDOUT" />
            <AppenderRef ref="MyRoutingAppender" />
        </Logger>
        <Root level="WARN">
            <AppenderRef ref="STDOUT" />
        </Root>
    </Loggers>
</Configuration>

运行Controller后,您将看到生成了两个文件夹,每个文件夹中都有一个文件:

enter