log4net进程id信息

发布于 2024-08-18 05:29:15 字数 1283 浏览 4 评论 0原文

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

因为我需要知道日志消息来自哪台机器和哪个进程,所以我也想将其包含在日志中。我发现 %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 中获得相同的?这是我的测试布局:

    <布局类型=“log4net.Layout.PatternLayout”>
        />
    
    
  3. 最后,对 UDP 附加程序使用 XML 布局是有意义的。看起来 XmlLayoutSchemaLog4j 已经将 HostNameProperty 添加到 XML 消息中。如果我不想将这个新的进程 ID(也可能是进程名称)添加到 XML 消息中,那么最好的方法是什么?我是否应该复制 src\Layouts\XmlLayoutSchemaLog4j.cs,修改它,并让 log4net 知道我创建了这个新布局(如 SampleLayoutsApp)?

感谢您的帮助

I am trying to create a logging solution that involves multiple processes on multiple machines. I planned on using the UDPAppender to send all log messages to a single machine that would manage them. I have a few questions about patternstrings vs patternlayouts.

Because I need to know both which machine and which process that log message came from, I want to include that in the log as well. I found %property{log4net:HostName} for hostname, and that works great. However, I don't see anything for process id in PatternLayouts. I do, of course, see something like that in the PatternString. From the FAQ:

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

But I am not sure if or how to mix and match the two (or even if this is the canonical way to do so).

So, my questions are:

  1. What is the difference between PatternString and PatternLayout? Why have both?

  2. I see the %processid in PatternString, how do I get the same in PatternLayout? Here is my test layout:

    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] [%property{log4net:HostName}] %-5level %logger  - %message%newline" />
    </layout>
    
  3. Finally, it makes sense to use the XML layout for the UDP appender. It looks like the XmlLayoutSchemaLog4j already adds the HostNameProperty to the XML message. If I wan't to add this new Process ID (and maybe Process Name) to the XML message, what is the best way to do this? Should I just copy src\Layouts\XmlLayoutSchemaLog4j.cs, modify it, and let log4net know that I created this new Layout (like the SampleLayoutsApp)?

Thanks for your help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

﹏半生如梦愿梦如真 2024-08-25 05:29:16

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

操作方法如下:

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

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 布局,因为它非常重,如果频繁使用,可能会降低应用程序的性能。

Apparently PatternString can only be used to create log names (i.e. filenames etc.) whereas layout lets you format the actual message that gets into the log. If there is no built-in pattern for process id in the process layout, then you can easily add it. It is much simpler than creating the whole layout.

Here is how to do it:

Create your own custom pattern converter (example below tries to get the name of the application no matter win or web):

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);
    }
}

Add the entry for your converter to the registry of PatternLayout class

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

Now you can use %ApplicationName in the PatternLayout value to get what you need.

I'd advise not to use the XmlLayoutSchemaLog4j layout as it is very heavy and can drop performance of your app if used frequently.

羁绊已千年 2024-08-25 05:29:15

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

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

然后,您使用常规模式从附加程序引用此属性,如下所示:

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

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

You can add any properties you want to the GlobalContext. I use this context to store the process id, like this:

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

Then you reference this property from your appender using a regular pattern, like this:

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

You can add as many properties as you want, but because of it's global nature, it works best for properties that don't change during your application's execution.

懷念過去 2024-08-25 05:29:15

您可以将 PatternString 馈送到 PatternLayout 中:

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

You can feed a PatternString into a PatternLayout:

    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern type="log4net.Util.PatternString" value="%processid" />
    </layout>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文