我目前将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,但这不是正确的输出,我如何获取消息字符串,因为它已以正确的模式和时间等信息写入文件/控制台日志,所以并进行构建我自己是StringBuilder吗?然后,将其放在我的电子邮件正文中,并使用SmtpClient发送。 RenderMessage只是给我提供给Log.Warn()调用的字符串,而不是写给日志的字符串。是否由于未在MemoryAppender上设置布局模式?

谢谢

最佳答案

MemoryAppender将仅“附加”到内存,因此仅在开发和测试目的中最有用。而且目前没有追加器仅在应用程序关闭时追加。
SMTPAppender介于两者之间,因为它继承了the BufferingAppenderSkeleton。这些追加程序具有BufferSize属性,该属性控制在刷新消息之前在内存中保留多少消息。
根目录元素或单个记录器元素上的级别设置控制要传递给附加程序的消息。在您的情况下,请使用WARN级别,它将通过WARN,ERROR和FATAL。如果您不希望收到ERROR消息,则必须在附加器上放置一个级别过滤器。
更新: 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);
        }
    }
}

10-06 15:02