10

我正在使用 log4cxx 我的项目,我可以使用 [%t] 标记记录当前线程 ID,如何在其中记录进程 ID 或 log4j?

我正在使用基于 ConversionPattern 和 xml 的配置文件。

谢谢,

4

5 回答 5

13

基于上述答案,我将在 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。

于 2012-08-30T17:16:17.880 回答
6

我已经浏览了 log4j 和 log4cxx 的文档,但我在任何地方都没有找到有关记录进程 ID 的任何信息。

因此,简而言之:不,您不能记录进程 ID,至少不能直接记录。

由于您使用的是 C++,因此您可以获得程序的 PID。是在 Linux 中的操作方法(此链接中的 Ubuntu)。以下是如何在 Windows 中执行此操作。

在您的程序开始时获取该 PID,使用MDC并将您的 PID 放入其中。

我不认为有更好的方法。

在 log4j 中执行此操作会更加棘手,因为我不知道正在运行的程序无法使用标准 Java 类获取它的 PID。

于 2010-11-26T15:34:23.480 回答
2

这在任何 log4xxx 中都不存在,但只需稍加努力,您就可以自己制作。实际上,如果您不介意一点编码,这是一项非常简单的任务。这基本上是我做过几次的事情——覆盖实际的附加程序,或者它的布局,确保你的类将进程 ID 粘贴到事件属性映射中。然后按名称使用此属性,就好像它是 MDC 属性一样。像上面建议的那样直接使用 MDC 不是最佳选择,因为它们是线程绑定的,您必须确保每个线程在启动时都放置 PID。但是,如果您不能或不想覆盖附加程序或布局,那么这可能是唯一的选择。

于 2012-08-31T15:08:47.233 回答
2

@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

于 2014-08-17T02:24:17.033 回答
2
于 2011-06-27T17:23:38.267 回答