Displaying live log file contents
I'm writing some benchmarking code, which involves a Console application calling a COM+ hosted process and measuring performance. I want to constantly display results on my active console, but since some of my code is running out-of-process, I can't really write directly to the console from all parts of the system. Not to mention the fact that I want it logged to a file as well.
So I cobbled together a quick Log class that does two things - it writes to a shared log file, keeping no locks so several processes can access it (I do serialize access to the WriteLine method itself, though). I don't mind the overhead of opening/closing the file every time, since this isn't production code.
The second method is the interesting one - it monitors the log file and returns every new line that is appended to it. If no lines are available, it will block until one is reached. The fun part was using the yield return keyword, which I've been looking for an excuse to use for quiet a while now.
Note that there are many places this code can go wrong or should be improved. There is no way to stop it running, only when the application is stopped. I bring this as the basic idea, and it can be cleaned up and improved later:
1: public static IEnumerable<string> ReadNextLineOrBlock()
2: {
3: // Open the file without locking it.
4: using (FileStream logFile = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
5: using (StreamReader reader = new StreamReader(logFile))
6: {
7: while (true)
8: {
9: // Read the next line.
10: string line = reader.ReadLine();
11: if (!string.IsNullOrEmpty(line))
12: {
13: yield return line;
14: }
15: else
16: {
17: Thread.Sleep(100);
18: }
19: }
20: }
21: }
This method can now be called from a worker thread:
1: private static void StartListenerThread()
2: {
3: Thread t = new Thread(delegate()
4: {
5: while (true)
6: {
7: foreach (string line in Log.ReadNextLineOrBlock())
8: {
9: // I added some formatting, too.
10: if (line.Contains("Total"))
11: Console.ForegroundColor = ConsoleColor.Green;
12:
13: Console.WriteLine(line);
14:
15: Console.ForegroundColor = ConsoleColor.White;
16: }
17: }
18: });
19:
20: t.Start();
21: }
5 Comments
Comments have been disabled for this content.
Byron said
Nice bit of code, sort of like a .NET Tail.
Noam H said
You can use the command line tool "tail -f filename.log" to monitor file append. It is part of the windows resource kit tools.
Avner Kashtan said
Noam: Of course I can. I can also use SMSTrace, that used to come with the SMS 2003 Toolkit, which is a nice graphical live log viewer with highlighting and everything. But that would be no fun, when I can write it myself and use it somewher in my code.
hooher tod said
Yes there should realize the reader to RSS my feed to RSS commentary, quite simply
Carlos said
Wow! I could not even guess about it)) Not bad.