如何在服务器重启或更改XML配置文件后保留log4j2的插件配置
我已经开发了一个定制的滚动文件附加器,它工作得很好。唯一的问题是,每当我重新启动服务器或更改log4j2.xml文件(文件的任何部分)时,它都会重新初始化,并且所有以前的日志都会突然被擦除。我没有观察到附带的默认附加器的这种行为,所以我想知道我可以做些什么来保留我的配置。
<CustomAppender name="CustomAppender"
fileName="${log.file.directory}/file.log"
filePattern="${log.file.directory}/file.log.%d{yyyy-MM-dd}-%i.gz"
immediateflush="true"
append="true">
<CustomLayout/>
<Policies>
<SizeBasedTriggeringPolicy size="3 KB"/>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
</CustomAppender>
附注:我已尝试将其设置为单例,但除此之外,它不起作用,我真的不想让它远离重新配置,我只想保留我以前生成的日志。
更新
显然,每次服务器关闭或更改log4j2.xml文件时,管理器都会从头开始重新构建附加器,尽管内置的附加器即使在重新启动或重新配置之后也会保持其状态。它们通过覆盖AbstractOutputStreamAppender.中的&Stop&Quot;方法来实现这一点我对我的附加器执行了相同的操作,但它的行为仍然不符合我的预期。@Override
public boolean stop(long timeout, TimeUnit timeUnit) {
setStopping();
final boolean stopped = super.stop(timeout, timeUnit, false);
setStopped();
return stopped;
}
这是我在附加器生成器中使用的管理器:
final RollingFileManager manager = RollingFileManager.getFileManager(fileName, filePattern, append,
isBufferedIo, policy, strategy, advertiseUri, layout, bufferSize, isImmediateFlush(),
createOnDemand, filePermissions, fileOwner, fileGroup, getConfiguration());
if (manager == null) {
return null;
}
manager.initialize();
解决方案
重新配置时会发生以下情况:
- 读取新配置文件并将其转换为节点树。
- 访问与节点关联的插件并创建其对应的类。
- 如果配置创建成功,则启动配置。
- 记录器已更新以引用新配置。
- 旧配置已停止。
如您所想,由于同时运行两个配置,这可能会导致问题。例如,如果两个组件尝试使用相同的端口,则第二个配置可能会失败。为了避免这些问题,Log4j2中的附加器使用管理器。管理器通常会有一个名称,其中包括任何项,如果它们在新配置中具有相同的值,则表明管理器应该被重新使用。这允许像OutputStreams这样的东西在重新配置期间保持打开。但是,这样做的副作用是,如果在附加器上更改了参数,并且该参数不是名称的一部分,则可能会忽略值中的更改,因为管理器未被修改。
因此,在创建新的附加器时,必须注意传递给管理器的名称,并且附加器应尝试更新管理器中不属于该名称的相关值。此外,管理器必须说明它被多次启动和停止的原因。AbstractManager实际上会为您处理此问题。相关文章