I wonder what the best approach is in implementing a logger which essentially eats all Console.WriteLine()
messages and spits out a text file of all these messages.
I know I could use a StringBuilder
and populate it with all the messages by doing .AppendLine
wherever Console.WriteLine
occurs...but I am looking for something more magical than that. Some way using which I don't have to write as many lines of code as Console.WriteLine
s in existing code.
And in case you missed the tags, this is for a C#4.0 console application.
I assume what you want is a stream that writes to standard out and to a file. That is, you want everything to still show up on the console, but you also want it to be written to a file. (If you just wanted to redirect output to a file, you could do that from the command line.)
You need to create your own TextWriter
-derived class, and have it do the actual output. You call Console.SetOut
to make the console write to your TextWriter
.
class ConsoleLogger: TextWriter
{
private TextWriter ConsoleOutputStream;
private StreamWriter LogOutputStream;
public ConsoleLogger(string logFilename)
{
ConsoleOutputStream = Console.Out;
// Initialize your log file
LogOutputStream = new StreamWriter(logFilename);
}
public void Write(string s)
{
ConsoleOutputStream.Write(s);
LogOutputStream.Write(s);
}
// Other Write functions format their arguments and call Write(string).
}
And in the program that uses this:
private ConsoleLogger MyLogger;
const string LogFilename = "ConsoleLog.txt";
void Main()
{
MyLogger = new ConsoleLogger(LogFilename);
Console.SetOut(MyLogger);
}
You don't have to override all the TextWriter
methods. As the documentation says, "A derived class must minimally implement the TextWriter.Write(Char)
method to make a useful instance of TextWriter
."
I've done something similar to this, and it works quite well.
Instead of using Console.Write
in your code, use Trace.Write
. Then in the config file, append the ConsoleTraceListener
to the trace listeners.
This technique will allow you to trace, and the trace framework will output it both to the console and whatever trace listener you set up (probably TextWriterTraceListener in your case).
Some 3rd party lib (log4not goes into my mind) allows an encapsulation of all logging mechanisms too.