c# log4net在某些条件下将条目存储在内存和电子邮件中

发布于 2024-07-30 17:59:16 字数 1644 浏览 3 评论 0 原文

我目前使用 log4net 和 RollingFileAppender。

当进行每个 Log 调用时,我想将其存储在内存中。 在我的控制台应用程序运行结束时,我想(如果 app.config 设置为 true)仅接受警告和致命消息并通过电子邮件发送所有这些消息。 我注意到 MemoryAppender 但不太确定如何使用它。 另请参阅 SMTPAppender,但不确定它是正确的工具,否则我将使用 MemoryAppender 并以某种方式仅过滤掉级别警告/致命的事件,然后使用 SmtpClient 类发送电子邮件。

如何实现这一目标?

谢谢

更新

我的 log4net 配置的最后一部分现在看起来像这样。

<appender name="MemoryAppender" type="log4net.Appender.MemoryAppender" >
    <onlyFixPartialEventData value="true" />
    <threshold value="WARN" />
  </appender>  

  <root>
     <level value="DEBUG" />
    <appender-ref ref="Console" />
    <appender-ref ref="RollingFile" />
    <appender-ref ref="MemoryAppender" />    
  </root>

在代码中我这样做:

private static MemoryAppender MemoryAppender
{
     get
     {
                if (memoryAppender == null)
                {
                    Hierarchy h = LogManager.GetRepository() as Hierarchy;
                    memoryAppender = h.Root.GetAppender("MemoryAppender") as MemoryAppender;
                }
                return memoryAppender;
            }
     }

然后当我想要事件时我调用:

MemoryAppender.GetEvents();

我已经尝试过 MemoryAppender.GetEvents()[0].RenderedMessage 但这不是正确的输出,如何获取以正确的模式和时间等写入文件/控制台日志的消息字符串< /strong> 并为自己构建一个 StringBuilder? 然后我会将其放入电子邮件正文中并使用 SmtpClient 发送。 RenderMessage 只是给我提供给 Log.Warn() 调用的字符串,而不是写入日志的字符串。 这是因为没有在 MemoryAppender 上设置布局模式吗?

谢谢

I currently use log4net with a RollingFileAppender.

As each Log call is made I'd like to store this in memory. At the end of my console application run I'd like to (if an app.config setting is true) take only the Warns and Fatals and send all these messages in an Email. I notice MemoryAppender but not quite sure how to use it. Also see SMTPAppender but not sure it is the right tool, else I'll use MemoryAppender and somehow filter out only events of Levels Warn/Fatal and then email using the SmtpClient class.

How to achieve this?

Thanks

Update

My last part of log4net config now looks like.

<appender name="MemoryAppender" type="log4net.Appender.MemoryAppender" >
    <onlyFixPartialEventData value="true" />
    <threshold value="WARN" />
  </appender>  

  <root>
     <level value="DEBUG" />
    <appender-ref ref="Console" />
    <appender-ref ref="RollingFile" />
    <appender-ref ref="MemoryAppender" />    
  </root>

In code I do:

private static MemoryAppender MemoryAppender
{
     get
     {
                if (memoryAppender == null)
                {
                    Hierarchy h = LogManager.GetRepository() as Hierarchy;
                    memoryAppender = h.Root.GetAppender("MemoryAppender") as MemoryAppender;
                }
                return memoryAppender;
            }
     }

Then when I want the events I call:

MemoryAppender.GetEvents();

I've tried MemoryAppender.GetEvents()[0].RenderedMessage but that is not the correct output, how do I get the message string as it was written to the File/Console logs with the correct pattern and time etc and build myself a StringBuilder? I'll then put this in the body of my Email and send it using the SmtpClient. RenderMessage is just giving me the string that was provided to the Log.Warn() call not what was written to the log. Is this due to not setting a layout pattern on the MemoryAppender?

Thanks

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

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

发布评论

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

