.net Diagnostics best practices?

You should plan on raising ETW trace events throughout your app - not only to alert listeners to issues, but also to provide visibility into the behavior and even performance of your apps' and components' performance.

ETW is an (insanely) high performance and (astonishingly) low-impact way of raising events that can be gathered and analyzed - even in production environments. It's the logging & tracing infrastructure used throughout Windows, SQL, etc.

Three useful links for you:

  1. Diagnostics: Using ETW tracing in .NET 3.5 (EventProviderTraceListener)
  2. Controlling .NET Framework Logging link text
  3. Two Minute Drill: Introduction to XPerf

Read all 3 in order and then re-read - later information will be highly useful, but will be harder to understand unless you grasp the basics first ;) Ignore the instructions to use logman to start and stop your trace collections; use XPerf instead.

If you've not yet seen the Perf toolkit and XPerf viewer, then you're in for a treat! :D

I strongly encourage you to consider raising start & stop events at the start and end of all of your apps' most important features so that you can overlay these events with other telemetry so that you can see, for example, the impact of your apps features on Disk, network, memory, CPU, etc.

Hope this helps.


This response is late, but ...

I think you should consider using TraceSources rather than Debug.WriteLine and/or Trace.WriteLine. With TraceSources, you can achieve a higher level of control over your logging. The level of each TraceSource can be controlled as can the destination of the TraceSource (TraceListener). You can write code like this:

public class RectToSqlServer : IDatabaseUtilities
{
  private static readonly TraceSource ts = new TraceSource("RectToSqlServer");

  public void AddRectToDatabase(object record)
  {
    ts.TraceEvent(TraceEventType.Information, "record = {0}", record.ToString());

    //Add record to database ...

  }
}

public class RectToOracle : IDatabaseUtilities
{
  private static readonly TraceSource ts = new TraceSource("RectToOracleServer");

  public void AddRectToDatabase(object record)
  {
    ts.TraceEvent(TraceEventType.Information, "record = {0}", record.ToString());

    //Add record to database ...

  }
}

Now, you can control the logging (level, destination, etc) for each class independently. Also, note that you don't have to add both Trace.WriteLine and Debug.WriteLine to get logging in both debug and release builds. Using TraceSources will put you in a good position to use ETW in the future as there is an ETWTraceListener available starting in .NET (maybe 3.5, certainly by 4.0). BUT this particular ETW functionality is only available on Vista and later OS's.

To add capability to System.Diagnostics (primarily - maybe only - if logging via TraceSource), look at Ukadc.Diagnostics. Ukadc.Diagnostics adds pretty cool formatting capability (similar to what you can do with log4net and NLog) to System.Diagnostics. There is no code dependency (just install Ukadc.Diagnostics and add some configuration to your app.config). I have to say that I think it is really cool.

If you want to put in a little work to wrap your access to TraceSources, see here for an interesting implementation of a TraceSource wrapper that essentially gives TraceSources the ability to "inherit" logging configuration from "ancestor" TraceSources (like how log4net and NLog loggers can inherit logging settings).