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"
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()
string theDate =txtDate.Text;
string FILE_NAME = @"\\" +txtMachine.Text +
drpSiteBox.SelectedItem.Text + @"\ex" + theDate + ".log";
FileStream fs = new FileStream(FILE_NAME, FileMode.Open,
StreamReader sr = new StreamReader(fs);
string strResult = sr.ReadToEnd();
string arLogLines = strResult.Split(Convert.ToChar("\n"));
dt = new DataTable("log");
string revisedColmNames=arLogLines.Replace("#Fields: ","");
string arColm=revisedColmNames.Split(Convert.ToChar(" "));
// need this because some logs get additional data appended
// aren't unhandled exceptions great? The CLR just loves 'em...
lblMessage.Text=ex.Message +"col: " +i.ToString();
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.
the code that accompanies this article