我怎样才能configurationLogbacklogging到不同的目的地logging器的不同级别?

我怎样才能configurationLogbacklogging到不同的目的地logging器的不同级别?

例如,给定以下的Logbackconfiguration,Logback会将INFO消息logging到STDOUT并将ERROR消息logging到STDERR

(请注意,这个例子是第3章:Logbackconfiguration中显示的logback-examples/src/main/java/chapters/configuration/sample4.xml示例的变体 )。

 <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> <target>System.err</target> </appender> <!-- What is the effective level of "chapters.configuration"? --> <logger name="chapters.configuration" level="INFO" additivity="false"> <appender-ref ref="STDOUT" /> </logger> <logger name="chapters.configuration" level="ERROR" additivity="false"> <appender-ref ref="STDERR" /> </logger> <!-- turn OFF all logging (children can override) --> <root level="OFF"> <appender-ref ref="STDOUT" /> </root> </configuration> 

更新:有关使用Groovy的所有基于configuration的方法,请参阅Dean Hiller的答案 。

你可以用Logbackfilter做一些有趣的事情。 下面的configuration将只打印警告和错误信息到stderr,其他所有的信息都是stdout。

logback.xml

 <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <target>System.out</target> <filter class="com.foo.StdOutFilter" /> ... </appender> <appender name="stderr" class="ch.qos.logback.core.ConsoleAppender"> <target>System.err</target> <filter class="com.foo.ErrOutFilter" /> ... </appender> <logger name="mylogger" level="debug"> <appender-ref ref="stdout" /> <appender-ref ref="stderr" /> </logger> 

com.foo.StdOutFilter

 public class StdOutFilter extends ch.qos.logback.core.filter.AbstractMatcherFilter { @Override public FilterReply decide(Object event) { if (!isStarted()) { return FilterReply.NEUTRAL; } LoggingEvent loggingEvent = (LoggingEvent) event; List<Level> eventsToKeep = Arrays.asList(Level.TRACE, Level.DEBUG, Level.INFO); if (eventsToKeep.contains(loggingEvent.getLevel())) { return FilterReply.NEUTRAL; } else { return FilterReply.DENY; } } } 

com.foo.ErrOutFilter

 public class ErrOutFilter extends ch.qos.logback.core.filter.AbstractMatcherFilter { @Override public FilterReply decide(Object event) { if (!isStarted()) { return FilterReply.NEUTRAL; } LoggingEvent loggingEvent = (LoggingEvent) event; List<Level> eventsToKeep = Arrays.asList(Level.WARN, Level.ERROR); if (eventsToKeep.contains(loggingEvent.getLevel())) { return FilterReply.NEUTRAL; } else { return FilterReply.DENY; } } } 

我相信这将是最简单的解决scheme:

 <configuration> <contextName>selenium-plugin</contextName> <!-- Logging configuration --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <Target>System.out</Target> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%level] %msg%n</pattern> </encoder> </appender> <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <Target>System.err</Target> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%level] [%thread] %logger{10} [%file:%line] %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT"/> <appender-ref ref="STDERR" /> </root> </configuration> 

好的,这是我最喜欢的xml方法。 我这样做的日食版本,所以我可以

  • 点击东西,带我到日志报表和
  • 看到信息和下面的黑色和警告/严重的红色

由于某种原因,SO没有正确显示这一切,但大多数似乎在那里…

 <configuration scan="true" scanPeriod="30 seconds"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> <expression> e.level.toInt() &lt;= INFO.toInt() </expression> </evaluator> <OnMismatch>DENY</OnMismatch> <OnMatch>NEUTRAL</OnMatch> </filter> <encoder> <pattern>%date{ISO8601} %X{sessionid}-%X{user} %caller{1} %-4level: %message%n</pattern> </encoder> </appender> <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>warn</level> </filter> <encoder> <pattern>%date{ISO8601} %X{sessionid}-%X{user} %caller{1} %-4level: %message%n</pattern> </encoder> <target>System.err</target> </appender> <root> <level value="INFO" /> <appender-ref ref="STDOUT"/> <appender-ref ref="STDERR"/> </root> </configuration> 

使用ThresoldFilter和多个LevelFilters:

 <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <target>System.err</target> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> <encoder> <pattern>%date %level [%thread] %logger %msg%n</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <target>System.out</target> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>DEBUG</level> <onMatch>ACCEPT</onMatch> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>TRACE</level> <onMatch>ACCEPT</onMatch> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>DENY</onMatch> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> </filter> <encoder> <pattern>%date %level [%thread] %logger %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="STDERR" /> </root> 

这是我使用的configuration,它工作正常,它基于XML + JaninoEventEvaluator(要求将Janino库添加到Classpath中)

 <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%date | [%-5level] in [%file:%line] - %msg %n</pattern> </encoder> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator"> <expression> level &lt;= INFO </expression> </evaluator> <OnMismatch>DENY</OnMismatch> <OnMatch>NEUTRAL</OnMatch> </filter> </appender> <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <target>System.err</target> <encoder> <pattern>%date | [%-5level] in [%file:%line] - %msg %n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> </appender> <root level="DEBUG"> <appender-ref ref="STDOUT" /> <appender-ref ref="STDERR" /> </root> </configuration> 

最简单的解决scheme是在appender上使用ThresholdFilter

  <appender name="..." class="..."> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> 

完整的例子:

 <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <pattern>%d %-5level: %msg%n</pattern> </encoder> </appender> <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <target>System.err</target> <encoder> <pattern>%d %-5level: %msg%n</pattern> </encoder> </appender> <root> <appender-ref ref="STDOUT" /> <appender-ref ref="STDERR" /> </root> </configuration> 

