【发布时间】:2010-11-26 14:26:11
【问题描述】:
我正在使用 log4cxx 我的项目,我可以使用 [%t] 标记记录当前线程 ID,如何在其中记录进程 ID 或 log4j?。
我正在使用基于 ConversionPattern 和 xml 的配置文件。
谢谢,
【问题讨论】:
我正在使用 log4cxx 我的项目,我可以使用 [%t] 标记记录当前线程 ID,如何在其中记录进程 ID 或 log4j?。
我正在使用基于 ConversionPattern 和 xml 的配置文件。
谢谢,
【问题讨论】:
基于以上答案,我将在log4j中进行如下操作:
import java.lang.management.*;
import org.apache.log4j.MDC;
private String getPID() {
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
return rt.getName();
}
private void configLog4j() {
// call this from somewhere before you start logging
MDC.put("PID", getPID());
}
然后在我的 log4j.properties 中:
log4j.appender.FILE.layout.ConversionPattern=%d %X{PID} [%t] %p %c{1} %x - %m%n
这实际上会产生一个由 ID 号和主机名组成的 PID,至少在我的 Java 实现中,并且从我读到的内容可能是特定于实现的。你可以更进一步,只拆分 PID。
【讨论】:
这在任何 log4xxx 中都不存在,但你可以自己做一点努力。实际上,如果您不介意一点编码,这是一项非常简单的任务。这基本上是我做过几次的事情——覆盖实际的附加程序,或者它的布局,确保你的类将进程 ID 粘贴到事件属性映射中。然后按名称使用此属性,就好像它是 MDC 属性一样。像上面建议的那样直接使用 MDC 不是最佳选择,因为它们是线程绑定的,您必须确保每个线程在启动时都放置 PID。但是,如果您不能或不想覆盖附加程序或布局,那么这可能是唯一的选择。
【讨论】:
@skiphoppy 的回答非常适用于 Log4j1.x,但我认为可以对其进行更新以显示它在新的 Log4j2 中的工作方式。
(注意:我试图将其作为上述帖子的编辑提交,因为它只是对答案代码的一个小修订,但我将其作为单独的答案发布,因为我的修订是拒绝。)
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import org.apache.logging.log4j.ThreadContext;
private String getPID() {
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
return rt.getName();
}
private void configLog4j() {
// Here is the Log4j2 way
ThreadContext.put("PID", rtmx.getName());
}
正如 skiphoppy 的回答所述,它输出的不仅仅是进程 ID。例如,在我的机器上(Fedora 20):
16237@localhost.localdomain
您可以使用以下代码仅提取进程 ID,并将其放在您的 XML 配置文件中:%replace{%X{PID}}{[A-Za-z@\.]*}{}
鉴于上面的进程ID输出:
16237@localhost.localdomain
正则表达式会产生
16237
【讨论】:
Log4J 中没有实现此目的的功能,但是您可以传入进程 ID 并使用它。
这篇博文展示了一种解决方法:http://blackbeanbag.net/wp/2009/01/14/log-file-management-in-coherence-using-log4j/
基本上,将进程 id 作为系统属性传入,然后在 Log4j 模式中使用它。
显然,这是由于 JVM 没有提供访问进程 ID 的简单方法。从 JDK1.5+ 开始,this 可以工作。 (从死链接http://www.theresearchkitchen.com/archives/100存档)
【讨论】: