【问题标题】:How do I not log a particular type of Exception in Logback?如何不在 Logback 中记录特定类型的异常?
【发布时间】:2011-09-02 21:20:46
【问题描述】:

如何配置 Logback 以忽略特定类型异常的日志记录?

【问题讨论】:

    标签: exception logging configuration logback


    【解决方案1】:

    你可以用一个简单的EvaluatorFilter

    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>java.lang.RuntimeException.class.isInstance(throwable)</expression>
        </evaluator>
        <onMatch>DENY</onMatch>
    </filter>
    

    请注意,您的pom.xml 中还需要以下依赖项:

    <dependency>
        <groupId>org.codehaus.janino</groupId>
        <artifactId>janino</artifactId>
        <version>2.5.16</version>
    </dependency>
    

    另一种可能的解决方案是自定义Filter 实现:

    import ch.qos.logback.classic.spi.ILoggingEvent;
    import ch.qos.logback.classic.spi.IThrowableProxy;
    import ch.qos.logback.classic.spi.ThrowableProxy;
    import ch.qos.logback.core.filter.Filter;
    import ch.qos.logback.core.spi.FilterReply;
    
    public class SampleFilter extends Filter<ILoggingEvent> {
    
        private Class<?> exceptionClass;
    
        public SampleFilter() {
        }
    
        @Override
        public FilterReply decide(final ILoggingEvent event) {
            final IThrowableProxy throwableProxy = event.getThrowableProxy();
            if (throwableProxy == null) {
                return FilterReply.NEUTRAL;
            }
    
            if (!(throwableProxy instanceof ThrowableProxy)) {
                return FilterReply.NEUTRAL;
            }
    
            final ThrowableProxy throwableProxyImpl = 
                (ThrowableProxy) throwableProxy;
            final Throwable throwable = throwableProxyImpl.getThrowable();
            if (exceptionClass.isInstance(throwable)) {
                return FilterReply.DENY;
            }
    
            return FilterReply.NEUTRAL;
        }
    
        public void setExceptionClassName(final String exceptionClassName) {
            try {
                exceptionClass = Class.forName(exceptionClassName);
            } catch (final ClassNotFoundException e) {
                throw new IllegalArgumentException("Class is unavailable: "
                        + exceptionClassName, e);
            }
        }
    }
    

    使用适当的配置:

    <filter class="hu.palacsint.logbacktest.SampleFilter">
        <exceptionClassName>java.lang.Exception</exceptionClassName>
    </filter>
    

    TurboFilteryou get the thrown Throwable instance directly 中,因此您可以调用isInstance 方法,而无需手动将IThrowableProxy 强制转换为ThrowableProxy

    Further documentation

    【讨论】:

    • 谢谢,我已经解决了这个特定问题,但这是未来的好信息。
    【解决方案2】:

    这个问题已有 5 年历史了,但我提供的解决方案只是为了使其保持最新状态。

    我在官方文档中找到了解决方案: http://logback.qos.ch/manual/layouts.html

    对于我的特殊情况,这是一个运行普通旧 servlet 的 17 年网站(啊,那些日子),如果用户没有登录,servlet 现在会抛出异常。所以这是我的代码 sn-ps:

    Servlet

      try {
        InvalidLoginException.throwIfBadLogin(webUser);
    
        // main logic here
    
      } catch (InvalidLoginException e) {
        throw e;
      } catch (Throwable t) {
        log.error(t);
        throw new UnhandledException(t);
      }
    

    web.xml

    <error-page>
        <exception-type>com.mycompany.servlet.exception.InvalidLoginException</exception-type>
        <location>/servlet/Login</location>
    </error-page>
    

    根据上面的设置,我不想记录此异常,因为它真的不是异常,而是重定向到登录的逻辑中断。

    所以,我的 logback.xml 文件的开头是这样的:

      <configuration packagingData="true" scan="true" debug="true" scanPeriod="30 seconds">
        <evaluator name="InvalidLoginExceptionSuppressor">
          <expression>throwable != null &amp;&amp; throwable instanceof com.mycompany.servlet.exception.InvalidLoginException</expression>
        </evaluator>
    

    在 logback.xml 文件的更下方,我的附加程序:

      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>%d{MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg %ex{full,InvalidLoginExceptionSuppressor}%n</pattern>
          <immediateFlush>false</immediateFlush>
        </encoder>
    

    另外请注意,为了完成这项工作,我必须包含 janino 来处理表达式解析。

    【讨论】:

      【解决方案3】:

      这是@palacsint 响应的另一个示例,当错误不是异常时使用JaninoEventEvaluator

      <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
          <expression>logger.equals("org.docx4j.fonts.GlyphCheck") &amp;&amp; level == ERROR</expression>
        </evaluator>
        <onMatch>DENY</onMatch>
      </filter>
      

      【讨论】:

      • 如果它是您忽略的记录器,您可以禁用该记录器
      猜你喜欢
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多