Java Logging: log everything> debug, but only when an error occurs

Debug logs are logged during request processing. At some point, an error may occur when a problem occurs. Idea: when no errors occur during the processing of the entire request, I would like to ignore all debugs, BUT if an error occurs, I would like to see all previous and successful debugs in the logs.

Is there any out-of-the-box solution for this (in log4j, logback, or whatever), or should I implement some sort of wrapper for my Logger that will "cache" debugs to the thread until needed

+3


source to share


3 answers


It is not a built-in solution, but here it implements a project that can be minimal and easy to integrate. It uses log4j2 and you don't need to change the client code if you are already using log4j2 or slf4j.

So the relevant test case is

  @Test
  public void no_error_so_no_log() throws Exception {
    LogEventCollector.clean();
    try {
      log.debug("hello world");
      log.debug("some debug again");
    } finally {
      LogEventCollector.clean();
    }
  }

  @Test
  public void error_so_log_from_the_beginning() throws Exception {
    LogEventCollector.clean();
    try {
      log.debug("hello world");
      log.error("some error", new RuntimeException("whatever"));
      log.debug("some debug again");
    } finally {
      LogEventCollector.clean();
    }
  }

      

LogEventCollector

will take care of initializing and clearing the request flow of the web application. It can be put into a servlet Filter

.

I created my custom Appender. The core of the application is the following:



    @Override
    public void append(LogEvent event) {
      if (Level.ERROR.isLessSpecificThan(event.getLevel()))
        LogEventCollector.markError();
      if (!LogEventCollector.hadError()) {
        LogEventCollector.collect(event);
        return;
      }
      for (LogEvent collected : LogEventCollector.events())
        push_log_out(collected);
      //and the current one
      push_log_out(event);
    }

      

The method push_log_event

is a real log. It can be your custom implementation or another delegate (like AsyncAppender).

myself LogEventCollector

:

  public class LogEventCollector {
    static ThreadLocal<Context> LOG_COLLECTOR = new ThreadLocal<Context>() {
      @Override
      protected Context initialValue() {
        return new Context();
      }
    };

    public static void clean() {
      LOG_COLLECTOR.get().clean();
    }

    static class Context {
      boolean had_error = false;
      List<LogEvent> events = new ArrayList<LogEvent>();

      public void clean() {
        had_error = false;
        events = new ArrayList<LogEvent>();
      }
    }

    public static void markError() {
      LOG_COLLECTOR.get().had_error = true;
    }

    public static boolean hadError() {
      return LOG_COLLECTOR.get().had_error;
    }

    public static void collect(LogEvent event) {
      LOG_COLLECTOR.get().events.add(event);
    }

    public static List<LogEvent> events() {
      List<LogEvent> ret = LOG_COLLECTOR.get().events;
      LOG_COLLECTOR.get().events = new ArrayList<LogEvent>();
      return ret;
    }

  }

      

I think this should be enough to customize to your needs.

+2


source


I believe what you are asking is documented at https://issues.apache.org/jira/browse/LOG4J2-1137 .



+1


source


I don't know of a single system that would work this way. To write unlimited logs, you will need enough memory to write it (which could potentially take too long or even run out of disk space later). Every logging system I've come across determines whether a log message should be written at the time of logging a log message rather than later.

However, you could include appropriate (potentially unique to the request) debug tokens and then search or filter the log file after the fact to find debug messages related to the error. Or you will need to create your own data structure to contain data that can potentially be written later and write it when you run into an error and discard it when you reach some boundary that you as an application writer know that it will never be needed.

0


source







All Articles