using System;
using System.Xml;
using System.IO;
using System.Collections;
using OpenNETCF;
namespace OpenNETCF.Diagnostics
{
/// <summary>
/// Implements writting to the event log using XML
/// </summary>
public class XMLEventLogWritter:IEventLogWritter
{
public event EntryWrittenEventHandler EntryWritten;
public event EventHandler EventLogCollectionUpdated;
private string source="";
private string log="";
private string logFileName="";
private string logPath="";
private string logDisplayName="";
private EventLogEntryCollection eventLogEntryCollection = new EventLogEntryCollection();
private ArrayList eventLogCollection = null;
/// <summary>
/// The Xml document representing the log
/// </summary>
private XmlDocument xmlLog=null;
/// <summary>
/// The current eventlog node which contains all Log nodes
/// </summary>
private XmlNode nodeEventLog = null;
/// <summary>
/// The current log node that is being written to
/// </summary>
private XmlNode nodeLog = null;
/// <summary>
/// The default Xml for a new log
/// </summary>
private readonly string EVENTLOG_ROOT = "<eventLog></eventLog>";
internal XMLEventLogWritter(string log, string source, string logPath, string logFileName)
{
this.log = log;
this.source = source;
this.logPath = logPath;
this.logFileName = logFileName;
this.InitializeLogFile();
}
#region Private Methods
/// <summary>
/// Creates the XML document to store the event logs
/// </summary>
private void InitializeLogFile()
{
//Create the log file
this.CreateLogFile();
//Load the nodes
this.LoadNodes();
//Save the file
this.SaveLogFile();
//Load the eventLogEntryColelction
this.LoadEventLogEntryCollection();
}
/// <summary>
/// Loads the eventlog collection
/// </summary>
private void LoadEventLogCollection()
{
XmlNodeList list = this.xmlLog.GetElementsByTagName("log");
this.eventLogCollection = new ArrayList();
foreach(XmlNode node in list)
{
string log = this.NodeAttributeValue(node,"name");
if(log.Length>0)
{
eventLogCollection.Add(new EventLog(log,"",this.logPath,this.logFileName, EventLogWritterType.XML));
}
}
}
/// <summary>
/// Creates a log file on the system
/// </summary>
private void CreateLogFile()
{
//Create a new log file
this.xmlLog = new XmlDocument();
//Check to see if the file exists
if(File.Exists(this.logPath+this.logFileName))
{
//The file is available so load it into the XML
try
{
this.xmlLog.Load("file://"+this.logPath+this.logFileName);
}
catch(Exception e)
{
throw new Exception("Unable to open log file as XML!!",e);
}
}
else
{
//The file does not exist so load the default XML
this.xmlLog.LoadXml(this.EVENTLOG_ROOT);
}
}
/// <summary>
/// Loads the source, log and EventLog nodes
/// </summary>
private void LoadNodes()
{
//Get the event Log node
this.nodeEventLog = this.xmlLog.GetElementsByTagName("eventLog")[0];
//Get the current log node
this.nodeLog = this.EventLogNode(this.log);
if(this.nodeLog==null)
{
//Create the log node
this.nodeLog = this.CreateLogNode(this.log);
}
//Set the log display name
this.logDisplayName = this.NodeAttributeValue(nodeLog,"logDisplayName");
}
/// <summary>
/// Loads the eventlog entry collection
/// </summary>
private void LoadEventLogEntryCollection()
{
//This is only called when the log is changed and when the class is instantiated so it's pretty safe
//to re-init the collection
this.eventLogEntryCollection = new EventLogEntryCollection();
string[] attributes = new string[]{"machineName","userName","timeGenerated",
"source","message","eventLogEntryType",
"eventID","category","rawData","id","timeWritten","index"};
//Get all the eventLog nodes
foreach(XmlNode node in this.nodeLog.ChildNodes)
{
string machineName = node.Attributes.GetNamedItem(attributes[0]).Value;
string userName = node.Attributes.GetNamedItem(attributes[1]).Value;
DateTime timeGenerated = DateTime.Parse(node.Attributes.GetNamedItem(attributes[2]).Value);
string source = node.Attributes.GetNamedItem(attributes[3]).Value;
string message = node.Attributes.GetNamedItem(attributes[4]).Value;
EventLogEntryType type = (EventLogEntryType)Int32.Parse(node.Attributes.GetNamedItem(attributes[5]).Value);
int eventID = Int32.Parse(node.Attributes.GetNamedItem(attributes[6]).Value);
short category = Int16.Parse(node.Attributes.GetNamedItem(attributes[7]).Value);
byte[] rawData = System.Text.Encoding.Unicode.GetBytes(node.Attributes.GetNamedItem(attributes[8]).Value);
string id = node.Attributes.GetNamedItem(attributes[9]).Value;
DateTime timeWritten = DateTime.Parse(node.Attributes.GetNamedItem(attributes[10]).Value);
int index = Int32.Parse(node.Attributes.GetNamedItem(attributes[11]).Value);
//Add to the collection
EventLogEntry eventLogEntry = new EventLogEntry(category,rawData,type,eventID,index,machineName,message,source,timeGenerated,timeWritten,userName,id);
this.eventLogEntryCollection.Add(eventLogEntry);
}
}
/// <summary>
/// Create the log node and adds it to the nodeEventLog
/// </summary>
private XmlNode CreateLogNode(string logName)
{
XmlNode newNode = this.xmlLog.CreateNode(XmlNodeType.Element,"log","");
XmlAttribute att = this.xmlLog.CreateAttribute("name");
att.Value = this.log;
newNode.Attributes.Append(att);
att = this.xmlLog.CreateAttribute("logDisplayName");
att.Value = this.logDisplayName;
newNode.Attributes.Append(att);
this.nodeEventLog.AppendChild(newNode);
return newNode;
}
/// <summary>
/// Retrieves and event log node by logName
/// </summary>
/// <param name="logName">The name of the log node</param>
/// <returns>The XmlNode containing the log items or null if not found</returns>
private XmlNode EventLogNode(string logName)
{
XmlNodeList list = this.xmlLog.GetElementsByTagName("log");
foreach(XmlNode node in list)
{
XmlAttribute att = (XmlAttribute)node.Attributes.GetNamedItem("name");
if(att!=null)
if(att.Value == logName)
return node;
}
//Return null;
return null;
}
/// <summary>
/// Changes an attribute in the specified node
/// </summary>
private void NodeAttributeValue(XmlNode node, string attributeName, string newAttributeValue)
{
XmlAttribute att = (XmlAttribute)node.Attributes.GetNamedItem(attributeName);
if(att!=null)
{
att.Value = newAttributeValue;
this.SaveLogFile();
}
else
throw new Exception("Attribute " + attributeName + " not found in node \"" + node.Name + "\"");
}
/// <summary>
/// Retreives the attribute in the specified node
/// </summary>
/// <param name="node"></param>
/// <param name="attName"></param>
/// <returns>The value of the attribute or null if not found</returns>
private string NodeAttributeValue(XmlNode node, string attributeName)
{
XmlAttribute att = (XmlAttribute)node.Attributes.GetNamedItem(attributeName);
if(att!=null)
return att.Value;
else
return "";
}
/// <summary>
/// Saves the logfile
/// </summary>
private void SaveLogFile()
{
this.xmlLog.Save(this.LogPath+this.LogFileName);
}
/// <summary>
/// Writes an entry to the log file
/// </summary>
/// <param name="source"></param>
/// <param name="message"></param>
/// <param name="type"></param>
/// <param name="eventID"></param>
/// <param name="category"></param>
/// <param name="rawData"></param>
private vo