运行一个解析许多xml文件的进程,并且在每个文件中有许多节点代表要完成的工作。
目前,发生的错误一次一个地记录到log4net,每个错误记录一次文件,每个错误也生成一次电子邮件。这并不理想,因此我正在努力汇总一次解析会话期间发生的所有错误,以便将它们作为单个电子邮件发送。例如,让我们说文件的创建者意外地从每个工作节点中留下了一个关键字段。我不想发送4,000封电子邮件,而是发送一封包含4,000个结果的电子邮件,另外还有顶部的摘要说明" 4,000个字段缺失错误"等等。
处理异常时会出现诀窍,因为我事先并不知道会发生什么异常。因此,系统的先前状态适用于容忍异常,因为它一旦获得它就会刷新其知识(例如,发送电子邮件)。但现在我看到等到最后发送电子邮件的风险根本没有发送电子邮件。让我们说重复错误的性质最终导致系统级异常。通过丢失任何错误报告,我从来没有得到关于重复错误的信息(几乎可以肯定)导致了大崩溃。
我如何才能充分利用两个世界,将日志记录保存到最后,但无论做什么工作,收集的任何信息都有可能被记录,即使发生错误?
我有一个想法是将日志信息发送到执行缓存或批处理的自定义log4net appender,从而允许随时间修改日志消息,直到最终触发发送/记录(可能接受单个项目和lambda)它最后执行以将这些项组装成可记录的结果)。然后,在我的申请中:
var loggingContext = CreateNewLoggingContext();
try {
// Note: all reasonable and known or handleable exceptions will be
// caught from within this message. We're talking unforeseen or
// difficult to handle errors, here.
ParseAndProcessABunchOfFiles(loggingContext);
// within this method repeatedly use loggingContext.Push("error id", "error message");
}
catch (Exception e) {
loggingContext.Push("System-level exception", e);
loggingContext.Flush();
throw;
}
loggingContext.Flush();
但我对抓住每一个例外都不是特别兴奋。 OutOfMemoryException
将使得执行诸如记录之类的操作非常困难,甚至可能需要更多内存。或者磁盘完全异常会使得很难添加到磁盘上的日志文件中(尽管如果它仍然试图运行其电子邮件结果并且可能还会登录到数据库,那么它会很棒。)
如何以合理的方式实现这些目标?
更新
困扰我的部分原因是在调用堆栈的每个级别区分什么是可恢复错误以及应该终止整个过程的错误。我想我要做的就是抓住我能想到并合理期待的那些,然后在出现其他异常时,为它们添加特定的处理。