5

I have a console program, I'd like to continuously mirror the result of Console.Write to a collection, which I can look at the tail of in real time. The collection could be an array, a list, etc.

I assume I'd have to use some sort of event handler?

I don't mind being pointed in the direction of a 3rd party library, e.g. NLog.

Update

I need to maintain a collection in memory, which mirrors the current console state (I can then send to a remote WinForms app using sockets). Details aside, I think I can do this with a few lines of C# - I don't want to add a huge logging library without a good need for it.

Contango
  • 76,540
  • 58
  • 260
  • 305

7 Answers7

5

The Console class allows you to replace the output and error streams. Just what you need here, you can replace them with a TextWriter that also logs what is written. A sample implementation:

    class ConsoleLogger : System.IO.TextWriter {
        private System.IO.TextWriter oldOut;
        private Queue<string> log = new Queue<string>();
        private StringBuilder line = new StringBuilder();
        private object locker = new object();
        private int newline;
        private int logmax;

        public ConsoleLogger(int history) {
            logmax = history;
            oldOut = Console.Out;
            Console.SetOut(this);
        }
        public override Encoding Encoding {
            get { return oldOut.Encoding; }
        }
        public override void Write(char value) {
            oldOut.Write(value);
            lock (locker) {
                if (value == '\r') newline++;
                else if (value == '\n') {
                    log.Enqueue(line.ToString());
                    if (log.Count > logmax) log.Dequeue();
                    line.Length = newline = 0;
                }
                else {
                    for (; newline > 0; newline--) line.Append('\r');
                    line.Append(value);
                }
            }
        }
    }

Usage:

    static void Main(string[] args) {
        var outLogger = new ConsoleLogger(100);
        // etc...
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
2

You could probably write a new TextWriter who's Write calls populate a list instead of writing to a stream. You would then need to set this through Console.SetOut(...)

Matthew Abbott
  • 60,571
  • 9
  • 104
  • 129
2

Using Console.SetOut you can set your custom implemented TextWriter.

George Polevoy
  • 7,450
  • 3
  • 36
  • 61
1

You can create a simple helper method and call that instead of Console.Write.

private void WriteToConsole(string message)
{
    myList.Add(message);

    Console.Write(message);
}
MartinHN
  • 19,542
  • 19
  • 89
  • 131
  • Ok, thats workable. However, I'd rather not change the existing console app, and this will create problems when there is multiple parameters for Console.Write(). – Contango Mar 20 '11 at 11:45
1

If you want to write code like:

    WriteToConsole("{0} tel is: {1:+### ### ### ###}", "Name", 242352356578);

Then you could have code:

    private static Queue<String> q = new Queue<String>(1000);
    private static void WriteToConsole(String message)
    {
        q.Enqueue(message);
        Console.Write(message);
    }
    private static void WriteToConsole(String message, params Object[] r)
    {
        String s = String.Format(message, r);
        q.Enqueue(s);
        Console.Write(s);
    }
Margus
  • 19,694
  • 14
  • 55
  • 103
0

Use log4net for continuosly dump in the file, and then use this for tail: http://tailf.codeplex.com/

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
0

See Capturing console output from a .NET application (C#).

Community
  • 1
  • 1
Contango
  • 76,540
  • 58
  • 260
  • 305