在我的 Spring Boot 应用程序中,我们需要仅为某些特定的日志消息添加额外的标签(键/值对),以突出显示这些是一些特殊用途的日志,而不是其他日志。
项目log4j2.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<JsonTemplateLayout eventTemplateUri="classpath:LogstashLayout.json">
</JsonTemplateLayout>
</Console>
</Appenders>
<Loggers>
<AsyncRoot level="info" additivity="false">
<AppenderRef ref="console" />
</AsyncRoot>
</Loggers>
</Configuration>
执行此操作的标准推荐方法是什么?这是否需要进行某种过滤器配置?
认为marker会对您有所帮助,尽管它只能标记日志消息但不能向其添加键/值。当你使用它来标记日志消息后,你可以在配置中配置一个filter来决定是否应该显示带有特定标签的消息。
例如,您可以为日志消息添加类似以下的标签:
public class Foo {
private static final Marker TAG1 = MarkerManager.getMarker("TAG1");
private static final Marker TAG2 = MarkerManager.getMarker("TAG2");
private static final Marker TAG3 = MarkerManager.getMarker("TAG3");
void test(){
log.info(TAG1, "message with tag1");
log.info(TAG1, "message with tag1");
log.info(TAG2, "message with tag2");
log.info(TAG2, "message with tag2");
log.info(TAG3, "message with tag3");
log.info(TAG3, "message with tag3");
}
}
然后使用此过滤器配置:
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{ISO8601} |%t| %5p | %c{1} | %L | %m%n" />
<Filters>
<MarkerFilter marker="TAG1" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="TAG2" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="TAG3" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>>
</Console>
</Appenders>
仅带有
TAG1
、 TAG2
且没有标签的消息才会显示到控制台。带有 TAG3
的消息不会。
如果过滤器配置是:
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{ISO8601} |%t| %5p | %c{1} | %L | %m%n" />
<Filters>
<MarkerFilter marker="TAG1" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="TAG2" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="TAG3" onMatch="DENY" onMismatch="DENY"/>
</Filters>>
</Console>
</Appenders>
则仅显示带有
TAG1
、 TAG2
的消息。带有 TAG3
或没有标签的消息不会。
过滤器可以在记录器级别或附加程序级别配置。我发现这个答案有助于理解过滤器如何工作的基本概念。
您可以创建另一个自定义类来处理在日志记录机制中添加额外标签(键/值)对。
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
import org.json.simple.JSONObject;
public class CustomLogger {
private static CustomLogger instance = null;
private static final Logger logger = LogManager.getLogger(CustomLogger.class);
private final static CustomLogger log = CustomLogger.getLogger();
private CustomLogger() {
super();
}
public static CustomLogger getLogger(){
if(instance==null){
instance = new CustomLogger();
//Configurator.setAllLevels(logger.getName(), org.apache.logging.log4j.Level.ALL);
}
return instance;
}
public void info(String msg) {
logger.info(msg);
}
public void info(JSONObject obj, String msg) {
// Add your key/value
logger.info("["+obj+"]" + msg);
}
}
您可以将这个自定义类与正常的日志机制一起使用。
import org.json.simple.JSONObject;
public class CustomLoggerMain {
private static final Logger logger = LogManager.getLogger(CustomLoggerMain.class);
public static void main(String[] args) {
CustomLogger log = CustomLogger.getLogger();
JSONObject obj = new JSONObject();
obj.put("test", "logger-test");
log.info(obj, "Msg with extra key pair");
//Configurator.setAllLevels(logger.getName(), org.apache.logging.log4j.Level.ALL);
logger.info("Normal Logger");
}
}
希望此解决方案能够解决问题或为您提供如何处理这种情况的想法。这是一个基本示例,您可以根据您的要求或项目进行自定义。