.Net Logging: Write Once Log Many
Need to write a log file in .Net C# and want to use the convenience of Console.WriteLine in writing to the console and one or more log files? That is what this article discusses.
In demonstration, I will show you the end result and work backwards. I have included the test as a static method on the class which demonstrates its functionality.
/// <summary>This is only for the blog post and meant to show how to use the /// function, simply call from your main function.</summary> public static void Usage() { // Setup the file to write to System.IO.StreamWriter FileLogging = new System.IO.StreamWriter(@"C:myLog.txt"); FileLogging.AutoFlush = true; // Create the MultipleLog to be a catalyst to doing double messages // one to the target file and one to console.out. TextWriter dual = new MultipleLogs(Console.Out, FileLogging); // Inform the console to use our overriden // write method which can output multiple writes. Console.SetOut(dual); // Now everytime we write to the console we also write to the file. Console.WriteLine(DateTime.Now.ToShortTimeString() + " Process Start"); Console.WriteLine(DateTime.Now.ToShortTimeString() + " Process End"); } #endregion
Pretty easy to setup, just create the MultipleLogs object and load it with targets. Then once you do a write to the screen it outputs it to all targets! Write once, log many.
The magic happens in our Multiple Logs class. Note this class could handle multiple targets and not just two. I have included the whole file here:
public class MultipleLogs : TextWriter { #region Variables // Holds multiple targets. private List<TextWriter> _OutputTargets = new List<TextWriter>(); #endregion #region Operations /// <summary>Setup the multipe log targets.</summary> /// <param name="targets">Individual targets to write to.</param> public MultipleLogs( params TextWriter[] targets ) { _OutputTargets.AddRange(targets); } /// <summary>We override this to pass in the character to all the logs.</summary> /// <param name="chr">Target character.</param> public override void Write( char chr ) { foreach (TextWriter tx in _OutputTargets) tx.Write(chr); } /// <summary>Let the system know our intentions on encoding. The first /// one is the standard</summary> public override System.Text.Encoding Encoding { get { return _OutputTargets[0].Encoding; } } #endregion #region Example Usage /// <summary>This is only for the blog post and meant to show how to use the /// function, simply call from your main function.</summary> public static void Usage() { // Setup the file to write to System.IO.StreamWriter FileLogging = new System.IO.StreamWriter(@"C:myLog.txt"); FileLogging.AutoFlush = true; // Create the MultipleLog to be a catalyst to doing double messages // one to the target file and one to console.out. TextWriter dual = new MultipleLogs(Console.Out, FileLogging); // Inform the console to use our overriden // write method which can output multiple writes. Console.SetOut(dual); Console.WriteLine(DateTime.Now.ToShortTimeString() + " Process Start"); Console.WriteLine(DateTime.Now.ToShortTimeString() + " Process End"); } #endregion }
Don’t forget to include System.IO; for the reference to TextWriter!