gpt4 book ai didi

java - Log4j2:切换到路由后自定义插件不起作用

转载 作者:行者123 更新时间:2023-12-02 09:02:51 27 4
gpt4 key购买 nike

我使用的是通过 PluginManager 类以编程方式注册的自定义插件,以加载 map 中的值并根据 map 的内容更改 RollingFileAppender 的文件名。

然后,我更改了配置以使用路由附加程序,以便能够使用 ThreadContext 内容进一步更改文件名(基本上,我希望应用程序的每个线程都有一个日志文件)。

但是,自从我开始使用路由附加器以来,我的自定义插件不再产生所需的结果,尽管我根本没有更改它。基本上,它返回空值。

我的 log4j2-configuration.xml 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m%n"/>
<ThresholdFilter level="debug"/>
</Console>

<Routing name="contextSpecificAppender">
<Routes pattern="$${ctx:threadName}">
<!-- This route is chosen if ThreadContext has no value for key threadName -->
<Route key="$${ctx:threadName}">
<RandomAccessFile
name="applicationAppender"
fileName="${sys:catalina.base}/logs/${propertymap:warName}.log"
filePattern="${sys:catalina.base}/logs/%d{yyyy-MM-dd}/${propertymap:warName}.%i.log"
append="true"
>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %highlight{%p} %style{[%t]}{magenta} %style{%c{1}:%L}{cyan,bold} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBaseTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="1" />
</RandomAccessFile>
</Route>
<Route>
<RandomAccessFile
name="${ctx:threadName}"
fileName="${sys:catalina.base}/logs/${propertymap:warName}-${ctx:threadName}.log"
filePattern="${sys:catalina.base}/logs/%d{yyyy-MM-dd}/${propertymap:warName}-${ctx:threadName}.%i.log"
append="true"
>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %highlight{%p} %style{[%t]}{magenta} %style{%c{1}:%L}{cyan,bold} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBaseTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="1" />
</RandomAccessFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="contextSpecificAppender" />
<!--<AppenderRef ref="STDOUT"/>-->
</Root>
<Logger name="org.apache.axis2.enterprise" level="info">
<AppenderRef ref="contextSpecificAppender" />
</Logger>
<Logger name="de.hunsicker.jalopy.io" level="fatal">
<AppenderRef ref="contextSpecificAppender" />
</Logger>
<Logger name="httpclient.wire.header" level="fatal">
<AppenderRef ref="contextSpecificAppender" />
</Logger>
<Logger name="org.apache.commons.httpclient" level="info">
<AppenderRef ref="contextSpecificAppender" />
</Logger>
</Loggers>
</Configuration>

负责加载 map 的类在这里:

package com.my.package;

import java.net.URISyntaxException;
import java.net.URL;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.plugins.util.PluginManager;

/**
*
* @author ixm
*/
public class Log4jInitiliazer {
public static void initialize(String warName, URL log4jProperties) {
PropertyMapLookup.propertyMap.put("warName", warName);

PluginManager.addPackage(PropertyMapLookup.class.getPackageName());

LoggerContext context = (LoggerContext) LogManager.getContext(false);
try {
context.setConfigLocation(log4jProperties.toURI());
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
}
}

它是从 ServletContextListener 调用的:

Log4jInitiliazer.initialize(warName, servletContextEvent.getServletContext().getResource("/WEB-INF/classes/log4j2-configuration.xml"));

最后,插件本身在这里:

package com.my.package;

import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;

/**
*
* @author ixm
*/
@Plugin(name="propertymap", category=StrLookup.CATEGORY)
public class PropertyMapLookup implements StrLookup {
public static Map<String, String> propertyMap = new HashMap();

@Override
public String lookup(String arg0) {
return propertyMap.getOrDefault(arg0, "");
}

@Override
public String lookup(LogEvent arg0, String arg1) {
return propertyMap.getOrDefault(arg0, "");
}

}

生成的日志文件名都是“/var/log/tomcat9/-theNameOfTheThread.log”,而应该是“/var/log/tomcat9/theNameOfTheWar-theNameOfTheThread.log”。

我尝试了几种没有帮助的方法:

目前,我已采取使用 xml 文件在 tomcat 中部署应用程序的方法,该文件包含可使用 ${web:initParam.warName} 访问的上下文参数,但这对我来说并不实际。

是否有一种嵌入式方法可以检索正在部署的 war 的名称,而无需使用“自定义”参数方法?

谢谢!

最佳答案

事实上,当它停止工作时,它正在创建一个名为“-threadId.log”的文件,这表明您的查找正在被调用。如果不是,文件名将为“${propertyMap:warName}-thr​​eadId.log”。因此,这意味着您存储的 warName 是错误的,或者您的查找有问题。我能想到两种可能性。

  1. 您没有说明 war 名称是如何得出的。那里可能出了问题。
  2. 您的 Lookup 可能存在于 2 个不同的类加载器中。如果发生这种情况,您将在 servlet 上下文初始化程序中初始化一个,但在记录时使用另一个。

如果是我,我会进行调试并确保在添加 war 名称和查找 war 名称时使用相同的 map 。

正如我在上面的评论中指出的,您还可以使用网络查找的 contextPath 键作为 ${web:contextPath}。它并不总是与 war 名称相同,但在默认的 Tomcat 环境中应该相同。

关于java - Log4j2:切换到路由后自定义插件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60035556/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com