Logging in multiple files in multiple folders independently - log4j JAVA
我正在开发一个多线程应用程序,其中我想使用log4j在不同的位置进行日志记录。
场景:
Folder1 ---> log1.log
log2.log
log3.logFolder2 ---> 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。
以下示例代码说明了如何使用
首先,我们创建2个实现
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 |
最后,我们需要配置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> |
运行
第一个线程的日志位于文件夹1> log1中,第二个线程的日志位于文件夹2> log2
中
请注意,我使用了基本的文件附加程序,但是您可以在路由附加程序中交换其他附加程序以满足您的需求。
希望这有助于您入门。