【问题标题】:Does System.Diagnostics.Trace have any performance degredation?System.Diagnostics.Trace 是否有任何性能下降?
【发布时间】:2015-11-23 14:11:29
【问题描述】:

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

全球.asax

protected void Application_Start(object sender, EventArgs e)
        {
            GlobalFilters.Filters.Add(new HandleExceptionsAttribute());
        }

处理异常属性:

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>

【问题讨论】:

    标签: c# asp.net-mvc-5 trace system.diagnostics


    【解决方案1】:

    视情况而定。

    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); 
    

    当然,另一个缺点是您不会从实时环境中的跟踪中获取任何信息,而这些信息可能被证明非常有用。在您的情况下,这意味着您的实时系统中抛出的任何异常对您来说都是完全不可见的。如果用户不抱怨结果,您将没有任何迹象表明有任何问题。

    更正

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

    【讨论】:

    • 感谢您的简洁回答,似乎合乎逻辑。在没有第三方库的情况下还有其他方法吗?
    • 我想要完成的是收到有关错误的电子邮件并将其记录到某个文件中而不会影响性能。
    • @Cyber​​drew:有很多方法。大多数涉及编写自己的日志库。第三方库已经解决了很多关于正确操作的棘手问题。如果您的应用程序不仅仅是一个小型业余爱好网站,我建议您使用第三方库。它们可以轻松配置为将信息发送到日志文件、数据库和/或电子邮件,并为每个目标提供自定义格式和阈值。他们可以异步执行此操作,并且可以通过错误处理来执行此操作,因此您不会因后台线程上的未处理异常而丢弃服务器。
    • 你应该使用正确的错误处理模块试试 Elmah。它通过数据库、文件、电子邮件日志等简单地集成到 MVC 中。
    • 仅供参考,默认情况下,VS 在发布模式下保留 TRACE 常量 on,而不是关闭。
    【解决方案2】:

    为每个异常获取一封电子邮件?我祝你好运。

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

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

    异常本身很慢。如果您追踪它们或不追踪它们,则没有任何作用。您可以优化 Trace 调用,但这是您最不关心的问题。堆栈展开是异常处理中最昂贵的部分。跟踪的主要性能影响来自您配置的输出设备。如果您对其进行分析,您会很快发现这一点。

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

    【讨论】:

      【解决方案3】:

      对于 Web 应用程序,没有理由自行开发——该框架能够通过使用 ASP.NET 运行状况监控的单独配置来通知您任何未经处理的异常。请参阅https://msdn.microsoft.com/en-us/library/Bb398933.aspx 以获得良好的开端。

      还请记住,您拥有的代码会很丑陋。当电子邮件服务器配置错误并在您的异常处理程序中引发异常时会发生什么。在不影响性能的情况下崩溃时记录错误是一个非常重要的问题,强烈建议使用经过良好测试的库,而不是尝试在此处推出自己的解决方案。

      【讨论】:

        猜你喜欢
        • 2021-12-17
        • 2015-07-28
        • 1970-01-01
        • 1970-01-01
        • 2013-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多