Skip to content

Instantly share code, notes, and snippets.

@tkrotoff
Created April 11, 2013 13:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkrotoff/5363486 to your computer and use it in GitHub Desktop.
Save tkrotoff/5363486 to your computer and use it in GitHub Desktop.
Enhancements for C# System.Diagnostics.Trace: add class and method names to the trace message
namespace Log
{
/// <summary>
/// Helps you trace the execution of your code.
/// </summary>
/// <remarks>
/// Same as System.Diagnostics.Trace but adds the class and method names to the trace message.<br/>
/// <br/>
/// More documentation about Trace and Debug:<br/>
/// <list type="bullet">
/// <item><a href="http://vincentlaine.developpez.com/tuto/dotnet/log/">La gestion correcte des logs en .Net</a></item>
/// <item><a href="http://www.15seconds.com/Issue/020910.htm">Tracing in .NET and Implementing Your Own Trace Listeners</a></item>
/// <item><a href="http://www.codeproject.com/KB/trace/debugtreatise.aspx">A Treatise on Using Debug and Trace classes, including Exception Handling</a></item>
/// <item><a href="http://www.thescarms.com/dotnet/DebugTrace.aspx">Use the Trace class with EventLog and TraceLog listeners to debug runtime code</a></item>
/// <item><a href="http://blogs.infosupport.com/blogs/marcelv/archive/2005/08/22/985.aspx">Please be careful when using Trace.WriteLineIf()</a></item>
/// </list>
/// It is preferable to set Trace.AutoFlush to true. AutoFlush should only be set to false if
/// your application is heavily writing inside a log file like a HTTP server for example.
/// For regular desktop applications, it is safer to set AutoFlush to true this way even
/// under a crash, the log file will be complete.<br/>
/// <br/>
/// Also don't forget to recreate the file log (via FileMode.Create) each time the application is rerun,
/// otherwise the log file will always increase its size.
/// </remarks>
/// <example>
/// <code>
/// FileStream textLogFile = new FileStream("ErrorLog.txt", FileMode.Create);
/// System.Diagnostics.Trace.Listeners.Add(new TextWriterTraceListener(textLogFile));
///
/// FileStream xmlLogFile = new FileStream("ErrorLog.xml", FileMode.Create);
/// System.Diagnostics.Trace.Listeners.Add(new XmlWriterTraceListener(xmlLogFile));
///
/// System.Diagnostics.Trace.TraceInformation("Hello World!"); // Outputs "Hello World!"
/// Log.TraceInformation("Hello World!"); // Outputs "MyNamespace.MyClass.MyMethod: Hello World!"
///
/// Log.Close();
/// </code>
/// </example>
/// <seealso cref="System.Diagnostics.Trace"/>
public static class Log
{
/// <summary>
/// Writes a message to the trace listeners.
/// </summary>
/// <seealso cref="System.Diagnostics.Trace.TraceInformation(string)"/>
/// <param name="message">The message to write.</param>
public static void TraceInformation(string message)
{
if (string.IsNullOrEmpty(message))
{
System.Diagnostics.Trace.TraceInformation(GetClassAndMethodName());
}
else
{
System.Diagnostics.Trace.TraceInformation(GetClassAndMethodName() + ": " + message);
}
}
/// <summary>
/// Writes a message to the trace listeners.
/// </summary>
/// <seealso cref="System.Diagnostics.Trace.TraceError(string)"/>
/// <param name="message">The message to write.</param>
public static void TraceError(string message)
{
if (string.IsNullOrEmpty(message))
{
System.Diagnostics.Trace.TraceError(GetClassAndMethodName());
}
else
{
System.Diagnostics.Trace.TraceError(GetClassAndMethodName() + ": " + message);
}
}
/// <summary>
/// Writes a message to the trace listeners.
/// </summary>
/// <seealso cref="System.Diagnostics.Trace.TraceWarning(string)"/>
/// <param name="message">The message to write.</param>
public static void TraceWarning(string message)
{
if (string.IsNullOrEmpty(message))
{
System.Diagnostics.Trace.TraceWarning(GetClassAndMethodName());
}
else
{
System.Diagnostics.Trace.TraceWarning(GetClassAndMethodName() + ": " + message);
}
}
/// <summary>
/// Flushes the output buffer, and then closes the listeners.
/// </summary>
/// <seealso cref="System.Diagnostics.Trace.Close"/>
public static void Close()
{
System.Diagnostics.Trace.Close();
}
/// <summary>
/// Gets the current class and method name.
/// Equivalent of C/C++ macro __FUNCTION__
/// </summary>
/// <remarks>
/// See:<br/>
/// <list type="bullet">
/// <item><a href="http://stackoverflow.com/questions/259536/c-version-of-function-macro">C# version of __FUNCTION__ macro</a></item>
/// <item><a href="http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&amp;ixPost=6163">printing the calling method name : C#</a></item>
/// </list>
/// <br/>
/// This method is public because of the unit tests.
/// </remarks>
/// <returns>The name of the last - 2 function called.</returns>
public static string GetClassAndMethodName()
{
System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace();
string className = stackTrace.GetFrame(2).GetMethod().ReflectedType.FullName;
string methodName = stackTrace.GetFrame(2).GetMethod().Name;
methodName = methodName.Replace(".ctor", "ctor");
return className + "." + methodName;
}
}
}
namespace Log.Tests
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class LogTests
{
[TestMethod]
public void TestTraceInformation()
{
Log.TraceInformation("info");
}
[TestMethod]
public void TestTraceError()
{
Log.TraceError("error");
}
[TestMethod]
public void TestTraceWarning()
{
Log.TraceWarning("warning");
}
[TestMethod]
public void TestGetClassAndMethodName()
{
string name = Log.GetClassAndMethodName();
Assert.AreEqual("System.RuntimeMethodHandle._InvokeMethodFast", name);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment