繁体   English   中英

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

[英]Does System.Diagnostics.Trace have any performance degredation?

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

Global.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>

为每个例外获取电子邮件? 祝你好运。祝你好运。

代码本身不会很好。 它不是关于Trace.TraceError本身,而是你想做什么。 我有时会看到错误循环,它会在几分钟内产生数百万个异常。 您正在努力实现自我拒绝服务攻击。 让我们做一些数学。 每分钟100万个例外,文本blob为ca. 网络上的1500字节导致1,5GB / min的邮件数据。 这会吃大约 25 MBit的网络带宽。 这是一个保守的估计。 但如果发生这种情况,你将很快耗尽内存。 异步任务方法将对任务进行排队。 由于您发送的电子邮件速度比生成异常的速度慢,您很快就会收到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); 

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

更正

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM