我目前使用带有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上设置布局模式吗?
谢谢
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)