5

我有一个 Java 分层应用程序,它有一个从不同点调用的多线程数据访问层。对该层的一次调用可能会产生多个线程来并行处理对 DB 的请求。

我正在寻找的是一个日志工具,它允许我定义由各种线程组成的“活动”。因此,数据访问层中的相同方法应根据其调用者记录不同的输出。对不同输出进行分组以总结操作总成本的能力也很重要。

虽然应用程序是 Java 语言,但语言不是限制;我需要的是设计指南,以便最终实现它。我们目前正在使用 log4j,但无法从中获得这种行为。

4

8 回答 8

5

您还应该看看 log4j 的嵌套诊断上下文功能。为不同的调用者将不同的上下文推送到记录器可能对你有用。

于 2008-09-17T13:36:27.197 回答
5

您应该能够传递一个记录器,因此您基于任务数据的一些“通用”创建一个记录器 - 即用户名等。然后,将此记录器作为参数传递给您需要的所有方法。这样,您就可以在 log4j 配置文件中设置不同的过滤器和/或规则。或者根据记录器名称抓取输出文件。

编辑:还要检查 log4j 中的 MDC 和 NDC 类。您可以在那里添加上下文数据。

于 2008-09-17T13:39:05.333 回答
3

在 log4j 中,您可以使用“%t”模式记录线程名称。请参阅log4j 模式布局

于 2008-09-17T13:33:52.023 回答
3

在我的一个(网络)应用程序中,我使用了一个 ThreadLocal 记录器,它将记录信息捕获到一个 StringBuilder 中。logger 对象在 HttpServlet#service 方法中初始化,如果设置了 trace 参数(如果没有设置,则有一个非常快的 null-logger)。结果输出要么作为 HTML 注释转储到请求页面中,要么写入一个段中的日志文件。

于 2008-09-17T18:00:19.917 回答
0

在 Java5(及更高版本)中,您可以调用

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

检查堆栈跟踪到您想要的任何深度并相应地记录。

在 Java 1.4 中,您可以获得相同的信息

StackTraceElement[] stackTrace = new Exception().getStackTrace();
于 2008-09-17T13:33:59.743 回答
0

您想将记录器对象与我认为的线程相关联。为每个线程保存一个 log4j 记录器实例的 ThreadLocal 变量可能会有所帮助:

http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html

于 2008-09-17T13:34:26.187 回答
0

您需要将一些结构传递给标识当前“活动”的数据访问层。您可能已经有一个有意义的“活动”类,您可以使用Sunny 建议的 Logger 实例,或者您可以使用第三种结构来跟踪活动上下文。

无论如何,由于您的“活动”是跨多个线程处理的,因此您不能使用线程本地存储来跟踪当前的“活动”,就像大多数其他当前答案所暗示的那样。您将需要明确地传递它。

我建议在 log4j 之上制作一个小外观,使用以下方法扩展接口

void debug(Activity activity, String message);

并将活动上下文从数据访问层传递给它。

您需要对数据访问层进行一些修改以允许您将当前活动传递给它,但如何最好地做到这一点很大程度上取决于当前接口。如果您使用 Workspace 模式,您可能只需要在 Workspace-class 上添加一个 setActivity() 方法,但其他接口模式可能需要您向所有方法添加一个 Activity 参数。

如果您由于某种原因无法或不愿意更改数据访问层,您当然可以在调用数据访问层之前将活动上下文存储在线程本地存储中,并在生成子线程或排队之前检索它数据访问层的工作。这是一个可行的解决方案,但是以这种方式传递信息是否有点危险。

于 2008-09-17T13:58:31.433 回答
0

您可以在您的场景中使用MDC 或 NDC , NDC 的工作原理是堆栈,而 MDC 工作在 Map 上,这里是两者的官方文档

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html

于 2021-10-21T19:04:12.563 回答