I saw a tweet today from the @ReactiveX account about a new release called Tx (LINQ to Logs and Traces). It appears to have a lot of plumbing to use the Reactive Extensions (Rx) to parse through Event Logs and Event Tracing files. One of the slides on the Tx Codeplex site also mentioned parsing IIS W3C Logs, which is something I spend a fair amount of time doing.
Even better Tx has a custom LINQPad Driver, which is one of my favorite tools for playing around with LINQ and Rx. I downloaded the sample traces and was able to view low level event tracing details from the HTTP.sys driver used by IIS, but I didn’t immediately see how to parse the IIS log files using Tx. After downloading the source I found a W3CTest.cs file that showed how to parse log files using the Tx.Windows.W3CEnumerable.FromFile or FromFiles methods.
To use this in LINQPad you do NOT need the Tx Driver, but instead you use F4 to add a reference to the Tx.Windows Nuget package:
Once the reference is added to your LINQPad query, you may also want to add the following additional namespace imports:
This gives you access to the common LINQ functions used in the Tx samples. Now I can write a query in LINQPad that uses the W3CEnumerable to parse the log files. You can write complex LINQ queries or use the toDataGrid parameter of the Dump method to display the data in a grid format:
After I had it working in LINQPad, I next thought: “Why can’t I use this in Powershell?”. The Tx library targets .NET 4.0 and 4.5, so as long as you have PS 3.0 or later you can add a reference to the Tx.Windows.dll and then use the W3CEnumerable class to work with Log files.
#Load Tx.Windows.dll from current user’s LINQPad nuget local cache
#Load log file and sent output to screen
$log = [Tx.Windows.W3CEnumerable]::FromFile("C:\inetpub\logs\LogFiles\W3SVC1\u_ex131230.log")
$log | select -Last 10 | ft dateTime,cs_method,cs_uri_stem,cs_uri_query,cs_username,sc_status,time_taken
#Sent log to gridview
$log | out-gridview
The Gridview is very helpful since you can add filters to target specific entries similar to a LINQ query