log4net进程ID信息

问题描述:

我正在尝试创建一个日志解决方案,涉及多个机器上的多个进程。我计划使用UDPAppender将所有日志消息发送到可管理它们的单台机器。我有几个有关patterntrings与patternlayouts的问题。log4net进程ID信息

因为我需要知道哪台机器和哪个进程的日志信息来自哪里,所以我想将它包含在日志中。我发现%property {log4net:HostName}用于主机名,并且工作得很好。但是,我没有在PatternLayouts中看到任何进程ID。当然,我在PatternString中看到类似的东西。从常见问题:

<appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 
    <file type="log4net.Util.PatternString" value="log-file-[%processid].txt" /> 

    <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" /> 
</appender> 

但我不知道是否或如何混搭两个(或者即使这是规范的方法来做到这一点)。

所以,我的问题是:

  1. 是什么PatternString和的PatternLayout之间的区别?为什么都有?

  2. 我在PatternString中看到%processid,我怎么在PatternLayout中得到相同的结果?这里是我的测试布局:

    <layout type="log4net.Layout.PatternLayout"> 
        <conversionPattern value="%date [%thread] [%property{log4net:HostName}] %-5level %logger - %message%newline" /> 
    </layout> 
    
  3. 最后,是有意义的使用XML布局为UDP附加目的地。它看起来像XmlLayoutSchemaLog4j已经将HostNameProperty添加到XML消息。如果我不想将这个新的进程ID(也可能是进程名称)添加到XML消息中,那么执行此操作的最佳方法是什么?我应该只复制src \ Layouts \ XmlLayoutSchemaLog4j.cs,修改它,让log4net知道我创建了这个新的布局(如SampleLayoutsApp)?

感谢您的帮助

您可以将所需的任何属性添加到GlobalContext中。我用这个背景下存储进程ID,像这样:

log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id; 

然后你从你的appender使用的是常规模式引用此属性,像这样:

<layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%date %property{pid} %level %logger - %message%newline" /> 
</layout> 

您可以添加尽可能多的属性你想要的,但是由于它是全局性的,它对于在应用程序执行期间不会改变的属性来说效果最好。

+0

尝试一切%PID,%进程ID和更多的人,毫无效果。你的解决方案有效谢谢。 – Nemo 2015-06-18 20:45:54

显然PatternString只能用于创建日志名称(即文件名等),而布局可以让你格式化实际的消息进入日志。如果在流程布局中没有内置的进程ID模式,那么您可以轻松添加它。这比创建整个布局要简单得多。

这里是如何做到这一点:

创建自己的自定义模式转换器(下面的例子试图获取应用程序的名称,不管赢或网络):

internal sealed class ApplicationNamePatternConverter : PatternLayoutConverter 
{ 
    /// <summary> 
    /// Write the event application name to the output 
    override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) 
    { 
     string name = string.Empty; 
     if(System.Web.HttpContext.Current != null) 
     { 
      string[] applicationPath = System.Web.HttpContext.Current.Request.ApplicationPath.Split('/'); 
      name = applicationPath[applicationPath.Length - 1]; 
     } 
     else 
     { 
      if(System.Reflection.Assembly.GetEntryAssembly() != null) 
      { 
       name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name; 
      } 
     } 
     writer.Write(name); 
    } 
} 

添加条目您转换器的PatternLayout类

static PatternLayout() 
{ 
... 
    s_globalRulesRegistry.Add("ApplicationName", typeof(ApplicationNamePatternConverter)); 
} 

的注册表现在你可以使用%ApplicationName中的PatternLayout价值得到你所需要的。

我建议不要使用XmlLayoutSchemaLog4j布局,因为它非常沉重,如果经常使用,可能会降低应用程序的性能。

可以养活一个PatternString成的PatternLayout:

<layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern type="log4net.Util.PatternString" value="%processid" /> 
    </layout> 
+0

这实际上工作。谢谢。 – 2010-11-18 22:37:25

+3

记住要逃避要从事件中提取的属性的百分比字符,例如将进程ID包含为日志文件之一列 – Pelle 2012-07-24 07:12:31