【问题标题】:Dump debug logs if exception occured如果发生异常则转储调试日志
【发布时间】:2015-07-07 18:26:42
【问题描述】:

我正在编写一个 java web 应用程序。我正在使用 slf4j & logback 进行日志记录。我使用调试级别来输出一些信息,这些信息可能对查找错误很有用,但通常它没有用而且非常冗长。

我在应用程序中有一个位置可以捕获所有异常并记录它们。我想做的是从请求开始捕获此线程中所有先前的日志记录输出,并将其全部保存在单独的事件文件中。因此,如果发生异常,我将拥有干净的系统执行日志和详细的事件日志。

这个问题有现成的解决方案吗?可能有稍微不同的方法吗?

现在我将所有调试输出保存到存储 7 天的文件中,但在需要时对这个文件进行 grepping 并不是最简单的任务。

【问题讨论】:

    标签: java logging slf4j logback error-logging


    【解决方案1】:

    您可以创建一个自定义 appender 来存储所有日志消息,然后在需要时写入另一个 appender。在请求开始时调用clearLog,如果有错误则调用writeLog

    import java.util.ArrayList;
    import java.util.List;
    
    import ch.qos.logback.core.Appender;
    import ch.qos.logback.core.AppenderBase;
    
    public class SavingAppender<E> extends AppenderBase<E> {
        private final ThreadLocal<List<E>> events = new ThreadLocal<List<E>>() {
            protected List<E> initialValue() {
                return new ArrayList<>();
            }
        };
    
        protected void append(E event) {
            events.get().add(event);
        }
    
        public void clearLog() {
            events.get().clear();
        }
    
        public void writeLog(Appender<E> other) {
            for(E event:events.get()) {
                other.doAppend(event);
            }
        }
    }
    

    将所有日志消息配置到 appender,并为事件日志创建另一个 appender:

    <configuration> 
        <appender name="savingAppender" class="SavingAppender"> 
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <appender name="outputError" class="ch.qos.logback.core.ConsoleAppender">
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> 
                <level>error</level>
            </filter>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <appender name="incidentAppender" class="ch.qos.logback.core.FileAppender">
            <file>output.log</file>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <root level="info">
            <appender-ref ref="savingAppender"/>
            <appender-ref ref="outputError"/>
        </root>
    
        <logger name="incident">
            <appender-ref ref="incidentAppender"/>
        </logger>
    </configuration>
    

    测试类:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import ch.qos.logback.core.Appender;
    
    public class Main {
        public static void main(String[] args) {
            Logger rootLogger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
            Appender<ILoggingEvent> savingAppender = ((ch.qos.logback.classic.Logger)rootLogger).getAppender("savingAppender");
    
            Logger incidentLogger = LoggerFactory.getLogger("incident");
            Appender<ILoggingEvent> incidentAppender = ((ch.qos.logback.classic.Logger)incidentLogger).getAppender("incidentAppender");
    
            ((SavingAppender<ILoggingEvent>)savingAppender).clearLog();
    
            LoggerFactory.getLogger(Main.class).error("Error 1...");
            LoggerFactory.getLogger(Main.class).error("Error 2...");
            LoggerFactory.getLogger(Main.class).error("Error 3...");
            LoggerFactory.getLogger(Main.class).info("Info 1...");
            LoggerFactory.getLogger(Main.class).info("Info 2...");
            LoggerFactory.getLogger(Main.class).info("Info 3...");
    
            ((SavingAppender<ILoggingEvent>)savingAppender).writeLog(incidentAppender);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-03
      • 2014-07-13
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      相关资源
      最近更新 更多