【问题标题】:How to log Process id using Log4cxx or log4j如何使用 Log4cxx 或 log4j 记录进程 ID
【发布时间】:2010-11-26 14:26:11
【问题描述】:

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

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

谢谢,

【问题讨论】:

    标签: log4j log4cxx


    【解决方案1】:

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

    【讨论】:

    • @rogerdpack,很高兴我的回答对您有所帮助!
    • 如果不为 log4j 编写代码,这将无法开箱即用
    【解决方案2】:

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

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

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

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

    我认为没有更好的方法。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        @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

        【讨论】:

        • + 1 表示 %replace{%X{PID}}
        【解决方案5】:

        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存档)

        【讨论】:

          猜你喜欢
          • 2016-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-07
          • 2014-04-16
          • 1970-01-01
          相关资源
          最近更新 更多