Я использовал пользовательский плагин, зарегистрированный программно с использованием класса PluginManager, чтобы загрузить значения в карту и изменить имя файла моего RollingFileAppender на основе содержимого карты.
Затем я изменил свою конфигурацию, чтобы использовать маршрутизацию appender, чтобы иметь возможность использовать содержимое ThreadContext для дальнейшего изменения fileName (в основном, я хотел иметь один файл журнала на поток моего приложения).
Однако, так как я начал использовать приложение Routing, мой пользовательский плагин не дает желаемых результатов больше, хотя я не изменил его вообще. По сути, он возвращает пустые значения.
Моя log4j2-конфигурация. 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>
Класс, который отвечает за загрузку карты, находится здесь:
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".
Я пробовал несколько вещей, которые не помогли:
На данный момент я прибег к развертыванию приложения в tomcat с использованием файла xml, который включает параметр контекста, доступный через $ {web: initParam.warName}, но это не очень практично для меня.
Есть ли Может быть, это встроенный способ получить название развертываемой войны, не прибегая даже к «пользовательскому» подходу к параметрам?
Спасибо!