|
<%@ Page trace="true"
language="c#"
AutoEventWireup="false"
Inherits="System.Web.UI.Page"
ContentType="text/xml"
%>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Collections" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Diagnostics" %>
<script runat=server >
/****************************************************************************************************************
* EVENT LOG RSS FEED GENERATOR
*------------------------------------------
*
* This simple utility provides a configurable RSS feed
* from the system Event Log in any machine with ASP.NET
* installed.
* Author Sergio Pereira (sergio_pereira@msn.com)
*
* Usage:
* * default (last 25 entries in the Application log)
* http://targetserver/somefolder/GetLog.aspx
*
* * change number of returned entries (showing how to return the last 40)
* http://targetserver/somefolder/GetLog.aspx?top=40
*
* * change the desired log (Security and System are blocked by code)
* http://targetserver/somefolder/GetLog.aspx?log=MyCustomLog
*
* * filter desired event types (showing how to retrieve errors and warnings)
* http://targetserver/somefolder/GetLog.aspx?types=error,warning
*
* * filter desired event source (showing how to retrieve entries from MSSQLSERVER )
* http://targetserver/somefolder/GetLog.aspx?source=MSSQLSERVER
*
* * combine all the above (last 40 MyApplication errors in the log MyLog)
* http://targetserver/somefolder/GetLog.aspx?top=40&types=error&log=MyLog&source=MyApplication
*
*
*****************************************************************************************************************/
private string LogName = "Application"; //by default
private int TopCount = 25; //by default
private ArrayList filterTypes = null;
private string EventSourceName = null;
override protected void OnInit(EventArgs e)
{
base.OnInit(e);
string[] allTypes = Enum.GetNames(typeof(EventLogEntryType));
filterTypes = new ArrayList(allTypes.Length);
for(int i=0; i<allTypes.Length; i++)
filterTypes.Add(allTypes[i].ToUpper());
string v = Request.QueryString["log"];
if(v != null && v != "" )
{
if(v.ToUpper() == "SYSTEM" || v.ToUpper() == "SECURITY")
{
//hey! You cannot view those logs buddy!
throw new HttpException(403, "Forbidden. The requested log in not accessible.");
}
LogName = v;
}
v = Request.QueryString["top"];
if(v != null && v != "")
{
TopCount = int.Parse(v);
}
v = Request.QueryString["types"];
if(v != null && v != "")
{
filterTypes = new ArrayList( v.ToUpper().Split(',', '|')) ;
}
v = Request.QueryString["source"];
if(v != null && v != "")
{
EventSourceName = v.ToUpper();
}
WriteResponse();
}
private void WriteResponse()
{
Response.Buffer = true;
Response.Clear();
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "text/xml";
Response.AddHeader("Content-Disposition","inline;filename=" + LogName + "_log.xml");
WriteRss();
Response.End();
}
private const string dcNamespace = "http://purl.org/dc/elements/1.1/";
private void WriteRss()
{
XmlTextWriter wr = new XmlTextWriter(Response.OutputStream, System.Text.Encoding.UTF8);
wr.Namespaces = true;
wr.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
wr.WriteProcessingInstruction("xml-stylesheet", "type='text/xsl' href='rssToTable.xsl' version='1.0'");
wr.WriteStartElement("rss");
wr.WriteAttributeString("version", "2.0");
wr.WriteAttributeString("xmlns", "dc", null, dcNamespace);
wr.WriteStartElement("channel");
wr.WriteElementString("title", "Event Log from " + Environment.MachineName);
wr.WriteElementString("description", "Events logged in the system's " + LogName + " Event Log");
wr.WriteElementString("copyright", "This RSS feed is copyright (c) 2004-2005 by Your Company. Resyndication and republication is expressly forbidden.");
wr.WriteElementString("publisher", dcNamespace, "Your Company");
wr.WriteElementString("author", dcNamespace, "You Lastname (you@YourCompany.com)");
wr.WriteElementString("language", dcNamespace, "en-US");
WriteItems(wr);
wr.WriteEndElement();//channel
wr.WriteEndElement();
wr.Flush();
}
private void WriteItems(XmlTextWriter wr)
{
if(EventLog.Exists(LogName))
{
EventLog log = new EventLog(LogName);
int count = 0;
int totalTries = 0;
for(int i=log.Entries.Count-1; i>=0; i--)
{
totalTries++;
EventLogEntry entry = log.Entries[i];
if(ValidateEntry(entry))
{
count++;
WriteOneItem(wr, entry);
}
if(count == TopCount || totalTries >= 500) break;
}
}
}
private bool ValidateEntry(EventLogEntry entry)
{
//check if the entry matches the requested specification
if(filterTypes.IndexOf(entry.EntryType.ToString().ToUpper()) == -1)
{
//not in the list of chosen types
return false;
}
if(EventSourceName != null && EventSourceName.CompareTo(entry.Source.ToUpper()) != 0)
{
return false;
}
return true;
}
private void WriteOneItem(XmlTextWriter wr, EventLogEntry entry)
{
wr.WriteStartElement("item");
wr.WriteElementString("title", entry.EntryType + ": " + entry.Source);
wr.WriteStartElement("guid");
wr.WriteAttributeString("isPermaLink", "false");
wr.WriteString(GetEntryUniqueID(entry));
wr.WriteEndElement();//guid
wr.WriteElementString("description", GetItemText(entry));
wr.WriteElementString("pubDate", entry.TimeWritten.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss 'GMT'"));
wr.WriteElementString("date", dcNamespace, entry.TimeWritten.ToString("yyyy-MM-dd'T'HH:mm:sszzz"));
wr.WriteElementString("creator", dcNamespace, entry.UserName);
wr.WriteEndElement();//item
}
private string GetEntryUniqueID(EventLogEntry entry)
{
return string.Format("{0}/{1}/{2}",
Environment.MachineName, LogName, entry.Index);
}
private string GetItemText(EventLogEntry entry)
{
const string itemFormat =
"<h4>The following event has been logged in the {0} Event Log of {1}</h4>" +
"<b>Event time:</b> {2:yyyy-MM-dd hh:mm:ss tt zzz} <br>" +
"<b>Event type:</b> {3} <br>" +
"<b>Event source:</b> {4} <br>" +
"<b>User:</b> {5} <br>" +
"<b>Event ID:</b> {6} <br>" +
"<pre>{7}</pre>";
return string.Format(itemFormat, LogName, Environment.MachineName,
entry.TimeWritten, entry.EntryType, entry.Source, entry.UserName, entry.EventID,
Server.HtmlEncode(entry.Message)
);
}
</script>
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Sergio Pereira is a senior software developer and architect. He currently makes his services available throughout Chicago and suburbs. Sergio has always made himself proficient in mainstream Microsoft technologies and has a deep interest in emerging technologies and the software life cycle aspect of development.
Feel free to contact Sergio at sergio_pereira(AT)msn(dot)com.