java当使用lo4j2进行滚动时,如何避免FileSystemException(无法删除其他进程使用的文件)?
当使用带有Log4j2库的CronTriggeringPolicy进行滚动时,我们会丢失日志文件,同时调用应用程序(我使用postman在滚动事件发生前5秒启动了10个调用)。在其他服务写入日志文件时,是否有方法更改应用程序中的配置或使用日志记录器进行线程安全滚动,以避免在生产中丢失有价值的日志文件
该应用程序运行在IBM WebSphere application Server 8.5.5.14、Red Hat Enterprise Linux 7.3、其他技术/库:Java 7、Java EE 6、Log4j2(v2.11.2)中
没有使用框架,我们使用的是WebSphere提供的实现
文件权限没有问题,因为用于启动服务器的用户是整个目录和子目录的所有者
我发现这个问题是当一个服务(或多个服务)在文件上写入并且发生滚动时进行检查。当log4j2试图移动文件时,文件明显被锁定。我已经阅读了文档,但还没有找到一个明确的例子来避免这个问题
这是扩展应用程序的websphere入口点类:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("")
public NiceServiceApplication extends Application {}
然后,我们可以从服务调用一个简单的bean
import org.apache.logging.log4j.Logger;
public interface BeanOne {
public abstract void hello();
public abstract void setLogger(Logger logger);
}
bean的实现
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
@Stateless
@Remote(BeanOne.class)
@TransactionManagement(TransactionManagementType.BEAN)
public class BeanOneImpl implements BeanOne {
private Logger logger;
public void hello() {
logger.info("Hello in bean one called :D");
}
public void setLogger(Logger logger) {
if(logger == null) {
LogManager.getLogger("fallback-logger")
} else {
this.logger = logger;
}
}
}
服务类
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/helloService")
public class NiceService {
private static final Logger logger = LogManager.getLogger("nice-logger");
@EJB
private BeanOne bean;
@PostConstruct
private void init() {
beanOne.setLogger(logger);
}
@GET
@Path("/hello")
@Produces(MediaType.APPLICATION_JSON)
public Response sayHelloToMe() {
bean.hello();
return Response.ok().entity("{\"msg\":\"Hello there!\"}").build();
}
}
使用的Lo4j2配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="30">
<Properties>
<Property name="log-path">C:\logs</Property>
</Properties>
<Appenders>
<!-- Default Console appender -->
<Console name="console-log" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %p %c{1}:%M - %m%n" />
</Console>
<RollingFile name="fallback-log-appender"
fileName="${log-path}/fallback.log"
filePattern="${log-path}/archive/fallback-%d{yyyyMMddHHmmss}.log.gz">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %p %C{1}:%M - %m%n</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="100 MB" />
<CronTriggeringPolicy schedule="0 0/5 * ? * * *"/>
</Policies>
</RollingFile>
<RollingFile name="nice-log-appender"
fileName="${log-path}/nice-service.log"
filePattern="${log-path}/archive/nice-service-%d{yyyyMMddHHmmss}.log.gz">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %p %C{1}:%M - %m%n</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50 MB" />
<CronTriggeringPolicy schedule="0 0/5 * ? * * *"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="console-log" />
</Root>
<Logger name="fallback-logger" level="trace" additivity="false">
<Appender-ref ref="fallback-log-appender" level="trace" />
</Logger>
<Logger name="nice-logger" level="trace" additivity="false">
<Appender-ref ref="nice-log-appender" level="trace" />
</Logger>
</Loggers>
</Configuration>
我从log4j2得到的异常是:
[04/07/19 13.35.00:041 CEST] 000000ee SystemOut O 2019-07-04 13:35:00,041 Log4j2-TF-7-Scheduled-6 ERROR Unable to delete file C:\logs\nice-service.log: java.nio.file.FileSystemException C:\logs\nice-service.log: Impossibile accedere al file. Il file è utilizzato da un altro processo.
我希望在滚动事件发生后,gzip日志文件可以毫无问题地移动到归档文件夹中
共 (0) 个答案