评论(2

嗳卜坏 2024-08-06 17:59:16

MemoryAppender 只会“追加”到内存,因此主要仅用于开发和测试目的。 目前还没有仅在应用程序关闭时追加的追加程序。

SMTPAppender 介于两者之间,因为它继承了 BufferingAppenderSkeleton 。 这些附加程序有一个 BufferSize 属性,该属性控制在刷新之前在内存中保留多少消息。

哪些消息传递到附加程序由根元素或各个记录器元素上的级别设置控制。 在您的情况下,使用 WARN 级别,该级别将允许 WARN、ERROR 和 FATAL。 如果您不想要错误消息,则必须在附加程序上放置一个级别过滤器。

更新: MemoryAppender 没有使用任何布局来“渲染”消息对象。 您从 MemoryAppender 获得的只是由 log4net 生成的原始消息对象。 您必须自己将它们转换为有意义的文本。

或者,如果您需要布局功能和内存附加,您可以查看子类 Appender骨架。 这样您就可以获得基本的布局支持。 实现 Append 方法时,您可以执行 MemoryAppender 所做的操作,即附加到内部消息列表。

更新2:要实现MemoryAppender替代方案,我建议采用MemoryAppender 作为起点。 MemoryAppender 是 AppenderSkeleton 的子类,因此可以访问 RenderLoggingEvent 方法。 因此,我们子类化 MemoryAppender 并添加一个呈现当前批次日志记录事件的方法:

public class RenderingMemoryAppender : MemoryAppender
{

    public IEnumerable<string> GetRenderedEvents()
    {
        foreach(var loggingEvent in GetEvents())
        {
            yield return RenderLoggingEvent(loggingEvent);
        }
    }
}

MemoryAppender will only "append" to memory and is thus mostly useful only for development and testing purposes. And there is currently no appender that will only append on application shutdown.

The SMTPAppender is something in between, since it inherits the BufferingAppenderSkeleton. These appenders have a BufferSize property which controls how many messages are kept in memory before they are flushed.

Which messages to pass to the appenders are controlled with the level settings either on the root element or on individual logger elements. In your case use a level of WARN which will let through WARN, ERROR and FATAL. If you don't want the ERROR messages you will have to put a level filter on your appender.

Update: MemoryAppender is not using any layout to "render" message objects. What you get from MemoryAppender is just the raw message objects as they are produced by log4net. You will have to convert those to meaningfull text yourself.

Alternatively, if you require both layout functionality and in-memory appending you could look into subclassing AppenderSkeleton. That way you get the basic Layout support. When implementing the Append method you can do what MemoryAppender does, that is just appending to an internal list of messages.

Update 2: to implement the MemoryAppender alternative I suggest taking the MemoryAppender as a starting point. MemoryAppender is a subclass of AppenderSkeleton and have thus access to the RenderLoggingEvent method. So, we subclass MemoryAppender and add a method that renders the current batch of logging events:

public class RenderingMemoryAppender : MemoryAppender
{

    public IEnumerable<string> GetRenderedEvents()
    {
        foreach(var loggingEvent in GetEvents())
        {
            yield return RenderLoggingEvent(loggingEvent);
        }
    }
}
神爱温柔 2024-08-06 17:59:16

您可以使用 SMTPAppender 并查看刷新功能的工作原理。 Log4net 将所有消息保留在内存中,直到调用刷新(如果以这种方式设置),因此当您刷新它时,电子邮件将被发送。

您可以做的另一件事是创建一个带有过滤器 WARN 和 FATAL 的单独附加程序(Rolling 或 FileAppender),然后将此附加程序附加到同一个记录器,并在运行结束时通过电子邮件发送此文件(如果它非空)(并且您可以选择以附件形式发送或直接在电子邮件正文中发送)。 如果您想要更多详细信息,请告诉我,这几乎与我所知道的相同。

祝你好运!

里卡多.

You can use SMTPAppender and look at how the flush functionality works. Log4net keeps all messages in memory until flush is called (if it's setup this way), so the email will be sent when you flush it.

Another thing you can do is create a separate appender (Rolling or FileAppender) with filters WARN and FATAL, then attach this appender to the same logger, and at the end of your run email this file if it's non-empty (and you can choose to send it as an attachment or right in the body of the email). Let me know if you want more details, this is almost the same I'm doing know.

Good luck!

Ricardo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文