Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

Log Wizard - Viewing Windows Event Logs Can Be Fun!

4.64/5 (5 votes)
21 Jan 2016GPL314 min read 30K   982  
You can do advanced searching through your Windows Event Logs. Even regex searching and filtering. No expert skills required.

Table of Contents

Other Articles in the Log Wizard Series

Introduction, Filters, Notes

Introduction

Viewing Windows Event Logs can get pretty painful. The default Event Viewer has a weird UI, to say the least (it's wasting a lot of space, for one). To the existing alternatives, I'm here to add a new one - Log Wizard.

I created Log Wizard to help anyone easily filter through logs in order to identify bug(s) and/or issue(s). It allows for several types of logs, and as of version 1.7, it allows for Windows Event Logs as well. I host it on github, and the plan is to get a new release out every 3-4 weeks or so.

The process of viewing, filtering and/or searching has to be extremely easy. If this is not the case, I clearly did something wrong - let me know!

Getting Started: The Short Version

Once you start Log Wizard, it will wait for you to open a Log. Just press Ctrl-O (equivalent of Actions >> Open Log).

Image 1

Select Windows Event Log and then press OK. Events will start coming in - as they show up, you'll see the progress in the status bar. Depending on the size of your Event Logs, this may take a few seconds, but the UI is responsive at all times.

I will show you events from the Application and the System Event Logs, bundled together.

Note that the latest events come first - thus you can have a quick look at what happened last while still waiting for the older events.

Image 2

As a sneak peak, just try the Ctrl-F (Find), type something (even regexes), and enjoy the preview. Or, try Ctrl-G (Go to Line/Time) and type something like -10h (go to 10 hours ago relative to your selected row), or -2.5d (go 2.5 days ago).

Or, just roam through the events, and see that I've done my best to use every bit of space to show relevant information. You can toggle information on/off until you only see what is important to you.

Getting Started: The Long Version

Once you've pressed Ctrl-O, and selected Windows Event Log, you can of course tweak a few things to your liking:

Image 3

First thing to note is that you can look at several (Windows Event) Logs at a time. They will be sorted by date/time. You can open Local Logs (default), or Remote Logs (more on that in a bit).

Opening Local Logs

In Event Log(s) text box, you can type the name of any Windows Event Log - and as soon as it's recognized, the green "OK" is shown (one entry per line).

Or, you can check/uncheck logs from the list shown below the text box (this is clearly easier :) ) - the text box will update, to reflect your choices.

The problem with the list shown below the box is that you're not guaranteed that the list is complete. To enumerate all Windows Event Logs is rather cumbersome and close to impossible. In .NET, we have EventLog.GetEventLogs([remote_machine_name]), but this will only return a very few log names. Or simply put, the usual ones. It won't even show the System log!

To get around that, I will go pay a visit to C:\Windows\System32\winevt\Logs - and show the more recently updated files. Unfortunately, that is a very long list, and most of the logs are empty.

The only way to know if such a log is empty or not is to open it and start reading from it. This is of course, time consuming. As you will come to see, everything is time consuming, when it comes to reading Windows Event Logs.

To help you realize which logs are worth pursuing, I've provided the Test button below the Event Logs. It will open a new window and show you which of the logs you selected have any entries - and it will also show you the number of entries of each log (it works even for remote machines, assuming you've set the password properly).

Once you're comfortable with your choice, just click OK at the bottom, and Log Wizard will start collecting and showing the information in the Log(s).

Opening Remote Logs

You can connect to Remote Logs as well. I've made it so that the process is as seamless and painless as possible. To connect to a remote machine, you will need to provide the machine name, domain, username and password.

When you've set them, you will see a Test button that shows you whether you've managed to connect to the remote machine or not. When you manage to connect, the (checked) list of Event Logs updates.

You can check/uncheck logs from that list or manually type the name of a Windows Event Log from the remote machine. As soon as the name is correct, you will see the green "OK".

Click the OK at the bottom, once you've selected the Logs you wanted to view. Log Wizard will now collect and show you the information in the Log(s).

One thing to note is that Log Wizard remembers your choices, so next time you open Log Wizard, it will re-open what you just selected now. In case you connected to a remote machine, it will not store the password locally - it will force you to re-enter it. Once the password is correct, it will re-read the logs and show them to you.

Tweak It To Your Liking

As I already said, I don't like wasting (UI) space. Anything you don't like, you can turn off. Here's what I mean:

The View Pane

Depending on the type of your log, it may contain lots of columns. In the View Pane, you want to have the best mix of "summary/detail", so that you don't have too many columns, but not too few either. In the case of Windows Event Logs, by default, I show you the Message, Line, Date, Time, Level (the rest are shown in the Details Pane).

You decide what matters to you: first, you can resize the columns and/or move them around. To move a column, right click its header. A menu will show up, and you can move that column to its left or right (see the bottom actions).

You can also show/hide any of the columns - just right click on any column header. Here, I just showed the Log and Category:

Image 4

The Details Pane

By default, the Details Pane shows everything except Line, Date, Time, Level columns. They are shown in the first row (which is fixed), and the second row is mobile, where the full Message is shown. You can of course resize the Details pane and/or customize it.

When you customize the Details Pane, you can show/hide columns, and specify where (in what row) they are shown. Right click on it, and select "Edit Description Layout".

Image 5

You should be able to easily modify it to what you want. For instance:

Image 6

Toggle Away!

Anything you don't want can be toggled off. Even the Details Pane! Just Alt-D it OFF, and then press Alt-D to turn it back ON. Or the Status bar - Alt-S to turn it ON/OFF.

You can even toggle of the title bar (Alt-T):

Image 7

To see what you can toggle ON/OFF (and instantly see what it means), you can press Actions >> Show/Hide Information (you have to have the Status Bar shown for the Actions button to be visible).

Searching for Text in Windows Event Log(s)

This is one of the places where Log Wizard truly shines. Anywhere you're in the Log, just type Ctrl-F (Find).

You can search for anything, with instant preview (of surrounding 1000 rows):

Image 8

As you can see, searching for regexes is a bliss. Few things to note:

  • By default, Log Wizard searches all columns. You can turn it off, and in that case, it will only search within the Message column
  • Log Wizard tries to guess if your text is a regex or not. You can override that
  • Your search is saved, so that next time you do Ctrl-F you can re-select it.

Once you press OK, it will take you to the first result:

Image 9

You will see that the found text is shown in bold, and in a different background, so that you can easily visually see the results.

If your search will take you to some place where the result is not visible in the View (only in the Details Pane), Log Wizard will show the full line in a different background (here, searching for .net runtime)

Image 10

In the above case, line 55534 contains .net runtime text in the Source column.

You can easily navigate within the results - just do F3 (Find Next) or Shift-F3 (Find-Previous).

The F3/ Shift-F3 are relative to your currently selected row. You can go to any row, and press F3 or Shift-F3 - the search will continue from there. Or...

You can easily toggle seeing only the results-of-the-search. Just press Ctrl-Alt-F, and here's what you'll see:

Image 11

Press it again, and you're back to seeing the full Log.

To stop the search (and stop the coloring of found words), just press ESCAPE.

Filtering

While examining the Window Event Log(s), just like with any log, there will be a lot of information you don't care about. So, you can simply filter it out. Log Wizard provides 3 types of filters:

  • Exclude Filters (you will exclude rows from your View)
  • Include Filters (you will include rows from your View - all Include filters are ORed)
  • Color Filters (you can apply pretty colors to certain rows)

One thing to note is that your Find (Ctrl-F) will work on your existing View. Namely, Find command will ignore every row what you've excluded by filtering.

I've explained Filters in dept here. To easily color some words, just select them, right click, Set Color of Lines >> Match Color, select the color, and that's it. In this case, resolution is shown in blue, and ping is shown in red.

Image 12

When you've filtered out stuff, and you quickly want it back, just toggle it in - Ctrl-Alt-L - this will show all rows from the Log, and those lines that are excluded will be shown in gray.

Image 13

In the above case, I excluded all lines starting with Installation Failure.

Go to Line/Time

Another way to navigate though your log is to go to a specific line or date/time. Just press Ctrl-G (Go to).

Image 14

The Go to works in two ways:

  • go to an exact line or date/time, OR
  • go to an offset line or date/time - just prefix with + or - and this will be an offset.

The dialog is pretty self explanatory and handles quite a lot of date/time formats. It also shows you in real-time where it will go. For instance:

  • -2.5d will show you a tip like "Before 216000 secs" (2.5 days before),
  • 11/20 will say "To Date 2016/11/20 00:00:00.000"
  • 11/19 2:4 will say "To Date 2016/11/19 02:04:00.000"
  • +10h will say "After 36000 secs" (10 hours after)

It's Real-Time

So, you've selected your Windows Event Log(s) to open, and are now nicely looking at them.

