首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >独立地登录多个文件夹中的多个文件-- log4j JAVA

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

Stack Overflow用户
提问于 2018-07-19 09:30:17
回答 1查看 1.5K关注 0票数 0

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

场景

Folder1 -> log1.log 商业、商业、金融、商业、金融、金融、商业、金融、金融等行业的自愿性、自愿性、自愿性等。 成本 Folder2 -> log1.log 商业、商业、金融、商业、金融、金融、商业、金融、金融等行业的自愿性、自愿性、自愿性等。 成本

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

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

代码语言:javascript
复制
<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中,如

代码语言:javascript
复制
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

代码语言:javascript
复制
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. 如何为多个文件夹位置和多个日志文件配置我的记录器?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-28 15:15:14

既然您说您可以切换到log4j2,那么我建议您这样做,然后使用类似于关于动态写入独立日志文件的log4j2常见问题中的示例的RoutingAppender

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

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

代码语言:javascript
复制
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");

    }
}

代码语言:javascript
复制
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个线程的基本控制器类:

代码语言:javascript
复制
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:

代码语言:javascript
复制
<?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之后,您将看到生成了两个文件夹,每个文件夹中有一个文件:

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

请注意,我使用了一个基本的文件附录,但您可以在路由附录中使用不同的缓存,以满足您的需要。

希望这能让你开始工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51419053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档