Build an IIS Log Reader Web App in ASP.NET
By Peter A. Bromberg, Ph.D.
Printer - Friendly Version
Peter Bromberg

One of the projects I've been working at on my "real job" is to move some of the cumbersome legacy processes such as monitoring and controlling Windows Services, checking the status of various machines on the network ( RAM , CPU usage, processes, etc) and so on, all to the ASP.NET platform so everything we used to have to do with Terminal Services can now be done by simply bringing up a web page in the browser and choosing a TreeView menu item.

A part of that process is being able to inspect IIS logs on various machines. Classic ASP has a COM component, MSWC.IISlog, which can be found at C:\WINNT\system32\inetsrv\logscrpt.dll for this purpose. However, using this in ASP.NET would require COM Interop and possibly having to set the Page directive ASPCOMPAT="true", which forces us to run in STA threading model with a fairly significant performance hit, and I am not particularly enamored of that.



If you think about it, all the IISlog component really does is read and parse the IIS log files which are nothing more than space-delimited text data - heck, we can do that ourselves in .NET very easily.  So the approach I"ve taken is simply to load the file into a string array using the end of line marker as the delimiter, and then throw each line into a row of a DataTable by parsing the line again into a new string array, and using one of the overloads of the Rows.Add() method. Pretty simple stuff!

This give us the opportunity to bind the DataTable to an ASP.NET Datagrid control and use all the cool DataGrid features, including custom paging, without having to write a whole bunch of "reinvent the wheel" type code.

I'm not going to go through all of my code because a lot of it is "pretty code" - stuff that populates a textBox or a dropdown listbox when the page loads, etc. , and you can look at all of it in the downloadable solution zip file from the link at the bottom of this article.

What I want to focus on here is the actual method "CreateDataSource" that I wrote to read the selected IIS log file and populate the DataTable, and then bind the DataGrid:


public void CreateDataSource()
{
 int i=0;
    try
    {
        string theDate =txtDate.Text;
        string FILE_NAME = @"\\" +txtMachine.Text +
	       @"\C$\WINNT\System32\LogFiles\" +  
		  drpSiteBox.SelectedItem.Text + @"\ex" + theDate + ".log";
        FileStream fs = new FileStream(FILE_NAME, FileMode.Open,
                             FileAccess.Read,FileShare.ReadWrite);
        StreamReader sr = new StreamReader(fs); 
        string strResult = sr.ReadToEnd();
        sr.Close();
        fs.Close();
        sr=null;
        fs=null;

        string[] arLogLines = strResult.Split(Convert.ToChar("\n"));
        dt = new DataTable("log");
        string revisedColmNames=arLogLines[3].Replace("#Fields: ","");
        string[] arColm=revisedColmNames.Split(Convert.ToChar(" "));
for(int j=0;j<arColm.Length;j++)
{   
	dt.Columns.Add(arColm[j]);
	Debug.WriteLine(arColm[j]);
}
for (i =arLogLines.Length-1; i>3;i--)
{  
	// need this because some logs get additional data appended 
	// aren't unhandled exceptions great? The CLR just loves 'em...
	try
	{
		dt.Rows.Add(arLogLines[i].Split(Convert.ToChar(" ")));
	}
	catch {}

}
DataGrid1.DataSource=dt;
DataGrid1.DataBind();
} 
catch(Exception ex)
{
        lblMessage.Text=ex.Message +"col: " +i.ToString();
		lblMessage.ForeColor=System.Drawing.Color.Wheat;
    }
}      

Once the Grid is bound, the result looks like this:

This produces a really nice customizable pageable DataGrid with an absolute minimum of extra coding.   I use the Administrative share "C$" in my code which allows us to employ UNC file access and therefore to be able to find the log files on any machine on the network.  One thing you'll need to be aware of if you decide to take this approach is that the account that the web app runs under must have read permissions to the share and folder where the logs are, on that specific machine. If you have an domain account with administrative permissions, you can use the <identity impersonate ="true" userName="Hotshot" password ="geronimo" /> in your web.config.

Download the code that accompanies this article

 

Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform.