How can I configure Logback to log different levels for a logger to different destinations?

前端 未结 12 1724
挽巷
挽巷 2020-11-28 18:37

How can I configure Logback to log different levels for a logger to different destinations?

For example, given the following Logback configuration, will Logback reco

相关标签:
12条回答
  • 2020-11-28 18:45

    Example of how to output colored messages of level "INFO" or higher to console and messages of level "WARN" or higher to file.

    Your logback.xml file:

    <?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>
    
    0 讨论(0)
  • 2020-11-28 18:47

    Solution based on configuration only, with a ThresoldFilter and LevelFilters to keep things really simple to understand :

    <configuration>
        <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>
    
    0 讨论(0)
  • 2020-11-28 18:47

    The simplest solution is to use ThresholdFilter on the appenders:

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

    Full example:

    <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>
    

    Update: As Mike pointed out in the comment, messages with ERROR level are printed here both to STDOUT and STDERR. Not sure what was the OP's intent, though. You can try Mike's answer if this is not what you wanted.

    0 讨论(0)
  • 2020-11-28 18:48

    This is the configuration that I use, which works fine, it is based on XML + JaninoEventEvaluator (requires the Janino library to be added to 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>  
    
    0 讨论(0)
  • 2020-11-28 18:50

    I use logback.groovy to configure my logback but you can do it with xml config as well:

    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"])
    

    I think to use GEventEvaluator is simplier because there is no need to create filter classes.
    I apologize for my English!

    0 讨论(0)
  • 2020-11-28 18:54

    okay, here is my favorite xml way of doing it. I do this for the eclipse version so I can

    • click on stuff to take me to the log statements and
    • see info and below in black and warn/severe in red

    and for some reason SO is not showing this all properly but most seems to be there...

    <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>
    
    0 讨论(0)
提交回复
热议问题