Write debug logs if an exception occurs

I am writing a Java application. I am using slf4j and logback for logging. I use the debug layer to display some information that may be useful for finding an error, but in general it is not useful and quite verbose.

I have a place in my application to catch all exceptions and log them. What I would like to do is grab ALL of the previous log output in this stream from the beginning of the request and save it all in a separate incident file. That way, I would have clean logs to keep the system running without errors and a detailed log of incidents if an exception occurred.

Are there out-of-the-box solutions for this problem? Maybe there is a slightly different approach?

At the moment I am saving all debug output to a file that is kept for 7 days, but grepping this file is not the easiest task when needed.

+3


source to share


1 answer


You can create a custom appender to store all log messages and then write to another application if needed. Call clearLog

at the beginning of the request and writeLog

if there is an error.

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);
        }
    }
}

      

Configure all log messages to navigate to the app and create another incident log app:



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

      

Test class:

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);
    }
}

      

+2


source







All Articles