System.Diagnostics.Trace是否有任何性能降级?

Cyb*_*rew 7 c# trace system.diagnostics asp.net-mvc-5

我正在寻找一个简单的本机.NET错误日志记录解决方案.我对使用log4net,Elmah或任何其他日志库不感兴趣.以下是我计划使用的内容.我的问题是我的网站上的性能是至关重要的,这个流程是否会引入任何性能问题?

Global.asax中

protected void Application_Start(object sender, EventArgs e)
        {
            GlobalFilters.Filters.Add(new HandleExceptionsAttribute());
        }
Run Code Online (Sandbox Code Playgroud)

处理异常属性:

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);
                }
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

Alo*_*aus 5

收到每个异常的电子邮件?祝你好运。

原样的代码将无法正常工作。它与Trace.TraceError本身无关,而与您要执行的操作有关。我有时看到错误循环,几分钟之内就会产生数百万个异常。您正在努力实现自我造成的拒绝服务攻击。让我们做一些数学。每分钟100万个例外,文字斑点约为ca。网络上的1500字节导致邮件数据流量为1.5GB / min。这会吃掉。网络带宽的25 MBit。这是一个保守的估计。但是,如果发生这种情况,您将很快耗尽内存。异步任务方法将使任务排队。由于您发送电子邮件的速度比产生异常的速度慢,因此您很快就会收到OutOfMemoryException异常,您也将尝试通过邮件发送....至少在拒绝服务状况持续之前,您将很快获得免费重启。

更好的方法是编写一个自定义MailTraceListener,它将聚集异常并限制每封邮件的异常发送率,例如,至多1分钟。然后,您可以添加一个RollingFileTraceListener(不是.NET的一部分。存在外部日志记录库的原因是这样),它将记录到一个平面文件中,并且可以通过邮件发送汇总摘要。通过异常消息检测重复的异常以仅记录摘要也很有意义。例如,始终记录第一个,然后再次检查,最后一个异常与新的相同。如果是,则增加一个计数器并继续这样做,直到出现另一个计数器为止。然后,您可以写一个不错的摘要,即刚刚发生了100亿个异常,除了第一个异常,您没有记录任何异常。

异常本身很慢。是否跟踪它们不起作用。您可以优化跟踪调用,但这是您最不用担心的。堆栈展开是异常处理中最昂贵的部分。跟踪的主要性能影响是配置的输出设备。如果您对其进行概要分析,将会很快发现。

正如我在上面概述的那样,一个好的错误处理策略不容易实现,因为您正在处理几乎任何事情都可能发生的异常情况。包括您对异常的处理成为问题的一部分。您需要进行彻底的测试,否则,如果没有错误发生,它将发现它可以正常工作,但是由于某种奇怪的原因,当发生一些极端情况时,它会崩溃。


Str*_*ior 4

这取决于。

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); 
Run Code Online (Sandbox Code Playgroud)

当然,另一个缺点是您无法从实际环境中的跟踪中获取任何信息,而在实际环境中它们可能非常有用。就您而言,这意味着您的实时系统中引发的任何异常对您来说都是完全不可见的。如果用户不抱怨结果,就没有任何迹象表明有任何问题。

更正

显然我上面所说的是正确的Debug,但 Visual Studio 默认情况下会在发布模式构建期间保持 TRACE 标志处于活动状态。