As new events are recorded - in any of the Log(s) you've open, you will see them in real-time. It automatically refreshes.

If by any chance you're on the first line (since for Windows Event Logs, latest entry is shown first, by default), you're automatically scrolled to the new entry.

History Of Opened Logs

Log Wizard is smart, and remembers everything. Your toggles, your window position, your filters, and so on. And amongst the things it remembers: History of the last Logs you opened.

By default, when you start Log Wizard, it will auto re-open your the Log you opened last time. You can turn this off in Preferences (Ctrl-P) - Automatically Open Last Log On Restart.

Just assuming you've turned off the Automatically Open Last Log On, there's no point in calling Actions >> Open Log every time to re-open Windows Event Logs you opened last time. Just go to Actions >> Show History, or Ctrl-H, and select the last log.

By default, the Last Log is in fact selected, so to do it even faster, you can consider Ctrl-H, Enter as the shortcut to re-open your last log.

Debug Viewer

Just as a side note, Log Wizard, besides Windows Event Logs, and files, can also monitor Debug Viewer entries - this is just anything an application writes using OutputDebugString. Or, for us C# users, anything written using Debug.Write[Line], or Trace.Write[Line]. So for instance, it can catch this:

C++
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    Debug.WriteLine("debug - this is the beginning");
    Trace.WriteLine("trace - this is the beginning");
    Application.Run(new Form1());
    Trace.WriteLine("this is the end");
}

When you open a new log - Ctrl-O or Actions >> Open Log, select Debug Viewer. You'll see this:

Image 15

You can filter the events by a certain application name, or show all events (depending on your running applications, this could get pretty crowded). Assuming your app is called Windowsformsapplication1, just type it in there (upper/lower case doesn't matter), and press OK. Run your application. You'll see something like this:

Image 16

Pretty cool. ;)

What Do You Want?

Creating (and optimizing) a Windows Event Log viewer was, I have to admit, much harder than I initially expected. Anyway, it was quite a lot of fun.

What would you want from such a Log Viewer? What's you favorite feature?

If it's not already here, I'll do my best to implement it:

  • drop a note in the comments below, or
  • add an issue on github

Advanced: Why Does It Take So Long For Events To Arrive?

When you open Event Viewer and open an Event Log, it's quite fast. But when you view the same log from an external application, things happen much slower. Why is that?

If you Google reading event logs in .NET, you'll see people complaining about this big time. Seems Microsoft doesn't really care. So you have two choices really:

  • Fast results, but the UI sucks big time (Event Viewer)
  • Slower results, but you can choose how to show them, thus allowing you to have a much nicer UI

If you want to query Windows Event Logs outside the Event Viewer, you have two choices:

  • Go really low level (Win32 API - Event Log Reference and Example). If you take a look at the example, you'll see why I avoided it.
  • Use the high level and easy to use .NET API. It's a few times slower.

So I chose the latter version. Why is it so slow? I don't know - I can tell you where the bottlenecks are, and the rest are simply my guesses.

Using one of the .NET APIs, you can query a Windows Event Log (using an XPATH query), and then process each record.

Walking through the query is pretty fast. Enumerating some of its important properties are the bottlenecks:

  • getting the event's Category (EventRecord.TaskDisplayName)
  • getting the Message itself (EventRecord.FormatDescription())

The FormatDescription() is very slow - on my (very fast) machine - it's about 2-3ms / call.

You should know that a lot of the EventRecord properties/methods throw a lot of exceptions. I'm guessing it's because the underlying code checks for user credentials (is user allowed to actually see the event?).

For instance, if your Windows account does not belong to "Event Log Readers" user group, reading the log will be MUCH slower.

The cost of having exceptions thrown is extremely high - sometimes 2000x fold or more (see here and here) - and you can have even more than one exception thrown when reading an event's details.

My personal take on this is that the EventRecord class is implemented very poorly - first of all, there should be a way to invoke its methods/properties without any exceptions being thrown.

But even worse, in FormatDescription(), there seems to be a global (mutex) lock - so that no two threads can access two different EventRecord' descriptions. I tried to do a Parallel.For for reading the details of 5000 events. To my surprise, the code executed in the same amount of time as reading those events in a single thread, with the only difference that using Parallel.For actually used close to 100% CPU (of my 8 logical CPUs), while doing it on a single thread used pretty much 6-8% of my CPU.

Avoiding FormatDescription() is pretty much impossible - but do let me know if you know of a way.

History

  • 21 Jan 2016, Initial version (1.7)

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)