我在Tomcat中说我的应用程序作为2个实例运行,例如客户端和服务器,我必须在特定于john.log这样的用户的唯一文件中捕获登录用户的用户活动。我能够使用Log4j2中的“路由”并将两个应用程序中的log4j2日志文件位置指向同一目录来实现此目标。
这是一个问题,当我每天晚上/每1小时尝试将日志文件翻转时,都会抛出异常,表明该文件已被另一个程序访问。
当我尝试单独编写日志而不是一个文件时,它可以正常工作并按照cron条件进行滚动,但是当指向同一目录并访问相同文件时,滚动会在滚动过程中引发异常。 我正在使用最新的Log4j2版本“ 2.11.2”
客户端Log4j xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Configuration status="WARN" name="MyApp-Client" monitorInterval="30">
<Properties>
<!-- Log File location-->
<Property name="BaseDir">C:\\Log_Files\webapp</Property>
<!-- Log pattern -->
<Property name="pattern">[%-5level] [%d] [%c{1}] - %msg%n</Property>
<!-- Routing File -->
<Property name="RoutFileName">${BaseDir}\${ctx:logFileName}.log</Property>
<Property name="RoutFilePattern">${BaseDir}\${ctx:logFileName}-%d{yyyy-MM-dd}-%i.log</Property>
<!-- CRON pattern -->
<Property name="Roll_perminute">0 * * * * ?</Property>
<Property name="Roll_Daily">0 0 0 * * ?</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${pattern}" />
</Console>
<Routing name="USERLEVEL">
<Routes pattern="$${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}" append="true" fileName="${RoutFileName}" filePattern="${RoutFilePattern}">
<PatternLayout pattern="Client-LOG: ${pattern}" />
<Policies>
<CronTriggeringPolicy schedule="${Roll_perminute}" evaluateOnStartup="true"/>
</Policies>
</RollingFile>
</Route>
<Route ref="Console" key="${ctx:logFileName}" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="com.myapp" level="ALL" additivity="false">
<Appender-Ref ref="USERLEVEL" level="ALL" />
</Logger>
<Root level="ALL" additivity="false">
<Appender-Ref ref="Console" level="ALL" />
</Root>
</Loggers>
</Configuration>
服务器Log4j xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Configuration status="WARN" name="MyApp-Server" monitorInterval="30">
<Properties>
<!-- Log File location-->
<Property name="BaseDir">C:\\Log_Files\webapp</Property>
<!-- Log pattern -->
<Property name="pattern">[%-5level] [%d] [%c{1}] - %msg%n</Property>
<!-- Routing File -->
<Property name="RoutFileName">${BaseDir}\${ctx:logFileName}.log</Property>
<Property name="RoutFilePattern">${BaseDir}\${ctx:logFileName}-%d{yyyy-MM-dd}-%i.log</Property>
<!-- CRON pattern -->
<Property name="Roll_perminute">0 * * * * ?</Property>
<Property name="Roll_Daily">0 0 0 * * ?</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${pattern}" />
</Console>
<Routing name="USERLEVEL">
<Routes pattern="$${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}" append="true" fileName="${RoutFileName}" filePattern="${RoutFilePattern}">
<PatternLayout pattern="SERVER-LOG: ${pattern}" />
<Policies>
<CronTriggeringPolicy schedule="${Roll_perminute}" evaluateOnStartup="true"/>
</Policies>
</RollingFile>
</Route>
<Route ref="Console" key="${ctx:logFileName}" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="com.myapp" level="ALL" additivity="false">
<Appender-Ref ref="USERLEVEL" level="ALL" />
</Logger>
<Root level="ALL" additivity="false">
<Appender-Ref ref="Console" level="ALL" />
</Root>
</Loggers>
</Configuration>
引发错误
2019-05-31 19:43:00,021 Log4j2-TF-3-Scheduled-4 ERROR Unable to move file C:\\Log_Files\webapp\User1.log to C:\\Log_Files\webapp\User1-2019-05-31-1.log: java.nio.file.FileSystemException C:\\Log_Files\webapp\User1.log -> C:\\Log_Files\webapp\User1-2019-05-31-1.log: The process cannot access the file because it is being used by another process.
2019-05-31 19:43:00,026 Log4j2-TF-3-Scheduled-4 ERROR Unable to delete file C:\\Log_Files\webapp\User1.log: java.nio.file.FileSystemException C:\\Log_Files\webapp\User1.log: The process cannot access the file because it is being used by another process.
基于引发的错误,我确实理解了触发翻转还是仍然由任何一个记录器实例访问日志文件。但是在这种情况下我们如何安全地进行翻转,我在配置上做错了吗。我们在log4j2中还有其他选择可以实现这一目标