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

m3n*_*tat 9 c# log4net

我目前使用带有RollingFileAppender的log4net.

在进行每次Log调用时,我想将其存储在内存中.在我的控制台应用程序运行结束时,我想(如果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>
Run Code Online (Sandbox Code Playgroud)

在代码我做:

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

然后当我想要我称之为的事件时:

MemoryAppender.GetEvents();

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

谢谢

Pet*_*old 6

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

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

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

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

或者,如果您需要布局功能和内存追加,您可以查看子类化AppenderSkeleton.这样您就可以获得基本的布局支持.实现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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)