以编程方式configurationLogBack appender

我有一个在logback.xml中定义的logback appender,它是一个数据库appender,但是我很好奇,是否有任何方法来使用我自己的连接池定义为一个bean在java中configurationappender。

我发现类似的东西,但从来没有真正的答案。

这里有一个简单的例子,适用于我(请注意,在本例中使用了FileAppender)

import org.slf4j.LoggerFactory; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.FileAppender; public class Loggerutils { public static void main(String[] args) { Logger foo = createLoggerFor("foo", "foo.log"); Logger bar = createLoggerFor("bar", "bar.log"); foo.info("test"); bar.info("bar"); } private static Logger createLoggerFor(String string, String file) { LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); PatternLayoutEncoder ple = new PatternLayoutEncoder(); ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n"); ple.setContext(lc); ple.start(); FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>(); fileAppender.setFile(file); fileAppender.setEncoder(ple); fileAppender.setContext(lc); fileAppender.start(); Logger logger = (Logger) LoggerFactory.getLogger(string); logger.addAppender(fileAppender); logger.setLevel(Level.DEBUG); logger.setAdditive(false); /* set to true if root should log too */ return logger; } } 

你可以通过编程来configurationappender。 几乎所有的appender都使用编程configuration进行testing。 由此可见,logback项目源代码中有许多编程appenderconfiguration的例子。 对于logback-core appender,在logback-core/src/test/java下查看,在logback-classic/src/test/java下查看logback-classic appender。

只是,如果有人会寻找一个编程configuration的具体例子。

在这里,我设置了ConsoleAppender的字符集:

 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); ConsoleAppender<ILoggingEvent> appender = (ConsoleAppender) lc.getLogger("appconsole").getAppender("STDOUT"); LayoutWrappingEncoder<ILoggingEvent> enc = (LayoutWrappingEncoder<ILoggingEvent>) appender.getEncoder(); enc.setCharset(Charset.forName("utf-8")); 

和我的logback.xml:

 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <charset>866</charset> <pattern>[%level] %msg%n</pattern> </encoder> </appender> <logger name="appconsole"> <appender-ref ref="STDOUT" /> </logger> 

为什么我需要programmaticalyconfigurationlogging器? 因为,我将我的应用程序(Spring Boot)打包成一个jar文件。 因此,Logback.xml文件似乎隐藏在一个jar中。 虽然拆包改造并不方便, 我的app.jar旁边不需要任何logback.xml文件。 我只有app.yaml文件,其中包含应用程序的所有configuration属性。

作为参考,当您尝试修改负责创buildlogging器的代码时,为了使logging器工作,必须满足一系列规则。

这些规则在一篇很有帮助的文章中描述了slf4j / logback的程序化configuration :

现在我有slf4j / logback的编程configuration经验。

任务

程序必须为每个已处理的input文件打开单独的日志文件。

解决任务

而不是通过xmlconfigurationlogback,需要“手动”实例化编码器,appender和logging器,然后configuration和链接在一起。

注意事项1

Logback在试图在appender之间共享编码器(即PatternLayoutEncoder)时变得疯狂。

解决方法注意事项1

为每个appender创build单独的编码器。

警告2

如果编码器和appender与logging上下文没有关联,Logback拒绝logging任何东西。

解决scheme的注意事项2

在每个编码器和appender上调用setContext,传递LoggerFactory作为参数。

警告3

如果编码器和appender没有启动,Logback拒绝logging任何东西。

解决scheme的注意事项3

编码器和appender需要以正确的顺序启动,即第一个编码器,然后是appender。

警告4

如果RollingPolicy对象(即TimeBasedRollingPolicy)未附加到与appender相同的上下文,则会生成奇怪的错误消息,如“date格式未识别”。

解决scheme的注意事项4

在RollingPolicy上调用与编码器和appender相同的setContext。

这里是“手动”logbackconfiguration的工作示例:

 package testpackage import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.classic.LoggerContext import ch.qos.logback.classic.encoder.PatternLayoutEncoder import ch.qos.logback.core.ConsoleAppender import ch.qos.logback.core.rolling.RollingFileAppender import ch.qos.logback.core.rolling.TimeBasedRollingPolicy import org.slf4j.LoggerFactory class TestLogConfig { public static void main(String[] args) { LoggerContext logCtx = LoggerFactory.getILoggerFactory() PatternLayoutEncoder logEncoder = new PatternLayoutEncoder() logEncoder.setContext(logCtx) logEncoder.setPattern('%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level - %msg%n') logEncoder.start() ConsoleAppender logConsoleAppender = new ConsoleAppender() logConsoleAppender.setContext(logCtx) logConsoleAppender.setName('console') logConsoleAppender.setEncoder(logEncoder) logConsoleAppender.start() logEncoder = new PatternLayoutEncoder() logEncoder.setContext(logCtx) logEncoder.setPattern('%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level - %msg%n') logEncoder.start() RollingFileAppender logFileAppender = new RollingFileAppender() logFileAppender.setContext(logCtx) logFileAppender.setName('logFile') logFileAppender.setEncoder(logEncoder) logFileAppender.setAppend(true) logFileAppender.setFile('logs/logfile.log') TimeBasedRollingPolicy logFilePolicy = new TimeBasedRollingPolicy() logFilePolicy.setContext(logCtx) logFilePolicy.setParent(logFileAppender) logFilePolicy.setFileNamePattern('logs/logfile-%d{yyyy-MM-dd_HH}.log') logFilePolicy.setMaxHistory(7) logFilePolicy.start() logFileAppender.setRollingPolicy(logFilePolicy) logFileAppender.start() Logger log = logCtx.getLogger("Main") log.additive = false log.level = Level.INFO log.addAppender(logConsoleAppender) log.addAppender(logFileAppender) } }