我正在实现log4j自定义模式转换器。在运行时,如果尝试调用转换器类的“ newInstance”方法,它将失败并显示错误:
“为cm java.lang.IllegalAccessException创建转换器时出错: 类org.apache.logging.log4j.core.pattern.PatternParser不能 使用以下命令访问com.test.plugin.LogMaskingConverter类的成员 修饰符“公共静态””
在调试之后,我发现在调用调用“ isSameClassPackage”的方法并返回false之前,应使用Reflection和Reflection类调用“ newInstance”。
一个可能的原因可能是使用不同的类加载器来加载主类和转换器类。
我尝试了以下线程中提供的解决方案,并在pom.xml中添加了插件配置,但没有一个起作用。
log4j2 configuration will not load custom pattern converter
LogMaskingConverter.java
package com.test.plugin;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
@Plugin(name = "LogMaskingConverter", category = "Converter")
@ConverterKeys({"cm"})
class LogMaskingConverter extends LogEventPatternConverter {
private static final String NAME = "cm";
private static final String JSON_REPLACEMENT_REGEX = "\"\\$1\": \"****\"";
private static final String JSON_KEYS = String.join("|", new String[]{"ssn", "private", "creditCard"});
private static final Pattern JSON_PATTERN = Pattern.compile("(${ssn|card}): ([^]+)");
private static final LogMaskingConverter INSTANCE = new LogMaskingConverter();
private LogMaskingConverter() {
super(NAME, NAME);
}
public static LogMaskingConverter newInstance(final String[] options) {
return INSTANCE;
}
@Override
public void format(LogEvent event, StringBuilder outputMessage) {
String message = event.getMessage().getFormattedMessage();
String maskedMessage = message;
if (event.getMarker().getName() == LoggingMarkers.JSON.getName()) {
try {
maskedMessage = mask(message);
} catch (Exception e) {
maskedMessage = message; // Although if this fails, it may be better to not log the message
}
}
outputMessage.append(maskedMessage);
}
private String mask(String message) {
StringBuffer buffer = new StringBuffer();
Matcher matcher = JSON_PATTERN.matcher(message);
while (matcher.find()) {
matcher.appendReplacement(buffer, JSON_REPLACEMENT_REGEX);
}
matcher.appendTail(buffer);
return buffer.toString();
}
}
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config"
status="all" packages="com.test.plugin">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern=" %-6level %cm %d{HH:mm:ss.SSS} %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger level="all" />
<root level="all">
<appender-ref ref="console" level="TRACE" />
</root>
</Loggers>
</Configuration>
主班
package com.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.test.plugin.LoggingMarkers;
public class TestLogging {
public static final Logger logger = LoggerFactory.getLogger(TestLogging.class);
public TestLogging() {
logger.info("test info");
logger.debug(LoggingMarkers.JSON, "{\"ssn\": \"1234567890\"}");
}
public static void main(String[] args) {
new TestLogging();
}
}