diff --git a/TimberWinR.ServiceHost/sampleconf.xml b/TimberWinR.ServiceHost/sampleconf.xml index c5a5bee..b39ad12 100644 --- a/TimberWinR.ServiceHost/sampleconf.xml +++ b/TimberWinR.ServiceHost/sampleconf.xml @@ -17,10 +17,11 @@ - + MMM d HH:mm:ss MMM dd HH:mm:ss diff --git a/TimberWinR.UnitTests/Configuration.cs b/TimberWinR.UnitTests/Configuration.cs index 12cad81..1eb1a31 100644 --- a/TimberWinR.UnitTests/Configuration.cs +++ b/TimberWinR.UnitTests/Configuration.cs @@ -260,7 +260,7 @@ namespace TimberWinR.UnitTests Assert.AreEqual(iCodepage, log.ICodepage); Assert.AreEqual(recurse, log.Recurse); Assert.AreEqual(splitLongLines, log.SplitLongLines); - Assert.IsNull(log.ICheckpoint); + name = "Second Set"; location = @"C:\Logs2\*.log"; @@ -275,7 +275,6 @@ namespace TimberWinR.UnitTests Assert.AreEqual(iCodepage, log.ICodepage); Assert.AreEqual(recurse, log.Recurse); Assert.AreEqual(splitLongLines, log.SplitLongLines); - Assert.IsNull(log.ICheckpoint); name = "Third Set"; @@ -291,7 +290,6 @@ namespace TimberWinR.UnitTests Assert.AreEqual(iCodepage, log.ICodepage); Assert.AreEqual(recurse, log.Recurse); Assert.AreEqual(splitLongLines, log.SplitLongLines); - Assert.IsNull(log.ICheckpoint); } [Test] diff --git a/TimberWinR/Configuration.cs b/TimberWinR/Configuration.cs index ecb7865..0967081 100644 --- a/TimberWinR/Configuration.cs +++ b/TimberWinR/Configuration.cs @@ -58,8 +58,15 @@ namespace TimberWinR { validateWithSchema(xmlConfFile, Properties.Resources.configSchema); - parseConfInput(xmlConfFile); - parseConfFilter(xmlConfFile); + try + { + parseConfInput(xmlConfFile); + parseConfFilter(xmlConfFile); + } + catch(Exception ex) + { + LogManager.GetCurrentClassLogger().Error(ex); + } } private static void validateWithSchema(string xmlConfFile, string xsdSchema) @@ -69,8 +76,7 @@ namespace TimberWinR // Ensure that the xml configuration file provided obeys the xsd schema. XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add("", XmlReader.Create(new StringReader(xsdSchema))); - -#if false +#if true bool errorsFound = false; config.Validate(schemas, (o, e) => { @@ -115,55 +121,40 @@ namespace TimberWinR select el; string tagName = "Inputs"; - if (inputs.Count() == 0) - { + if (inputs.Count() == 0) throw new TimberWinR.ConfigurationErrors.MissingRequiredTagException(tagName); - } - + // WINDOWS EVENTS IEnumerable xml_events = from el in inputs.Elements("WindowsEvents").Elements("Event") select el; - foreach (XElement e in xml_events) - { - WindowsEvent.Parse(_events, e); - } - - + foreach (XElement e in xml_events) + WindowsEvent.Parse(_events, e); // TEXT LOGS IEnumerable xml_logs = from el in inputs.Elements("Logs").Elements("Log") select el; - foreach (XElement e in xml_logs) - { - TailFileInput.Parse(_logs, e); - } - - + foreach (XElement e in xml_logs) + TailFileInput.Parse(_logs, e); // IIS LOGS IEnumerable xml_iis = from el in inputs.Elements("IISLogs").Elements("IISLog") select el; - foreach (XElement e in xml_iis) - { - IISLog.Parse(_iislogs, e); - } - + foreach (XElement e in xml_iis) + IISLog.Parse(_iislogs, e); // IISW3C LOGS IEnumerable xml_iisw3c = from el in inputs.Elements("IISW3CLogs").Elements("IISW3CLog") select el; - foreach (XElement e in xml_iisw3c) - { - IISW3CLog.Parse(_iisw3clogs, e); - } + foreach (XElement e in xml_iisw3c) + IISW3CLog.Parse(_iisw3clogs, e); } static void parseConfFilter(string xmlConfFile) @@ -178,16 +169,20 @@ namespace TimberWinR { switch (e.Name.ToString()) { + case DateFilter.TagName: + DateFilter.Parse(_filters, e); + break; case GrokFilter.TagName: GrokFilter.Parse(_filters, e); break; case MutateFilter.TagName: MutateFilter.Parse(_filters, e); break; + default: + throw new Exception(string.Format("Unknown tag: {0}", e.Name.ToString())); + break; } } } - - } } \ No newline at end of file diff --git a/TimberWinR/Filters/DateFilter.cs b/TimberWinR/Filters/DateFilter.cs index 554fa08..f23cfcb 100644 --- a/TimberWinR/Filters/DateFilter.cs +++ b/TimberWinR/Filters/DateFilter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; +using System.Xml; using Newtonsoft.Json.Linq; using System.Xml.Linq; @@ -10,6 +11,8 @@ namespace TimberWinR.Filters { public class DateFilter : FilterBase { + public const string TagName = "Date"; + public string Field { get; private set; } public string Target { get; private set; } public bool ConvertToUTC { get; private set; } @@ -29,67 +32,13 @@ namespace TimberWinR.Filters { Patterns = new List(); - ParseField(parent); - ParseTarget(parent); - ParseConvertToUTC(parent); + Field = ParseStringAttribute(parent, "field"); + Target = ParseStringAttribute(parent, "target", Field); + ConvertToUTC = ParseBoolAttribute(parent, "convertToUTC", false); ParsePatterns(parent); } - private void ParseField(XElement parent) - { - string attributeName = "field"; - - try - { - XAttribute a = parent.Attribute(attributeName); - Field = a.Value; - } - catch - { - } - } - - private void ParseTarget(XElement parent) - { - string attributeName = "field"; - - try - { - XAttribute a = parent.Attribute(attributeName); - Field = a.Value; - } - catch - { - } - } - - private void ParseConvertToUTC(XElement parent) - { - string attributeName = "convertToUTC"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ON" || value == "true") - { - ConvertToUTC = true; - } - else if (value == "OFF" || value == "false") - { - ConvertToUTC = false; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - + private void ParsePatterns(XElement parent) { foreach (var e in parent.Elements("Pattern")) @@ -148,6 +97,5 @@ namespace TimberWinR.Filters else json[Target] = ts; } - } } diff --git a/TimberWinR/Filters/FilterBase.cs b/TimberWinR/Filters/FilterBase.cs index e9a8e42..46162f1 100644 --- a/TimberWinR/Filters/FilterBase.cs +++ b/TimberWinR/Filters/FilterBase.cs @@ -2,12 +2,45 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Xml.Linq; using Newtonsoft.Json.Linq; namespace TimberWinR.Filters { public abstract class FilterBase { - public abstract void Apply(JObject json); + public abstract void Apply(JObject json); + + protected static string ParseStringAttribute(XElement e, string attributeName, string defaultValue="") + { + string retValue = defaultValue; + XAttribute a = e.Attribute(attributeName); + if (a != null) + retValue = a.Value; + return retValue; + } + + protected static bool ParseBoolAttribute(XElement e, string attributeName, bool defaultValue) + { + bool retValue = defaultValue; + XAttribute a = e.Attribute(attributeName); + + if (a != null) + { + switch (a.Value) + { + case "ON": + case "true": + retValue = true; + break; + + case "OFF": + case "false": + retValue = false; + break; + } + } + return retValue; + } } } diff --git a/TimberWinR/Filters/GrokFilter.cs b/TimberWinR/Filters/GrokFilter.cs index e48574f..0c6c9c0 100644 --- a/TimberWinR/Filters/GrokFilter.cs +++ b/TimberWinR/Filters/GrokFilter.cs @@ -44,20 +44,9 @@ namespace TimberWinR.Filters private void ParseMatch(XElement parent) { XElement e = parent.Element("Match"); - - if (e != null) - { - string attributeName = "value"; - try - { - Match = e.Attribute(attributeName).Value; - } - catch - { - throw new TimberWinR.ConfigurationErrors.MissingRequiredAttributeException(e, attributeName); - } - } + Match = e.Attribute("value").Value; + Field = e.Attribute("field").Value; } private void ParseAddFields(XElement parent) @@ -177,7 +166,7 @@ namespace TimberWinR.Filters var namedCaptures = regex.MatchNamedCaptures(text); foreach (string fieldName in namedCaptures.Keys) { - AddOrModify(json, fieldName, namedCaptures[fieldName]); + AddOrModify(json, fieldName, namedCaptures[fieldName]); } } } diff --git a/TimberWinR/Inputs/InputBase.cs b/TimberWinR/Inputs/InputBase.cs index d1c52a9..3759ad8 100644 --- a/TimberWinR/Inputs/InputBase.cs +++ b/TimberWinR/Inputs/InputBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Xml.Linq; @@ -52,5 +53,96 @@ namespace TimberWinR.Inputs return fields; } + protected static string ParseRequiredStringAttribute(XElement e, string attributeName) + { + XAttribute a = e.Attribute(attributeName); + if (a != null) + return a.Value; + else + throw new TimberWinR.ConfigurationErrors.MissingRequiredAttributeException(e, attributeName); + } + + protected static string ParseStringAttribute(XElement e, string attributeName, string defaultValue = "") + { + string retValue = defaultValue; + XAttribute a = e.Attribute(attributeName); + if (a != null) + retValue = a.Value; + return retValue; + } + + protected static bool ParseRequiredBoolAttribute(XElement e, string attributeName) + { + XAttribute a = e.Attribute(attributeName); + if (a == null) + throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(e.Attribute(attributeName)); + + bool retValue = false; + switch (a.Value) + { + case "ON": + case "true": + return true; + + case "OFF": + case "false": + return false; + break; + + default: + throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(e.Attribute(attributeName)); + } + } + + protected static string ParseEnumAttribute(XElement e, string attributeName, IEnumerable values, string defaultValue) + { + XAttribute a = e.Attribute(attributeName); + + if (a != null) + { + string v = a.Value; + if (values.Contains(v)) + return v; + else + throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(e.Attribute(attributeName)); + } + return defaultValue; + } + + protected static int ParseIntAttribute(XElement e, string attributeName, int defaultValue) + { + XAttribute a = e.Attribute(attributeName); + if (a != null) + { + int valInt; + if (int.TryParse(a.Value, out valInt)) + return valInt; + else + throw new TimberWinR.ConfigurationErrors.InvalidAttributeIntegerValueException(a); + } + return defaultValue; + } + protected static bool ParseBoolAttribute(XElement e, string attributeName, bool defaultValue) + { + bool retValue = defaultValue; + XAttribute a = e.Attribute(attributeName); + + if (a != null) + { + switch (a.Value) + { + case "ON": + case "true": + retValue = true; + break; + + case "OFF": + case "false": + retValue = false; + break; + } + } + return retValue; + } } } diff --git a/TimberWinR/Inputs/TailFileInput.cs b/TimberWinR/Inputs/TailFileInput.cs index 5e62eca..700692e 100644 --- a/TimberWinR/Inputs/TailFileInput.cs +++ b/TimberWinR/Inputs/TailFileInput.cs @@ -14,8 +14,7 @@ namespace TimberWinR.Inputs // Parameters public int ICodepage { get; private set; } public int Recurse { get; private set; } - public bool SplitLongLines { get; private set; } - public string ICheckpoint { get; private set; } + public bool SplitLongLines { get; private set; } public static void Parse(List logs, XElement logElement) { @@ -29,139 +28,13 @@ namespace TimberWinR.Inputs public TailFileInput(XElement parent) { - ParseName(parent); - ParseLocation(parent); - - // Default values for parameters. - ICodepage = 0; - Recurse = 0; - SplitLongLines = false; - - ParseICodepage(parent); - ParseRecurse(parent); - ParseSplitLongLines(parent); - ParseICheckpoint(parent); - + Name = ParseRequiredStringAttribute(parent, "name"); + Location = ParseRequiredStringAttribute(parent, "location"); + ICodepage = ParseIntAttribute(parent, "iCodepage", 0); + Recurse = ParseIntAttribute(parent, "recurse", 0); + SplitLongLines = ParseBoolAttribute(parent, "splitLongLines", false); ParseFields(parent); - } - - private void ParseName(XElement parent) - { - string attributeName = "name"; - - try - { - XAttribute a = parent.Attribute(attributeName); - - Name = a.Value; - } - catch - { - throw new TimberWinR.ConfigurationErrors.MissingRequiredAttributeException(parent, attributeName); - } - } - - private void ParseLocation(XElement parent) - { - string attributeName = "location"; - - try - { - XAttribute a = parent.Attribute(attributeName); - - Location = a.Value; - } - catch - { - throw new TimberWinR.ConfigurationErrors.MissingRequiredAttributeException(parent, attributeName); - } - } - - private void ParseICodepage(XElement parent) - { - string attributeName = "iCodepage"; - int valInt; - - try - { - XAttribute a = parent.Attribute(attributeName); - - if (int.TryParse(a.Value, out valInt)) - { - ICodepage = valInt; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeIntegerValueException(a); - } - } - catch - { - } - } - - private void ParseRecurse(XElement parent) - { - string attributeName = "recurse"; - int valInt; - - try - { - XAttribute a = parent.Attribute(attributeName); - - if (int.TryParse(a.Value, out valInt)) - { - Recurse = valInt; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeIntegerValueException(a); - } - } - catch - { - } - } - - private void ParseSplitLongLines(XElement parent) - { - string attributeName = "splitLongLines"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ON" || value == "true") - { - SplitLongLines = true; - } - else if (value == "OFF" || value == "false") - { - SplitLongLines = false; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseICheckpoint(XElement parent) - { - string attributeName = "iCheckpoint"; - - try - { - XAttribute a = parent.Attribute(attributeName); - - ICheckpoint = a.Value; - } - catch { } - } + } private void ParseFields(XElement parent) { @@ -182,15 +55,12 @@ namespace TimberWinR.Inputs 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)); - } + 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("\tsplitLongLines: {0}\n", SplitLongLines)); - sb.Append(String.Format("\tiCheckpoint: {0}\n", ICheckpoint)); + sb.Append(String.Format("\tsplitLongLines: {0}\n", SplitLongLines)); return sb.ToString(); } diff --git a/TimberWinR/Inputs/WindowsEvent.cs b/TimberWinR/Inputs/WindowsEvent.cs index 1822823..d0f0c6f 100644 --- a/TimberWinR/Inputs/WindowsEvent.cs +++ b/TimberWinR/Inputs/WindowsEvent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using System.Xml.Linq; +using Microsoft.SqlServer.Server; namespace TimberWinR.Inputs { @@ -33,237 +34,18 @@ namespace TimberWinR.Inputs WindowsEvent(XElement parent) { - - ParseSource(parent); - - // Default values for parameters. - FullText = true; - ResolveSIDS = true; - FormatMsg = true; - MsgErrorMode = "MSG"; - FullEventCode = false; - Direction = "FW"; - StringsSep = "|"; - BinaryFormat = "PRINT"; - - ParseFullText(parent); - ParseResolveSIDS(parent); - ParseFormatMsg(parent); - ParseMsgErrorMode(parent); - ParseFullEventCode(parent); - ParseDirection(parent); - ParseStringsSep(parent); - ParseBinaryFormat(parent); - + Source = ParseRequiredStringAttribute(parent, "source"); + FullText = ParseBoolAttribute(parent, "fullText", true); + ResolveSIDS = ParseBoolAttribute(parent, "resolveSIDS", true); + FormatMsg = ParseBoolAttribute(parent, "formatMsg", true); + MsgErrorMode = ParseEnumAttribute(parent, "msgErrorMode", new string[] {"NULL", "ERROR", "MSG"}, "MSG"); + FullEventCode = ParseBoolAttribute(parent, "fullEventCode", false); ; + Direction = ParseEnumAttribute(parent, "direction", new string[] { "FW", "BW" }, "FW"); + StringsSep = ParseStringAttribute(parent, "stringsSep", "|"); + BinaryFormat = ParseEnumAttribute(parent, "binaryFormat", new string[] { "ASC", "PRINT", "HEX" }, "PRINT"); ParseFields(parent); } - - private void ParseSource(XElement parent) - { - string attributeName = "source"; - - try - { - XAttribute a = parent.Attribute(attributeName); - - Source = a.Value; - } - catch - { - throw new TimberWinR.ConfigurationErrors.MissingRequiredAttributeException(parent, attributeName); - } - } - - private void ParseFullText(XElement parent) - { - string attributeName = "fullText"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ON" || value == "true") - { - FullText = true; - } - else if (value == "OFF" || value == "false") - { - FullText = false; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseResolveSIDS(XElement parent) - { - string attributeName = "resolveSIDS"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ON" || value == "true") - { - ResolveSIDS = true; - } - else if (value == "OFF" || value == "false") - { - ResolveSIDS = false; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseFormatMsg(XElement parent) - { - string attributeName = "formatMsg"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ON" || value == "true") - { - FormatMsg = true; - } - else if (value == "OFF" || value == "false") - { - FormatMsg = false; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseMsgErrorMode(XElement parent) - { - string attributeName = "msgErrorMode"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "NULL" || value == "ERROR" || value == "MSG") - { - MsgErrorMode = value; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseFullEventCode(XElement parent) - { - string attributeName = "fullEventCode"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ON" || value == "true") - { - FullEventCode = true; - } - else if (value == "OFF" || value == "false") - { - FullEventCode = false; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseDirection(XElement parent) - { - string attributeName = "direction"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "FW" || value == "BW") - { - Direction = value; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - - private void ParseStringsSep(XElement parent) - { - string attributeName = "stringsSep"; - - try - { - XAttribute a = parent.Attribute(attributeName); - - StringsSep = a.Value; - } - catch { } - } - - private void ParseBinaryFormat(XElement parent) - { - string attributeName = "binaryFormat"; - string value; - - try - { - XAttribute a = parent.Attribute(attributeName); - - value = a.Value; - - if (value == "ASC" || value == "PRINT" || value == "HEX") - { - BinaryFormat = value; - } - else - { - throw new TimberWinR.ConfigurationErrors.InvalidAttributeValueException(parent.Attribute(attributeName)); - } - } - catch { } - } - + private void ParseFields(XElement parent) { Dictionary allPossibleFields = new Dictionary() diff --git a/TimberWinR/configSchema.xsd b/TimberWinR/configSchema.xsd index cd4bd01..9059af2 100644 --- a/TimberWinR/configSchema.xsd +++ b/TimberWinR/configSchema.xsd @@ -4,7 +4,8 @@ - + + @@ -247,56 +248,96 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +