我们正在从Log41.x迁移到Log4j2.x。我们在log4j1中进行了一些自定义日志记录,在其中将一些日志参数放入ThreadLocal中,以获取一些日志,以及由记录器选择并发送到附加程序的那些参数。附加程序也是自定义附加程序,它将日志消息格式化为Json格式。每次记录后,将从本地线程中清除这些参数。
我想在log4j2中实现以支持旧的日志记录系统。
我已经尝试通过覆盖日志方法创建自定义LoggerConfig类来在log4j2中进行尝试,在那里我从线程本地清除了参数。
要包括自定义Logger配置插件,我将{log4j.plugin.packages}系统属性设置为我的customLoggerConfig类包。 但是log4j2配置未选择新的记录器配置。
import java.util.Arrays;
import java.util.List;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.async.AsyncLoggerContext;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
import org.apache.logging.log4j.message.Message;
@Plugin(name = "customLogger", category = "Core", printObject = true)
public class CustomLoggerConfig extends LoggerConfig
{
public CustomLoggerConfig(final String name, final List<AppenderRef> appenders, final Filter filter,
final Level level, final boolean additive, final Property[] properties, final Configuration config, final boolean includeLocation)
{
super(name, appenders, filter, level, additive, null, config, includeLocation);
}
@Override
public void log(final String loggerName, final String fqcn, final Marker marker, final Level level,
final Message data, final Throwable t)
{
super.log(loggerName, fqcn, marker, level, data, t);
clearLogArg();
}
@Override
public void log(final LogEvent event)
{
super.log(event);
clearLogArg();
}
public void clearLogArg()
{
LogArg.clear();
}
@PluginFactory
public static LoggerConfig createLogger(@PluginAttribute(value = "additivity", defaultBoolean = true) final boolean additivity,
@PluginAttribute("level") final Level level,
@Required(message = "Loggers cannot be configured without a name") @PluginAttribute("name") final String loggerName,
@PluginAttribute("includeLocation") final String includeLocation,
@PluginElement("AppenderRef") final AppenderRef[] refs,
@PluginElement("Properties") final Property[] properties,
@PluginConfiguration final Configuration config,
@PluginElement("Filter") final Filter filter
) {
return new CustomLoggerConfig(loggerName, Arrays.asList(refs), filter, level, additivity, properties, config,
includeLocation(includeLocation, config));
}
protected static boolean includeLocation(final String includeLocationConfigValue, final Configuration configuration)
{
if (includeLocationConfigValue == null)
{
LoggerContext context = null;
if (configuration != null)
{
context = configuration.getLoggerContext();
}
if (context != null)
{
return !(context instanceof AsyncLoggerContext);
}
else
{
return !AsyncLoggerContextSelector.isSelected();
}
}
return Boolean.parseBoolean(includeLocationConfigValue);
}
}