log4j 记录多线程应用程序中的活动

ki0zmccv  于 2022-11-06  发布在  其他
关注(0)|答案(8)|浏览(143)

我有一个分层的Java应用程序,它有一个多线程数据访问层,从不同的点调用。对这个层的一个调用可能会产生几个线程,以并行化对数据库的请求。
我正在寻找的是一个日志记录工具,它允许我定义由不同线程组成的“活动”。因此,数据访问层中的同一个方法应该根据其调用者记录不同的输出。将不同的输出分组以汇总操作的总成本的能力也很重要。
虽然应用程序是Java的,但语言不是限制;我需要的是设计指南,以便最终实现它。我们目前正在使用log4j,但不能从它得到这种行为。

v440hwme

v440hwme1#

您还应该了解一下log4j的nested diagnostic context特性,为不同的调用者将不同的上下文推送到记录器可能会对您有用。

vqlkdk9b

vqlkdk9b2#

你应该能够传递一个记录器,所以你可以根据一些“公共”的任务数据创建一个记录器--比如用户名等等。然后,把这个记录器作为参数传递给你需要的所有方法。这样,你就可以在log4j配置文件中设置不同的过滤器和/或规则。或者根据记录器的名字来抓取输出文件。
编辑:同时检查log4j中的MDC和NDC类。您可以在那里添加上下文数据。

klh5stk1

klh5stk13#

在log4j中,你可以用“%t”模式记录线程名称。请参见log4j Pattern Layout

tpxzln5u

tpxzln5u4#

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

nwsw7zdq

nwsw7zdq5#

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

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

检查堆栈跟踪到所需的任何深度,并相应地记录。
在Java 1.4中,您可以使用以下命令获得相同的信息

StackTraceElement[] stackTrace = new Exception().getStackTrace();
7ajki6be

7ajki6be6#

我想你想把logger对象和线程关联起来。一个ThreadLocal变量为每个线程保存一个log4j logger示例可能会有帮助:
http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html

gorkyyrv

gorkyyrv7#

您需要将一些结构传递给数据访问层,以标识当前的“活动”。您可能已经有了一个有意义的“Activity”类,您可能像Sunny建议的那样使用Logger示例,或者您可能使用第三种结构来跟踪活动上下文。
在任何情况下,由于“活动”是在多个线程中处理的,所以不能像大多数其他当前答案所建议的那样,使用线程本地存储来跟踪当前的“活动”,您需要显式地传递它。
我建议在log4j上做一个小的外观,用如下方法扩展接口:

void debug(Activity activity, String message);

并将活动上下文从数据访问层传递到该层。
您需要对数据访问层进行一些修改,以允许您将当前活动传递给它,但如何最好地完成这一点在很大程度上取决于当前的接口。如果您使用Workspace-pattern,您可能只需要在Workspace-class上添加一个setActivity()方法,但其他接口模式可能需要您向所有方法添加一个Activity参数。
如果由于某种原因您不能或不愿意更改数据访问层,您当然可以在调用数据访问层之前将活动上下文存储在线程本地存储中,并在生成子线程或在数据访问层中对作业进行排队之前检索它。这是一个可行的解决方案,但以这种方式传递信息有点危险。

b09cbbtk

b09cbbtk8#

您可以针对您的方案使用MDC或NDCNDC基于堆栈原理工作,而MDC基于Map工作,以下是两者的官方文档
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.htmlhttp://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html显示器

相关问题