System.Diagnostics.Trace是否有性能降低?
本文关键字:性能 Diagnostics Trace 是否 System | 更新日期: 2023-09-27 18:10:13
我正在寻找一个简单的本地。net错误记录解决方案。我对使用log4net、Elmah或任何其他日志库不感兴趣。下面是我打算使用的。我的问题是我的网站的性能是最重要的,这个流程会带来任何性能问题吗?
Global.asax
protected void Application_Start(object sender, EventArgs e)
{
GlobalFilters.Filters.Add(new HandleExceptionsAttribute());
}
Handle Exceptions属性:
public sealed class HandleExceptionsAttribute : HandleErrorAttribute
{
private void TraceError(Exception _this)
{
Trace.TraceError("{0} Exception {1}", DateTime.Now.ToString("M/d/yyyy h:mmtt"), _this);
}
public override void OnException(ExceptionContext filterContext)
{
var ex = filterContext.Exception;
TraceError(ex);
Task.Run(() =>
{
using (var msg = new MailMessage(ConfigurationManager.AppSettings["SendErrorsFrom"], ConfigurationManager.AppSettings["SendErrorsTo"]))
{
msg.Subject = ex.Message;
msg.Body = ex.StackTrace;
using (var smtp = new SmtpClient())
smtp.Send(msg);
}
});
}
}
web . config:
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="textWriterListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="logs'log.txt"/>
<add name="eventLogListener" type="System.Diagnostics.EventLogTraceListener" initializeData="Base Test" />
<remove name="Default"/>
</listeners>
</trace>
</system.diagnostics>
为每个异常获取电子邮件?祝你好运。
代码将不能很好地工作。这和Trace无关。TraceError本身,而是你想要做的。我有时看到错误循环在几分钟内产生数百万个异常。你这是自找的拒绝服务攻击。让我们做一些数学运算。每分钟100万个异常,网络上大约1500字节的文本团导致1.5 gb/分钟的邮件数据。这将消耗大约25mbit的网络带宽。这是一个保守估计。但如果发生这种情况,内存很快就会用完。异步任务方法将使任务排队。因为你发送电子邮件的速度比你产生异常的速度慢,你很快就会得到一个OutOfMemoryException,你也会尝试通过邮件....发送至少在拒绝服务情况持续之前,您将很快获得免费重启。
一个更好的方法是编写一个自定义的MailTraceListener,它将聚合异常并限制每封邮件发送异常的速率,例如最多1/分钟。然后你可以添加一个RollingFileTraceListener(不是. net的一部分)。存在外部日志库是有原因的),它将记录到平面文件,您可以通过邮件发送汇总摘要。通过异常消息检测重复异常,只记录摘要也是有意义的。例如,第一个异常总是被记录下来,然后你检查最后一个异常是否与新异常相同。如果是,增加一个计数器,一直这样做,直到一个不同的计数器出现。然后你可以写一个很好的总结100亿个异常确实发生了,除了第一个,你没有记录任何一个。
异常本身很慢。你是否追踪他们都无关紧要。您可以优化Trace调用,但这是您最不关心的。栈展开是异常处理中开销最大的部分。跟踪的主要性能影响来自您配置的输出设备。如果你仔细分析一下,你会很快发现的。
正如我上面所概述的,一个好的错误处理策略并不容易实现,因为您正在处理几乎任何事情都可能发生的异常情况。包括你对异常的处理成为问题的一部分。你需要彻底地测试它,否则你会发现,如果没有错误发生,它会完美地工作,但由于某些奇怪的原因,当出现一些极端情况异常时,它会崩溃。
看情况。
TraceError使用条件编译器属性,这意味着如果您在编译时将TRACE标志关闭(如在RELEASE模式下),则所有对TraceError的调用将从编译的代码中删除。从表面上看,这将消除活动代码的大多数性能问题,因为性能是如此重要,您肯定会在RELEASE模式下编译。
但是,在对TraceError
的调用中没有找到的任何补充代码仍然会运行。所以在你的例子中,对HandleExceptionsAttribute.TraceError()
的调用仍然会被执行——它会立即返回,不做任何事情。
// This code sticks around, and could still have performance implications.
var additionalInfo = GoGetMoreInformation();
// This code disappears when compiled
Trace.TraceError("Something went wrong: {0}", additionalInfo);
当然,另一个缺点是,您将无法从实时环境中的跟踪中获得任何信息,而它们可能被证明是非常有用的。在您的情况下,这意味着在您的活动系统中抛出的任何异常对您来说都是完全不可见的。如果用户不抱怨结果,你就没有任何迹象表明出了问题。
<<h2>修正/h2>显然我上面所说的关于Debug
是正确的,但是Visual Studio将在默认情况下在发布模式构建期间保留TRACE标志。
对于web应用程序,没有理由自己动手——框架有能力通过使用ASP单独配置通知你任何异常。NET运行状况监视。请参阅https://msdn.microsoft.com/en-us/library/Bb398933.aspx以获得良好的开端。
还要记住你得到的代码将是丑陋的。当电子邮件服务器配置错误,在异常处理程序中抛出异常时会发生什么。当程序崩溃而不影响性能时记录错误是一个非常重要的问题,建议使用经过良好测试的库,而不是尝试在这里推出自己的解决方案。