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

时间:2009-08-07 16:09:32

标签: c# log4net

我目前使用带有RollingFileAppender的log4net。

在进行每次日志调用时,我想将其存储在内存中。在我的控制台应用程序运行结束时,我想(如果app.config设置为true)只接受警告和致命并在电子邮件中发送所有这些消息。我注意到 MemoryAppender 但不太确定如何使用它。另请参阅 SMTPAppender ,但不确定它是否是正确的工具,否则我将使用MemoryAppender并以某种方式过滤掉Levels Warn / Fatal的事件,然后使用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,但这不是正确的输出,如何获取消息字符串,因为它已使用正确的模式写入文件/控制台日志时间等并构建自己的StringBuilder?然后我将它放在我的电子邮件正文中并使用SmtpClient发送它。 RenderMessage只是给我提供给Log.Warn()调用的字符串,而不是写入日志的字符串。这是因为没有在MemoryAppender上设置布局模式吗?

由于

2 个答案:

答案 0 :(得分:6)

MemoryAppender只会“附加”到内存中,因此仅用于开发和测试目的。并且目前没有只会在应用程序关闭时附加的appender。

SMTPAppender介于两者之间,因为它继承了the BufferingAppenderSkeleton。这些appender有一个BufferSize属性,可以控制在刷新之前在内存中保留的消息数。

要传递给appender的消息是使用根元素或单个记录器元素上的级别设置来控制的。在你的情况下使用一个WARN级别,它将通过WARN,ERROR和FATAL。如果您不想要ERROR消息,则必须在appender上放置一个级别过滤器。

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

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

更新2 :为了实现MemoryAppender替代方案,我建议以the MemoryAppender为出发点。 MemoryAppender是AppenderSkeleton的子类,因此可以访问RenderLoggingEvent方法。因此,我们将MemoryAppender子类化,并添加一个呈现当前批记录事件的方法:

public class RenderingMemoryAppender : MemoryAppender
{

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

答案 1 :(得分:1)

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

您可以做的另一件事是使用过滤器WARN和FATAL创建一个单独的appender(Rolling或FileAppender),然后将此appender附加到同一个记录器,并在运行结束时通过电子邮件发送此文件(如果它是非空的)(和您可以选择将其作为附件发送或在电子邮件正文中发送。如果您想了解更多细节,请告诉我,这几乎与我所知道的相同。

祝你好运!

里卡多。