更新:正如Mike在注释中指出的那样,带有ERROR级别的消息在这里同时打印到STDOUT和STDERR。 不知道OP的意图是什么。 如果这不是你想要的,你可以试试Mike的答案。

我使用logback.groovy来configuration我的logback,但是你也可以用xml config来做:

 import static ch.qos.logback.classic.Level.* import static ch.qos.logback.core.spi.FilterReply.DENY import static ch.qos.logback.core.spi.FilterReply.NEUTRAL import ch.qos.logback.classic.boolex.GEventEvaluator import ch.qos.logback.classic.encoder.PatternLayoutEncoder import ch.qos.logback.core.ConsoleAppender import ch.qos.logback.core.filter.EvaluatorFilter def patternExpression = "%date{ISO8601} [%5level] %msg%n" appender("STDERR", ConsoleAppender) { filter(EvaluatorFilter) { evaluator(GEventEvaluator) { expression = 'e.level.toInt() >= WARN.toInt()' } onMatch = NEUTRAL onMismatch = DENY } encoder(PatternLayoutEncoder) { pattern = patternExpression } target = "System.err" } appender("STDOUT", ConsoleAppender) { filter(EvaluatorFilter) { evaluator(GEventEvaluator) { expression = 'e.level.toInt() < WARN.toInt()' } onMismatch = DENY onMatch = NEUTRAL } encoder(PatternLayoutEncoder) { pattern = patternExpression } target = "System.out" } logger("org.hibernate.type", WARN) logger("org.hibernate", WARN) logger("org.springframework", WARN) root(INFO,["STDERR","STDOUT"]) 

我认为使用GEventEvaluator更简单,因为不需要创buildfilter类。
我为我的英语道歉!

尝试这个。 你可以使用内build的ThresholdFilterLevelFilter 。 不需要编程创build您自己的filter。 在这个例子中,WARN和ERROR级别被logging到System.err,并放在System.out中:

 <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <!-- deny ERROR level --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> </filter> <!-- deny WARN level --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>DENY</onMatch> </filter> <target>System.out</target> <immediateFlush>true</immediateFlush> <encoder> <charset>utf-8</charset> <pattern>${msg_pattern}</pattern> </encoder> </appender> <appender name="stderr" class="ch.qos.logback.core.ConsoleAppender"> <!-- deny all events with a level below WARN, that is INFO, DEBUG and TRACE --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> <target>System.err</target> <immediateFlush>true</immediateFlush> <encoder> <charset>utf-8</charset> <pattern>${msg_pattern}</pattern> </encoder> </appender> <root level="WARN"> <appender-ref ref="stderr"/> </root> <root level="TRACE"> <appender-ref ref="stdout"/> </root> 

我对这个答案没有任何评价,因为它仅仅是上面最好的两个答案的组合:X Sat Satuk和SébastienHelbert的那个: ThresholdFilter是可爱的,但是你不能把它设置成一个更高的级别,一个较低的级别*,但将它与两个LevelFilters设置为“DENY” WARNERROR作品是一种享受。

非常重要的是 :不要忘记STDERR appender中的<target>System.err</target>标签:我的遗漏让我感到沮丧了几分钟。

 <configuration> <timestamp key="byDay" datePattern="yyyyMMdd'T'HHmmss" /> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>DENY</onMatch> </filter> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> </filter> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n </pattern> </encoder> </appender> <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> <target>System.err</target> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n </pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> <appender-ref ref="STDERR" /> </root> </configuration> 

*但它确实有一个方法decide在API中,但我不知道如何在这种情况下使用它。

 <configuration scan="true" scanPeriod="60 seconds"> <appender name="A1" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${storm.log.dir}/${logfile.name}</file> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <fileNamePattern>${storm.log.dir}/${logfile.name}.%i</fileNamePattern> <minIndex>1</minIndex> <maxIndex>9</maxIndex> </rollingPolicy> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>100MB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZ} %c{1} [%p] %m%n</pattern> </encoder> </appender> <appender name="ACCESS" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${storm.log.dir}/access.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <fileNamePattern>${storm.log.dir}/access.log.%i</fileNamePattern> <minIndex>1</minIndex> <maxIndex>9</maxIndex> </rollingPolicy> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>100MB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZ} %c{1} [%p] %m%n</pattern> </encoder> </appender> <appender name="METRICS" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${storm.log.dir}/metrics.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <fileNamePattern>${storm.log.dir}/logs/metrics.log.%i</fileNamePattern> <minIndex>1</minIndex> <maxIndex>9</maxIndex> </rollingPolicy> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>2MB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%d %-8r %m%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="A1"/> </root> <logger name="backtype.storm.security.auth.authorizer" additivity="false"> <level value="INFO" /> <appender-ref ref="ACCESS" /> </logger> <logger name="backtype.storm.metric.LoggingMetricsConsumer" additivity="false" > <level value="INFO"/> <appender-ref ref="METRICS"/> </logger> </configuration> So here is the logback file in which I am not printing backtype.storm.metric.LoggingMetricsConsumer info level if i say additivity = "true" then for for all classes in backtype.* this rule will be applied 

如何输出级别为“INFO”或更高级别的彩色消息到控制台以及级别“WARN”或更高级别消息到文件的示例。

你的logback.xml文件:

 <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <!--output messages of exact level only--> <!--<onMatch>ACCEPT</onMatch>--> <!--<onMismatch>DENY</onMismatch>--> </filter> <encoder> <pattern>%d{yyyy-MMM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n </pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>myfile.log</file> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> <append>true</append> <encoder> <pattern>%d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE"/> </root> </configuration>