From 28d49046fcd88093d6bc486f56b4e0bce02a766a Mon Sep 17 00:00:00 2001 From: Jonathan Preddy Date: Thu, 17 Jul 2014 15:05:43 -0400 Subject: [PATCH] Added ISSW3C capability and improved exception handling. --- TimberWinR/Configuration.cs | 572 +++++++++++++++++++++++++++++++++--- 1 file changed, 527 insertions(+), 45 deletions(-) diff --git a/TimberWinR/Configuration.cs b/TimberWinR/Configuration.cs index 2d65b40..1c513a6 100644 --- a/TimberWinR/Configuration.cs +++ b/TimberWinR/Configuration.cs @@ -13,6 +13,16 @@ namespace TimberWinR public class Configuration { + private class MissingRequiredAttributeException : Exception + { + public MissingRequiredAttributeException(XElement e, string attributeName) + : base( + string.Format("{0}:{1} Missing required attribute \"{2}\" for element <{3}>", e.Document.BaseUri, + ((IXmlLineInfo)e).LineNumber, attributeName, e.Name.ToString())) + { + } + } + private class InvalidAttributeNameException : Exception { public InvalidAttributeNameException(XAttribute a) @@ -53,21 +63,24 @@ namespace TimberWinR } } - private static List _events = new List(); - public IEnumerable Events { get { return _events; } } + private static List _events = new List(); + public IEnumerable Events { get { return _events; } } - private static List _logs = new List(); - public IEnumerable Logs { get { return _logs; } } + private static List _logs = new List(); + public IEnumerable Logs { get { return _logs; } } - private static List _iislogs = new List(); - public IEnumerable IIS { get { return _iislogs; } } + private static List _iislogs = new List(); + public IEnumerable IIS { get { return _iislogs; } } + + private static List _iisw3clogs = new List(); + public IEnumerable IISW3C { get { return _iisw3clogs; } } public Configuration(string xmlConfFile) { parseXMLConf(xmlConfFile); } - static List parseFields_Events(IEnumerable xml_fields) + static List parseFields_Event(IEnumerable xml_fields) { List fields = new List(); @@ -92,7 +105,19 @@ namespace TimberWinR foreach (XElement f in xml_fields) { - string name = f.Attribute("name").Value; + // Parse field name. + string name; + string attributeName = "name"; + try + { + name = f.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(f, attributeName); + } + + // Ensure field name is valid. if (allPossibleFields.ContainsKey(name)) { fields.Add(new FieldDefinition(name, allPossibleFields[name])); @@ -103,6 +128,7 @@ namespace TimberWinR } } + // If no fields are provided, default to all fields. if (fields.Count == 0) { foreach (KeyValuePair entry in allPossibleFields) @@ -114,7 +140,7 @@ namespace TimberWinR return fields; } - static List parseFields_Logs(IEnumerable xml_fields) + static List parseFields_Log(IEnumerable xml_fields) { List fields = new List(); @@ -127,7 +153,19 @@ namespace TimberWinR foreach (XElement f in xml_fields) { - string name = f.Attribute("name").Value; + // Parse field name. + string name; + string attributeName = "name"; + try + { + name = f.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(f, attributeName); + } + + // Ensure field name is valid. if (allPossibleFields.ContainsKey(name)) { fields.Add(new FieldDefinition(name, allPossibleFields[name])); @@ -138,6 +176,7 @@ namespace TimberWinR } } + // If no fields are provided, default to all fields. if (fields.Count == 0) { foreach (KeyValuePair entry in allPossibleFields) @@ -176,7 +215,19 @@ namespace TimberWinR foreach (XElement f in xml_fields) { - string name = f.Attribute("name").Value; + // Parse field name. + string name; + string attributeName = "name"; + try + { + name = f.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(f, attributeName); + } + + // Ensure field name is valid. if (allPossibleFields.ContainsKey(name)) { fields.Add(new FieldDefinition(name, allPossibleFields[name])); @@ -187,6 +238,7 @@ namespace TimberWinR } } + // If no fields are provided, default to all fields. if (fields.Count == 0) { foreach (KeyValuePair entry in allPossibleFields) @@ -198,9 +250,86 @@ namespace TimberWinR return fields; } - static Params_WindowsEvents parseParams_Events(IEnumerable attributes) + static List parseFields_IISW3C(IEnumerable xml_fields) { - Params_WindowsEvents.Builder p = new Params_WindowsEvents.Builder(); + List fields = new List(); + + Dictionary allPossibleFields = new Dictionary() + { + { "LogFilename", typeof(string) }, + { "LogRow", typeof(int) }, + { "date", typeof(DateTime) }, + { "time", typeof(DateTime) }, + { "c-ip", typeof(string) }, + { "cs-username", typeof(string) }, + { "s-sitename", typeof(string) }, + { "s-computername", typeof(int) }, + { "s-ip", typeof(string) }, + { "s-port", typeof(int) }, + { "cs-method", typeof(string) }, + { "cs-uri-stem", typeof(string) }, + { "cs-uri-query", typeof(string) }, + { "sc-status", typeof(int) }, + { "sc-substatus", typeof(int) }, + { "sc-win32-status", typeof(int) }, + { "sc-bytes", typeof(int) }, + { "cs-bytes", typeof(int) }, + { "time-taken", typeof(int) }, + { "cs-version", typeof(string) }, + { "cs-host", typeof(string) }, + { "cs (User-Agent)", typeof(string) }, + { "cs (Cookie)", typeof(string) }, + { "cs (Referer)", typeof(string) }, + { "s-event", typeof(string) }, + { "s-process-type", typeof(string) }, + { "s-user-time", typeof(double) }, + { "s-kernel-time", typeof(double) }, + { "s-page-faults", typeof(int) }, + { "s-total-procs", typeof(int) }, + { "s-active-procs", typeof(int) }, + { "s-stopped-procs", typeof(int) } + }; + + foreach (XElement f in xml_fields) + { + // Parse field name. + string name; + string attributeName = "name"; + try + { + name = f.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(f, attributeName); + } + + // Ensure field name is valid. + if (allPossibleFields.ContainsKey(name)) + { + fields.Add(new FieldDefinition(name, allPossibleFields[name])); + } + else + { + throw new InvalidAttributeValueException(f.Attribute("name")); + } + } + + // If no fields are provided, default to all fields. + if (fields.Count == 0) + { + foreach (KeyValuePair entry in allPossibleFields) + { + fields.Add(new FieldDefinition(entry.Key, entry.Value)); + } + } + + return fields; + } + + static Params_WindowsEvent parseParams_Event(IEnumerable attributes) + { + Params_WindowsEvent.Builder p = new Params_WindowsEvent.Builder(); foreach (XAttribute a in attributes) { @@ -311,9 +440,9 @@ namespace TimberWinR return p.Build(); } - static Params_TextLogs parseParams_Logs(IEnumerable attributes) + static Params_TextLog parseParams_Log(IEnumerable attributes) { - Params_TextLogs.Builder p = new Params_TextLogs.Builder(); + Params_TextLog.Builder p = new Params_TextLog.Builder(); foreach (XAttribute a in attributes) { @@ -371,9 +500,9 @@ namespace TimberWinR return p.Build(); } - static Params_IISLogs parseParams_IIS(IEnumerable attributes) + static Params_IISLog parseParams_IIS(IEnumerable attributes) { - Params_IISLogs.Builder p = new Params_IISLogs.Builder(); + Params_IISLog.Builder p = new Params_IISLog.Builder(); foreach (XAttribute a in attributes) { @@ -435,6 +564,109 @@ namespace TimberWinR return p.Build(); } + static Params_IISW3CLog parseParams_IISW3C(IEnumerable attributes) + { + Params_IISW3CLog.Builder p = new Params_IISW3CLog.Builder(); + + foreach (XAttribute a in attributes) + { + string val = a.Value; + int valInt; + + switch (a.Name.ToString()) + { + case "name": + break; + case "location": + break; + case "iCodepage": + if (int.TryParse(val, out valInt)) + { + p.WithICodepage(valInt); + } + else + { + throw new InvalidAttributeIntegerValueException(a); + } + break; + case "recurse": + if (int.TryParse(val, out valInt)) + { + p.WithRecurse(valInt); + } + else + { + throw new InvalidAttributeIntegerValueException(a); + } + break; + case "minDateMod": + DateTime dt; + if (DateTime.TryParseExact(val, + "yyyy-MM-dd hh:mm:ss", + CultureInfo.InvariantCulture, + DateTimeStyles.None, + out dt)) + { + p.WithMinDateMod(val); + } + else + { + throw new InvalidAttributeDateValueException(a); + } + break; + case "dQuotes": + if (val == "ON" || val == "true") + { + p.WithDQuotes(true); + } + else if (val == "OFF" || val == "false") + { + p.WithDQuotes(false); + } + else + { + throw new InvalidAttributeValueException(a); + } + break; + case "dirTime": + if (val == "ON" || val == "true") + { + p.WithDirTime(true); + } + else if (val == "OFF" || val == "false") + { + p.WithDirTime(false); + } + else + { + throw new InvalidAttributeValueException(a); + } + break; + case "consolidateLogs": + if (val == "ON" || val == "true") + { + p.WithConsolidateLogs(true); + } + else if (val == "OFF" || val == "false") + { + p.WithConsolidateLogs(false); + } + else + { + throw new InvalidAttributeValueException(a); + } + break; + case "iCheckpoint": + p.WithICheckpoint(val); + break; + default: + throw new InvalidAttributeNameException(a); + } + } + + return p.Build(); + } + static void parseXMLConf(string xmlConfFile) { XDocument config = XDocument.Load(xmlConfFile, LoadOptions.SetLineInfo | LoadOptions.SetBaseUri); @@ -450,16 +682,32 @@ namespace TimberWinR foreach (XElement e in xml_events) { - string source = e.Attribute("source").Value; + // Required attributes. + string source; + string attributeName; + + // Parse required attributes. + attributeName = "source"; + try + { + source = e.Attribute("source").Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + // Parse fields. IEnumerable xml_fields = from el in e.Descendants("Fields").Descendants("Field") select el; - List fields = parseFields_Events(xml_fields); + List fields = parseFields_Event(xml_fields); - Params_WindowsEvents args = parseParams_Events(e.Attributes()); + // Parse parameters. + Params_WindowsEvent args = parseParams_Event(e.Attributes()); - WindowsEvents evt = new WindowsEvents(source, fields, args); + WindowsEvent evt = new WindowsEvent(source, fields, args); _events.Add(evt); } @@ -472,17 +720,43 @@ namespace TimberWinR foreach (XElement e in xml_logs) { - string name = e.Attribute("name").Value; - string location = e.Attribute("location").Value; + // Required attributes. + string name; + string location; + string attributeName; + + // Parse required attributes. + attributeName = "name"; + try + { + name = e.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + attributeName = "location"; + try + { + location = e.Attribute("location").Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + // Parse fields. IEnumerable xml_fields = from el in e.Descendants("Fields").Descendants("Field") select el; - List fields = parseFields_Logs(xml_fields); + List fields = parseFields_Log(xml_fields); - Params_TextLogs args = parseParams_Logs(e.Attributes()); + // Parse parameters. + Params_TextLog args = parseParams_Log(e.Attributes()); - TextLogs log = new TextLogs(name, location, fields, args); + TextLog log = new TextLog(name, location, fields, args); _logs.Add(log); } @@ -494,26 +768,101 @@ namespace TimberWinR select el; foreach (XElement e in xml_iis) { - string name = e.Attribute("name").Value; - string location = e.Attribute("location").Value; + // Required attributes. + string name; + string location; + string attributeName; + + // Parse required attributes. + attributeName = "name"; + try + { + name = e.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + attributeName = "location"; + try + { + location = e.Attribute("location").Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + // Parse fields. IEnumerable xml_fields = from el in e.Descendants("Fields").Descendants("Field") select el; List fields = parseFields_IIS(xml_fields); - Params_IISLogs args = parseParams_IIS(e.Attributes()); + // Parse parameters. + Params_IISLog args = parseParams_IIS(e.Attributes()); - IISLogs iis = new IISLogs(name, location, fields, args); + IISLog iis = new IISLog(name, location, fields, args); _iislogs.Add(iis); } + + // IISW3C LOGS + IEnumerable xml_iisw3c = + from el in inputs.Descendants("IISW3CLogs").Descendants("IISW3CLog") + select el; + foreach (XElement e in xml_iis) + { + // Required attributes. + string name; + string location; + + string attributeName; + + // Parse required attributes. + attributeName = "name"; + try + { + name = e.Attribute(attributeName).Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + attributeName = "location"; + try + { + location = e.Attribute("location").Value; + } + catch (NullReferenceException) + { + throw new MissingRequiredAttributeException(e, attributeName); + } + + // Parse fields. + IEnumerable xml_fields = + from el in e.Descendants("Fields").Descendants("Field") + select el; + List fields = parseFields_IISW3C(xml_fields); + + // Parse parameters. + Params_IISW3CLog args = parseParams_IISW3C(e.Attributes()); + + + IISW3CLog iisw3c = new IISW3CLog(name, location, fields, args); + _iisw3clogs.Add(iisw3c); + } + + Console.WriteLine("end"); } - public class WindowsEvents + public class WindowsEvent { public string Source { get; private set; } public List Fields { get; private set; } @@ -529,7 +878,7 @@ namespace TimberWinR public string ICheckpoint { get; private set; } public string BinaryFormat { get; private set; } - public WindowsEvents(string source, List fields, Params_WindowsEvents args) + public WindowsEvent(string source, List fields, Params_WindowsEvent args) { Source = source; Fields = fields; @@ -569,7 +918,7 @@ namespace TimberWinR } } - public class TextLogs + public class TextLog { public string Name { get; private set; } public string Location { get; private set; } @@ -581,7 +930,7 @@ namespace TimberWinR public bool SplitLongLines { get; private set; } public string ICheckpoint { get; private set; } - public TextLogs(string name, string location, List fields, Params_TextLogs args) + public TextLog(string name, string location, List fields, Params_TextLog args) { Name = name; Location = location; @@ -614,7 +963,7 @@ namespace TimberWinR } } - public class IISLogs + public class IISLog { public string Name { get; private set; } public string Location { get; private set; } @@ -627,7 +976,7 @@ namespace TimberWinR public string Locale { get; private set; } public string ICheckpoint { get; private set; } - public IISLogs(string name, string location, List fields, Params_IISLogs args) + public IISLog(string name, string location, List fields, Params_IISLog args) { Name = name; Location = location; @@ -662,7 +1011,61 @@ namespace TimberWinR } } - public class Params_WindowsEvents + public class IISW3CLog + { + public string Name { get; private set; } + public string Location { get; private set; } + public List Fields { get; private set; } + + // Parameters + public int ICodepage { get; private set; } + public int Recurse { get; private set; } + public string MinDateMod { get; private set; } + public bool DQuotes { get; private set; } + public bool DirTime { get; private set; } + public bool ConsolidateLogs { get; private set; } + public string ICheckpoint { get; private set; } + + public IISW3CLog(string name, string location, List fields, Params_IISW3CLog args) + { + Name = name; + Location = location; + Fields = fields; + + ICodepage = args.ICodepage; + Recurse = args.Recurse; + MinDateMod = args.MinDateMod; + DQuotes = args.DQuotes; + DirTime = args.DirTime; + ConsolidateLogs = args.ConsolidateLogs; + ICheckpoint = args.ICheckpoint; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("TextLog\n"); + sb.Append(String.Format("Name: {0}\n", Name)); + sb.Append(String.Format("Location: {0}\n", Location)); + sb.Append("Fields:\n"); + foreach (FieldDefinition f in Fields) + { + sb.Append(String.Format("\t{0}\n", f.Name)); + } + sb.Append("Parameters:\n"); + sb.Append(String.Format("\tiCodepage: {0}\n", ICodepage)); + sb.Append(String.Format("\trecurse: {0}\n", Recurse)); + sb.Append(String.Format("\tminDateMod: {0}\n", MinDateMod)); + sb.Append(String.Format("\tdQuotes: {0}\n", DQuotes)); + sb.Append(String.Format("\tdirTime: {0}\n", DirTime)); + sb.Append(String.Format("\tconsolidateLogs: {0}\n", ConsolidateLogs)); + sb.Append(String.Format("\tiCheckpoint: {0}\n", ICheckpoint)); + + return sb.ToString(); + } + } + + public class Params_WindowsEvent { public bool FullText { get; private set; } public bool ResolveSIDS { get; private set; } @@ -741,9 +1144,9 @@ namespace TimberWinR return this; } - public Params_WindowsEvents Build() + public Params_WindowsEvent Build() { - return new Params_WindowsEvents() + return new Params_WindowsEvent() { FullText = fullText, ResolveSIDS = resolveSIDS, @@ -759,7 +1162,7 @@ namespace TimberWinR } } - public class Params_TextLogs + public class Params_TextLog { public int ICodepage { get; private set; } public int Recurse { get; private set; } @@ -798,9 +1201,9 @@ namespace TimberWinR return this; } - public Params_TextLogs Build() + public Params_TextLog Build() { - return new Params_TextLogs() + return new Params_TextLog() { ICodepage = iCodepage, Recurse = recurse, @@ -813,7 +1216,7 @@ namespace TimberWinR } - public class Params_IISLogs + public class Params_IISLog { public int ICodepage { get; private set; } public int Recurse { get; private set; } @@ -860,9 +1263,9 @@ namespace TimberWinR return this; } - public Params_IISLogs Build() + public Params_IISLog Build() { - return new Params_IISLogs() + return new Params_IISLog() { ICodepage = iCodepage, Recurse = recurse, @@ -874,5 +1277,84 @@ namespace TimberWinR } } + public class Params_IISW3CLog + { + public int ICodepage { get; private set; } + public int Recurse { get; private set; } + public string MinDateMod { get; private set; } + public bool DQuotes { get; private set; } + public bool DirTime { get; private set; } + public bool ConsolidateLogs { get; private set; } + public string ICheckpoint { get; private set; } + + public class Builder + { + // Default values for parameters. + private int iCodepage = -2; + private int recurse = 0; + private string minDateMod; + private bool dQuotes; + private bool dirTime; + private bool consolidateLogs; + private string iCheckpoint; + + public Builder WithICodepage(int value) + { + iCodepage = value; + return this; + } + + public Builder WithRecurse(int value) + { + recurse = value; + return this; + } + + public Builder WithMinDateMod(string value) + { + minDateMod = value; + return this; + } + + public Builder WithDQuotes(bool value) + { + dQuotes = value; + return this; + } + + public Builder WithDirTime(bool value) + { + dirTime = value; + return this; + } + + public Builder WithConsolidateLogs(bool value) + { + consolidateLogs = value; + return this; + } + + public Builder WithICheckpoint(string value) + { + iCheckpoint = value; + return this; + } + + public Params_IISW3CLog Build() + { + return new Params_IISW3CLog() + { + ICodepage = iCodepage, + Recurse = recurse, + MinDateMod = minDateMod, + DQuotes = dQuotes, + DirTime = dirTime, + ConsolidateLogs = consolidateLogs, + ICheckpoint = iCheckpoint + }; + } + } + } + } }