从读取log4j 2 documentation开始,如果相应的配置文件在classpath中,则应该加载配置。但我需要确定配置文件已正确处理。有没有办法可以验证我希望加载的配置文件是否实际上已找到并成功加载?
我正在编写将由其他开发人员使用的代码,并且可能是log4j 2(它是我们正在编写的库的组成部分)未正确配置的情况,因为该文件不在类路径中或配置错误。如果没有正确配置log4j 2,我必须停止进一步处理我们的库,它必须吐出重大错误,并且必须对此进行大量处理。我不能让代码继续下去。所以最重要的是,我需要知道log4j 2正确处理了预期的配置文件。
另外,我更喜欢使用log4j 2 API而不是Core库,但如果Core是唯一的方式那么就可以了。
答案 0 :(得分:3)
您只需使用api即可进行某些验证:
您可以使用StatusListener
注册StatusLogger
。 Log4J在内部使用StatusLogger来记录Log4J内部的详细信息。大多数内部日志记录都与配置有关。
例如:
public class HaltingStatusListener implements StatusListener {
public Level getStatusLevel() {
return Level.ERROR;
}
public void log(StatusData data) {
throw new BigDealException("Internal log4j error detected: "
+ data.getMessage());
}
}
但这可能不足以满足您的需求。 你可以检查另一件事:
LoggerContext context = LogManager.getContext();
if (context instanceof SimpleLoggerContext) {
throw new BigDealException(
"Log4j did not find config file & uses default setup");
}
如果您想了解更多细节并验证appender / loggers等,您将需要使用核心类。在这种情况下,请向log4j-user邮件列表发送一条消息,以便让其他团队成员参与其中。
更新: Log4J团队目前假定Log4J初始化失败不关键,不应该停止应用程序。如果没有找到核心jar或没有找到配置文件,你可以要求log4j暂停应用程序(抛出异常)的增强功能。你可以为此提出一张Jira票,也可以在邮件列表上询问。
答案 1 :(得分:0)
另一种可能的选择是直接检查StatusLogger
:
StatusLogger.getLogger().getStatusData()
.stream()
.filter(s -> s.getLevel().isMoreSpecificThan(Level.ERROR))
.forEach(s ->
System.out.println(s.getFormattedStatus())
);
这将打印所有内部log4j2 状态,错误级别为ERROR
和FATAL
答案 2 :(得分:0)
这似乎对我有用。它很有用,因为如果找不到配置文件,它会实例化一个简单的编程配置。这使得小型util类型的包更易于传输到可能发生配置文件冲突的环境。
private static boolean configured = false;
private static void buildLog()
{
try
{
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
System.out.println("Configuration found at "+ctx.getConfiguration().toString());
if(ctx.getConfiguration().toString().contains(".config.DefaultConfiguration"))
{
System.out.println("\n\n\nNo log4j2 config available. Configuring programmatically\n\n");
ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory
.newConfigurationBuilder();
builder.setStatusLevel(Level.ERROR);
builder.setConfigurationName("IkodaLogBuilder");
AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE")
.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern",
"%d [%t] %msg%n%throwable"));
builder.add(appenderBuilder);
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout").addAttribute("pattern",
"%d [%t] %-5level: %msg%n");
appenderBuilder = builder.newAppender("file", "File").addAttribute("fileName", "./logs/ikoda.log")
.add(layoutBuilder);
builder.add(appenderBuilder);
builder.add(builder.newLogger("ikoda", Level.DEBUG)
.add(builder.newAppenderRef("file"))
.add(builder.newAppenderRef("Stdout"))
.addAttribute("additivity", false));
builder.add(builder.newRootLogger(Level.DEBUG)
.add(builder.newAppenderRef("file"))
.add(builder.newAppenderRef("Stdout")));
((org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false)).start(builder.build());
ctx.updateLoggers();
}
else
{
System.out.println("Configuration file found.");
}
configured=true;
}
catch(Exception e)
{
System.out.println("\n\n\n\nFAILED TO CONFIGURE LOG4J2"+e.getMessage());
configured=true;
}
}