diff --git a/src/Grok.Net.Tests/UnitTests.cs b/src/Grok.Net.Tests/UnitTests.cs index 855ec78..0c1c6b1 100644 --- a/src/Grok.Net.Tests/UnitTests.cs +++ b/src/Grok.Net.Tests/UnitTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using GrokNet; using PCRE; using Xunit; @@ -395,5 +396,33 @@ public void GrokResult_To_Dictionary() Assert.True(grokResult.ContainsKey("email")); Assert.True(grokResult.ContainsKey("comment")); } + + [Fact] + public void InvalidPattern_ThrowsException() + { + // Arrange + const string logs = @"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165 + 06-22-19 22:00:13:589265;156;WARN;main;DECODED: 775233900043 EMPTY DISTANCE: --------"; + + var sut = new Grok("%{MONTHDA:month}-%{MONTHDAY:day}-%{MONTHDAY:year} %{TIME:timestamp};%{WORD:id};%{LOGLEVEL:loglevel};%{WORD:func};%{GREEDYDATA:msg}"); + + // Act & Assert + FormatException exception = Assert.Throws(() => sut.Parse(logs)); + Assert.Contains("Invalid Grok pattern: Pattern 'MONTHDA' not found.", exception.Message); + } + + [Fact] + public void InvaidPattern_With_Custom_Patterns() + { + // Arrange + const string zipcode = "122001"; + const string email = "Bob.Davis@microsoft.com"; + + var sut = new Grok("%{ZIPCOD:zipcode}:%{EMAILADDRESS:email}", ReadCustomFile()); + + // Act & Assert + FormatException exception = Assert.Throws(() => sut.Parse($"{zipcode}:{email}")); + Assert.Contains("Invalid Grok pattern: Pattern 'ZIPCOD' not found.", exception.Message); + } } } diff --git a/src/Grok.Net/Grok.cs b/src/Grok.Net/Grok.cs index 9df24d5..cc02f5c 100644 --- a/src/Grok.Net/Grok.cs +++ b/src/Grok.Net/Grok.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -104,6 +104,7 @@ public GrokResult Parse(string text) { if (_compiledRegex == null) { + ValidateGrokPattern(); ParsePattern(); } @@ -286,5 +287,20 @@ private string ReplaceWithoutName(PcreMatch match) return "()"; } + + private void ValidateGrokPattern() + { + var grokPatternRegex = new PcreRegex("%\\{([^:}]+)(?::[^}]+)?(?::[^}]+)?\\}"); + IEnumerable matches = grokPatternRegex.Matches(_grokPattern); + + foreach (PcreMatch match in matches) + { + var patternName = match.Groups[1].Value; + if (!_patterns.ContainsKey(patternName)) + { + throw new FormatException($"Invalid Grok pattern: Pattern '{patternName}' not found."); + } + } + } } }