我正在使用 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。
我已经浏览了 log4j 和 log4cxx 的文档,但我在任何地方都没有找到有关记录进程 ID 的任何信息。
因此,简而言之:不,您不能记录进程 ID,至少不能直接记录。
由于您使用的是 C++,因此您可以获得程序的 PID。这是在 Linux 中的操作方法(此链接中的 Ubuntu)。以下是如何在 Windows 中执行此操作。
在您的程序开始时获取该 PID,使用MDC并将您的 PID 放入其中。
我不认为有更好的方法。
在 log4j 中执行此操作会更加棘手,因为我不知道正在运行的程序无法使用标准 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