当前位置: 首页 > 知识库问答 >
问题:

独立地登录多个文件夹中的多个文件-log4j JAVA

夏景胜
2023-03-14

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

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

我想让我的记录器独立地登录到文件中。

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

<appender name="logfile1" class="org.apache.log4j.RollingFileAppender">
    <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>

<appender name="logfile2" class="org.apache.log4j.RollingFileAppender">
    <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>

<appender name="logfile3" class="org.apache.log4j.RollingFileAppender">
    <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" />
    <appender-ref ref="logfile1" />
</logger>

<logger name="Logger2" additivity="false">
    <level value="INFO" />
    <appender-ref ref="logfile2" />
</logger>

<logger name="Logger3" additivity="false">
    <level value="INFO" />
    <appender-ref ref="logfile3" />
</logger>

这些文件夹将在运行时创建

我的方法:
我想根据我的文件夹名实例化我的记录器,并将它们保存在一个hashmap中,如

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

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.如何为多个文件夹位置和多个日志记录文件配置我的记录器?

共有1个答案

邹野
2023-03-14

既然您说过愿意切换到log4j2,我建议您这样做,然后使用RoutingAppender,类似于log4j2常见问题解答中关于动态写入单独日志文件的示例。

下面是一些示例代码,说明如何使用ThreadContext动态更改文件夹和日志文件:

首先,我们创建两个实现runnable的类:

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

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

    }
}
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:

<?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>

运行控制器后,您将看到生成两个文件夹,每个文件夹中有一个文件:

来自第一个线程的日志位于folder1>log1中,来自第二个线程的日志位于folder2>log2中

 类似资料:
  • 我是java新手,我在VSCODE上编码。我创建2.java文件,如下图所示: 这些是每个文件: Main.java:

  • 我有100个不同名称的文件夹,每个文件夹中应该有相同的三个文件,但在某些文件夹中,这三个文件都不存在。 如何删除空文件夹或仅包含一个或两个文件的文件夹? 这是三个文件:

  • 问题内容: 我想知道如何从单个文件夹中读取多个文件(无需指定文件名,只是它们是json文件)。 另外,有可能将它们转换为DataFrame吗? 能给我一个基本的例子吗? 问题答案: 一种选择是使用os.listdir列出目录中的所有文件,然后仅查找以’.json’结尾的文件: 现在,您可以使用pandas DataFrame.from_dict将json(此时为python字典)读入pandas数

  • //我得到的错误是java。尼奥。文件FileAlreadyExistsException所以据我所知,它试图将文件保存到确切的位置,而不是保存在文件中,如果我将目标地址改为“垃圾/垃圾”,我需要以这种方式保存几个文本文件。它将在那里保存一个名为垃圾的文件。txt。但在for-each的下一个循环中,它会抛出一个“已经存在”的异常。。。 有人能解释一下我如何从src文件夹将所有txt文件保存到该文

  • 在一个项目中,我有3个src文件夹(src1、src2、src3)。我已经能够通过将文件夹合并到单个src中来编译它。 当我使用helper插件编译它并定义三个src文件夹时,我可以看到78个java文件正在编译,但在最终的包中只包含4个类文件。 “-X”没有用。

  • 我在同一个文件夹中有数千个csv文件名,如下file_x_x.csv,其中x是1到10000之间的数字。每个文件包括一个标题和一行数据: file_1_1.csv 我的方法: 我不知道如何在最后创建一个唯一的文件。你能看一下上面的代码并告诉我如何获得所需的输出吗?如果我错过了什么?