【问题标题】:How can I configure Logback to log different levels for a logger to different destinations?如何配置 Logback 以将记录器的不同级别记录到不同的目的地?
【发布时间】:2011-08-04 21:57:04
【问题描述】:

如何配置Logback 以将记录器的不同级别记录到不同的目的地?

例如,给定以下 Logback 配置,Logback 是否会将 INFO 消息记录到 STDOUTERROR 消息到 STDERR

(请注意,此示例是Chapter 3: Logback Configuration 中示例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>

【问题讨论】:

  • 在一个流行测验中我会说 - 更高的一个:),但说真的,如果你同时登录两个级别,你的控制台/标准输出会说什么?
  • 再想一想,我认为我更感兴趣的问题是,“如何将记录器的不同级别记录到不同的目的地”?
  • 你可能会喜欢我创建的filter
  • @kostja 这是正确的答案。 levels are ordered as follows: TRACE &lt; DEBUG &lt; INFO &lt; WARN &lt; ERROR.

标签: java logging logback


【解决方案1】:

好的,这是我最喜欢的 xml 方式。我为 eclipse 版本做这个,所以我可以

  • 点击内容将我带到日志语句和
  • 查看信息和下方以黑色显示,并以红色显示警告/严重

由于某种原因,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>

【讨论】:

  • 这是将跟踪调试信息与警告和错误分开的最佳过滤解决方案
  • 这条look line的logback.groovy版本会是什么?
【解决方案2】:

仅基于配置的解决方案,使用 ThresoldFilter 和 LevelFilters 使事情非常容易理解

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

【讨论】:

  • 有点冗长,但我喜欢这个解决方案,因为它非常简单易读。
  • @Gondy 为什么要冗长?您只能使用ThresoldFilter
  • 为什么不使用ThresoldFilter 到STDOUT,而不是使用五个LevelFilter
  • @Alex78191, @tonarimochi 据我所知,ThresholdFilter 可用于接受或拒绝高于指定级别(WARN)的日志,反之则不行。所以你不能用它来过滤低于WARN的日志。但如果我错了,请随时改进此答案或提交一个新答案。
【解决方案3】:

我相信这是最简单的解决方案:

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

【讨论】:

  • 您想改用ThresholdFilters。
  • 是的,只有当您希望将信息、调试和跟踪记录到标准输出但被忽略时才进行信息级别,对吧?
  • 这吃调试和跟踪?
  • @MartinSchröder 鉴于&lt;filter class="ch.qos.logback.classic.filter.ThresholdFilter"&gt; 的使用,在logback.xml 中指定&lt;root level="INFO"&gt; &lt;appender-ref ref="STDOUT"/&gt; &lt;appender-ref ref="STDERR" /&gt; &lt;/root&gt; 的实际作用是什么?
  • 想通了 - &lt;onMatch&gt;&lt;onMismatch&gt; 没有为 ThresholdFilter 定义。只需删除它们,它就会按预期工作。
【解决方案4】:

更新:有关使用 Groovy 的所有基于配置的方法,请参阅 Dean Hiller's answer

--

您可以使用Logback filters 做一些有趣的事情。以下配置只会将警告和错误消息打印到 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;
        }
    }

}

【讨论】:

【解决方案5】:

无需编程。配置让您的生活更轻松。

以下是将不同级别的日志记录到不同文件的配置

<property name="DEV_HOME" value="./logs" />

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    <layout class="ch.qos.logback.classic.PatternLayout">
        <Pattern>
            %d{yyyy-MM-dd HH:mm:ss} %-5level - %msg%n
        </Pattern>
    </layout>
</appender>

<appender name="FILE-ERROR"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/app-error.log</file>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <Pattern>
            %d{yyyy-MM-dd HH:mm:ss} %-5level - %msg%n
        </Pattern>
    </encoder>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/app-error.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <!--output messages of exact level only -->
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>
<appender name="FILE-INFO"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/app-info.log</file>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <Pattern>
            %d{yyyy-MM-dd HH:mm:ss} %-5level - %msg%n
        </Pattern>
    </encoder>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/app-info.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>


    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>INFO</level>
        <!--output messages of exact level only -->
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>


<appender name="FILE-DEBUG"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/app-debug.log</file>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <Pattern>
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
        </Pattern>
    </encoder>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/app-debug.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>DEBUG</level>
        <!--output messages of exact level only -->
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>

<appender name="FILE-ALL"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/app.log</file>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <Pattern>
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
        </Pattern>
    </encoder>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/app.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
</appender>

<logger name="com.abc.xyz" level="DEBUG" additivity="true">
    <appender-ref ref="FILE-DEBUG" />
    <appender-ref ref="FILE-INFO" />
    <appender-ref ref="FILE-ERROR" />
    <appender-ref ref="FILE-ALL" />
</logger>

<root level="INFO">
    <appender-ref ref="STDOUT" />
</root>

【讨论】:

    【解决方案6】:

    试试这个。您可以只使用内置的ThresholdFilterLevelFilter。无需以编程方式创建自己的过滤器。在此示例中,WARN 和 ERROR 级别记录到 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>
    

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

        最简单的解决方案是在附加程序上使用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 的回答。

        【讨论】:

        • 我正在使用记录器和根。记录器中的附加程序被执行,但根目录中的附加程序没有被调用。
        • Gangadhar,在您的子记录器中设置 additivity="true"(您覆盖了默认值)。
        • 谢谢...重要的是不要忘记 STDERR 附加程序中的 标记!但这也有一个问题:过滤器级别以上的所有输出都被打印...但是对于标准输出,您希望不打印错误级别(及以上)...请参阅我的解决方案,它将其与 S Hébert 的答案相结合...
        【解决方案9】:

        我不相信这个答案,因为它只是上述两个最佳答案的组合:X. Wo Satuk 的答案和 Sébastien Helbert 的答案:ThresholdFilter 很可爱,但您不能将其配置为上层和下层*,但将其与设置为“DENY”的两个 LevelFilters WARNERROR 结合起来效果很好。

        非常重要:不要忘记 STDERR 附加程序中的 &lt;target&gt;System.err&lt;/target&gt; 标签:我的遗漏让我沮丧了几分钟。

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

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

        【讨论】:

        • 这确实是最好的解决方案,结合了ThresholdFilter和LevelFilter!
        • System.err 是干什么用的?
        • 这个巧妙结合现有知识的答案值得称赞。
        【解决方案10】:
        <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
        

        【讨论】:

          【解决方案11】:

          这是我使用的配置,效果很好,它基于 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>  
          

          【讨论】:

            【解决方案12】:

            我使用 logback.groovy 来配置我的 logback,但您也可以使用 xml 配置来配置:

            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 更简单,因为不需要创建过滤器类。
            我为我的英语道歉!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-08-09
              • 1970-01-01
              • 2012-02-14
              • 1970-01-01
              • 1970-01-01
              • 2015-08-13
              • 2013-06-11
              相关资源
              最近更新 更多