以编程方式配置 Log4j Loggers

我第一次尝试使用 SLF4J (与log4j绑定)。

我想配置 3 个不同的命名 Loggers ,可以由一个 LoggerFactory 返回,它将记录不同的级别,并将消息推送到不同的 appenders:

  • 记录器1“FileLogger”记录DEBUG并附加到DailyRollingFileAppender
  • 记录器2“TracingLogger”记录TRACE+并附加到JmsAppender
  • Logger 3 "ErrorLogger"记录ERROR+并附加到不同的JmsAppender

此外,我希望它们以编程方式配置(在Java中,而不是XML或log4j.properties文件中)。

我想,通常情况下,我会在一些引导代码的某个地方定义这些__abc0,比如init()方法。然而,因为我想使用slf4j-log4j,我不知道在哪里可以定义记录器并使它们对类路径可用。

我不相信这是违反SLF4J的底层目的(作为facade),因为我的代码使用SLF4J API将永远不知道这些记录器的存在。我的代码只是对SLF4J API进行普通调用,然后将它们转发到它在类路径上找到的log4j logger。

但是我如何在类路径上配置那些log4j记录器…在Java ? !

213327 次浏览

您可以通过编程方式向Log4j添加/删除Appender:

  ConsoleAppender console = new ConsoleAppender(); //create appender
//configure the appender
String PATTERN = "%d [%p|%c|%C{1}] %m%n";
console.setLayout(new PatternLayout(PATTERN));
console.setThreshold(Level.FATAL);
console.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(console);


FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("mylog.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();


//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(fa);
//repeat with all other desired appenders
我建议你把它放在一个init()的地方,在那里你确定,这将在其他任何事情之前执行。 然后可以使用

删除根日志记录器上的所有现有附加程序
 Logger.getRootLogger().getLoggerRepository().resetConfiguration();

从添加你自己的开始。当然,要使其工作,在类路径中需要log4j。

< p >备注:< br > 你可以用任何你喜欢的Logger.getLogger(...)来添加追加器。我只使用根记录器,因为它位于所有东西的底部,将处理通过其他类别中的其他appender传递的所有内容(除非通过设置可添加性标志进行了其他配置)。< / p >

如果你需要知道日志是如何工作的,以及如何决定日志写在哪里,阅读本手册可以获得更多相关信息 简而言之:< / p >

  Logger fizz = LoggerFactory.getLogger("com.fizz")

将为您提供类别“com.fizz”的记录器 对于上面的例子,这意味着用它记录的所有内容都将被引用到根记录器上的控制台和文件追加器 如果将追加器添加到 Logger.getLogger (com.fizz) .addAppender (newAppender) 那么来自fizz的日志记录将由根记录器和newAppender的所有附加程序处理 您不需要使用配置创建记录器,只需为系统中所有可能的类别提供处理程序

听起来好像您试图从“两端”(使用者端和配置端)使用log4j。

如果你想针对slf4j api编码,但提前(并以编程方式)确定类路径将返回的log4j记录器的配置,你绝对有有某种日志适应,利用惰性构造。

public class YourLoggingWrapper {
private static boolean loggingIsInitialized = false;


public YourLoggingWrapper() {
// ...blah
}


public static void debug(String debugMsg) {
log(LogLevel.Debug, debugMsg);
}


// Same for all other log levels your want to handle.
// You mentioned TRACE and ERROR.


private static void log(LogLevel level, String logMsg) {
if(!loggingIsInitialized)
initLogging();


org.slf4j.Logger slf4jLogger = org.slf4j.LoggerFactory.getLogger("DebugLogger");


switch(level) {
case: Debug:
logger.debug(logMsg);
break;
default:
// whatever
}
}


// log4j logging is lazily constructed; it gets initialized
// the first time the invoking app calls a log method
private static void initLogging() {
loggingIsInitialized = true;


org.apache.log4j.Logger debugLogger = org.apache.log4j.LoggerFactory.getLogger("DebugLogger");


// Now all the same configuration code that @oers suggested applies...
// configure the logger, configure and add its appenders, etc.
debugLogger.addAppender(someConfiguredFileAppender);
}

使用这种方法,您不需要担心在哪里/何时配置log4j记录器。当类路径第一次请求它们时,它们被惰性地构造、传递回去并通过slf4j可用。希望这对你有所帮助!

如果您已经在log4j属性中定义了一个appender,并且希望以编程方式更新它,请在log4j属性中设置名称并通过名称获取它。

下面是一个例子log4j。属性条目:

log4j.appender.stdout.Name=console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Threshold=INFO

要更新它,请执行以下操作:

((ConsoleAppender) Logger.getRootLogger().getAppender("console")).setThreshold(Level.DEBUG);

如果有人来寻找在Java中以编程方式配置log4j2,那么这个链接可能会有帮助:(https://www.studytonight.com/post/log4j2-programmatic-configuration-in-java-class)

下面是配置控制台Appender的基本代码:

ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();


builder.setStatusLevel(Level.DEBUG);
// naming the logger configuration
builder.setConfigurationName("DefaultLogger");


// create a console appender
AppenderComponentBuilder appenderBuilder = builder.newAppender("Console", "CONSOLE")
.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
// add a layout like pattern, json etc
appenderBuilder.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d %p %c [%t] %m%n"));
RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);
rootLogger.add(builder.newAppenderRef("Console"));


builder.add(appenderBuilder);
builder.add(rootLogger);
Configurator.reconfigure(builder.build());

这将重新配置默认的rootLogger,也将重新配置创建一个新的追加器