如果发生异常,则转储调试日志
Dump debug logs if exception occured
我正在编写 java 网络应用程序。我正在使用 slf4j 和 logback 进行日志记录。我使用调试级别输出一些可能对查找错误有用的信息,但通常它没有用,而且非常冗长。
我在应用程序中有一个地方可以捕获所有异常并记录它们。我想做的是从请求开始捕获该线程中所有以前的日志记录输出,并将其全部保存在单独的事件文件中。因此,如果发生异常,我将拥有干净的系统运行日志和详细的事件日志。
这个问题有现成的解决方案吗?方法可能略有不同?
现在我正在将所有调试输出保存到文件中并保存 7 天,但是在需要时获取此文件并不是最简单的任务。
您可以创建一个自定义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);
}
}
}
将所有日志消息配置到附加程序,并为事件日志创建另一个附加程序:
<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>
测试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);
}
}
我正在编写 java 网络应用程序。我正在使用 slf4j 和 logback 进行日志记录。我使用调试级别输出一些可能对查找错误有用的信息,但通常它没有用,而且非常冗长。
我在应用程序中有一个地方可以捕获所有异常并记录它们。我想做的是从请求开始捕获该线程中所有以前的日志记录输出,并将其全部保存在单独的事件文件中。因此,如果发生异常,我将拥有干净的系统运行日志和详细的事件日志。
这个问题有现成的解决方案吗?方法可能略有不同?
现在我正在将所有调试输出保存到文件中并保存 7 天,但是在需要时获取此文件并不是最简单的任务。
您可以创建一个自定义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);
}
}
}
将所有日志消息配置到附加程序,并为事件日志创建另一个附加程序:
<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>
测试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);
}
}