log4net进程id信息

log4net进程id信息,log4net,Log4net,我正在尝试创建一个日志解决方案,它涉及多台机器上的多个进程。我计划使用UDPAppender将所有日志消息发送到一台管理它们的机器。我有一些关于模式字符串和模式布局的问题 因为我需要知道日志消息来自哪台机器和哪个进程,所以我也想将其包括在日志中。我找到了%property{log4net:HostName}作为主机名,效果很好。但是,我在PatternLayouts中没有看到任何进程id。当然,我确实在图案串中看到了类似的东西。从常见问题解答: <appender name="LogFil

我正在尝试创建一个日志解决方案,它涉及多台机器上的多个进程。我计划使用UDPAppender将所有日志消息发送到一台管理它们的机器。我有一些关于模式字符串和模式布局的问题

因为我需要知道日志消息来自哪台机器和哪个进程,所以我也想将其包括在日志中。我找到了%property{log4net:HostName}作为主机名,效果很好。但是,我在PatternLayouts中没有看到任何进程id。当然,我确实在图案串中看到了类似的东西。从常见问题解答:

<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>

但我不确定是否或如何混合和匹配这两者(或者即使这是实现这一点的标准方法)

因此,我的问题是:

  • PatternString和PatternLayout之间有什么区别?为什么两者都有

  • 我在PatternString中看到%processid,如何在PatternLayout中获得相同的值?以下是我的测试布局:

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


  • 感谢您的帮助

    显然,模式字符串只能用于创建日志名(即文件名等),而布局允许您格式化进入日志的实际消息。如果流程布局中没有流程id的内置模式,那么您可以轻松地添加它。它比创建整个布局简单得多

    以下是如何做到这一点:

    创建您自己的自定义模式转换器(下面的示例尝试获取应用程序的名称,无论是win还是web):

    内部密封类ApplicationNamePatternConverter:PatternLayoutConverter
    {
    /// 
    ///将事件应用程序名称写入输出
    覆盖受保护的无效转换(TextWriter编写器、LoggingEvent LoggingEvent)
    {
    string name=string.Empty;
    if(System.Web.HttpContext.Current!=null)
    {
    字符串[]applicationPath=System.Web.HttpContext.Current.Request.applicationPath.Split('/');
    name=applicationPath[applicationPath.Length-1];
    }
    其他的
    {
    if(System.Reflection.Assembly.GetEntryAssembly()!=null)
    {
    name=System.Reflection.Assembly.GetEntryAssembly().GetName().name;
    }
    }
    作者:写(姓名);
    }
    }
    
    将转换器的项添加到PatternLayout类的注册表中

    静态模式布局()
    {
    ...
    s_globalRulesRegistry.Add(“ApplicationName”,typeof(ApplicationNamePatternConverter));
    }
    
    现在,您可以在PatternLayout值中使用
    %ApplicationName
    ,以获取所需内容


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

    您可以向GlobalContext添加任何想要的属性。我使用此上下文存储进程id,如下所示:

    log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id;
    
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %property{pid} %level %logger - %message%newline" />
    </layout>
    
    然后使用常规模式从appender引用此属性,如下所示:

    log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id;
    
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %property{pid} %level %logger - %message%newline" />
    </layout>
    
    
    

    您可以添加任意数量的属性,但由于其全局性质,它最适合于在应用程序执行期间不会更改的属性。

    您可以将PatternString馈送到PatternLayout中:

        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern type="log4net.Util.PatternString" value="%processid" />
        </layout>
    
    
    
    记住要从事件中提取的属性的百分比字符要转义,例如,要将进程id作为日志文件列之一,则此答案应标记为正确答案尝试了所有内容%pid、%processid以及更多内容,但均无效。你的解决方案有效。谢谢