gpt4 book ai didi

Java 日志记录 : log everything >debug but only when an error occured

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:42:35 24 4
gpt4 key购买 nike

在请求处理期间,记录了一堆调试日志。如果出现问题,有时可能会记录错误。想法:当整个请求处理过程中没有错误发生时,我想忽略所有调试,但如果发生错误,我想在日志中看到所有之前和之后的调试。

是否有任何开箱即用的解决方案(在 log4j、logback 或任何其他程序中),或者我必须为我的 Logger 实现某种包装器,它将“缓存”每个线程的调试,直到需要它们为止?

最佳答案

它不是一个内置的解决方案,但它是我的草稿实现,它可以是非常小的并且易于集成。它使用 log4j2,如果您已经在使用 log4j2 或 slf4j,则无需更改客户端代码。

于是对应的测试用例

  @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 将负责对您的 Web 应用程序请求线程进行初始化和清理。它可以放入 servlet Filter 中。

我已经创建了我的自定义 Appender。 appender 的核心如下:

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

方法push_log_event 才是真正的日志记录。它可以是您的自定义实现或委托(delegate)给另一个实现(如 AsyncAppender)。

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

}

我觉得根据自己的需求定制一定够了。

关于Java 日志记录 : log everything >debug but only when an error occured,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31454904/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com