Search code examples
c#asp.net-mvc-5tracesystem.diagnostics

Does System.Diagnostics.Trace have any performance degredation?


I am looking for a simple native .NET error logging solution. I am not interested in using log4net, Elmah or any other logging library. Below is what I am planning on using. My question is performance on my site is paramount and does this flow introduce any performance concerns?

Global.asax

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

Handle Exceptions Attribute:

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>

Solution

  • It depends.

    TraceError uses a conditional compiler attribute, which means that if you compile with the TRACE flag turned off (as in RELEASE mode), then all calls to TraceError will be removed from your compiled code. Ostensibly this would remove most performance concerns for live code, because with performance being so paramount, you are certainly going to compile in RELEASE mode.

    However, any supplemental code that's not actually found inside the call to TraceError will still run. So in your case, the call to HandleExceptionsAttribute.TraceError() will still be executed--it will just return immediately without doing anything.

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

    And, of course, the other down-side is that you're not going to get any information from your traces in live environments, where they may prove to be pretty useful. In your case, that means that any exceptions thrown in your live system will be completely invisible to you. You'll have no indication that anything is wrong if users don't complain about the results.

    Correction

    Apparently what I said above is true about Debug, but Visual Studio will leave the TRACE flag active during Release mode builds by default.