diff --git a/README.md b/README.md index f84fa38..f219839 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Cross platform .NET grok implementation as a NuGet package [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Marusyk/grok.net/blob/main/LICENSE) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/Marusyk/grok.net/blob/main/CONTRIBUTING.md) -[![NuGet version](https://badge.fury.io/nu/grok.net.svg)](https://badge.fury.io/nu/grok.net) +[![NuGet version](https://img.shields.io/nuget/v/grok.net.svg?logo=NuGet)](https://www.nuget.org/packages/grok.net) [![Nuget](https://img.shields.io/nuget/dt/grok.net.svg)](https://www.nuget.org/packages/Grok.Net) [![PowerShell Gallery Version](https://img.shields.io/powershellgallery/v/Grok)](https://www.powershellgallery.com/packages/Grok) [![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/Grok)](https://www.powershellgallery.com/packages/Grok) diff --git a/benchmark/ParseBenchmark.cs b/benchmark/ParseBenchmark.cs index 93f578e..5ce09ec 100644 --- a/benchmark/ParseBenchmark.cs +++ b/benchmark/ParseBenchmark.cs @@ -11,55 +11,53 @@ public class ParseBenchmark private static readonly Grok _grokCustom = new("%{ZIPCODE:zipcode}:%{EMAILADDRESS:email}"); [Benchmark] - public void Empty() + public GrokResult Empty() { - _ = _grokEmpty.Parse(""); + return _grokEmpty.Parse(""); } [Benchmark] - public void Custom() + public GrokResult Custom() { - _ = _grokCustom.Parse("06590:halil.i.kocaoz@gmail.com"); + return _grokCustom.Parse("06590:halil.i.kocaoz@gmail.com"); } [Benchmark] - public void Log() + public GrokResult Log() { - _ = _grokLog.Parse(@"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165 + return _grokLog.Parse(@"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165 06-21-19 21:00:13:589265;156;WARN;main;DECODED: 775233900043 EMPTY DISTANCE: --------"); } - [Params("DBG", "INF", "WARN", "ERR")] - public string LogLevel { get; set; } - [Benchmark] - public void LogWithParam() + public bool LogWithParam() { + const string logLevel = "INF"; GrokResult grokResult = _grokLog.Parse($@"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165 - 06-21-19 21:00:13:589265;156;{LogLevel};main;DECODED: 775233900043 EMPTY DISTANCE: --------"); + 06-21-19 21:00:13:589265;156;{logLevel};main;DECODED: 775233900043 EMPTY DISTANCE: --------"); - bool resut = (string)grokResult[0].Value == LogLevel; + return (string)grokResult[0].Value == logLevel; } [Benchmark] - public void EmptyLocal() + public GrokResult EmptyLocal() { Grok grokEmptyLocal = new Grok(""); - _ = grokEmptyLocal.Parse(""); + return grokEmptyLocal.Parse(""); } [Benchmark] - public void CustomLocal() + public GrokResult CustomLocal() { Grok grokCustomLocal = new Grok("%{ZIPCODE:zipcode}:%{EMAILADDRESS:email}"); - _ = grokCustomLocal.Parse("06590:halil.i.kocaoz@gmail.com"); + return grokCustomLocal.Parse("06590:halil.i.kocaoz@gmail.com"); } [Benchmark] - public void LogLocal() + public GrokResult LogLocal() { Grok grokLogLocal = new Grok("%{MONTHDAY:month}-%{MONTHDAY:day}-%{MONTHDAY:year} %{TIME:timestamp};%{WORD:id};%{LOGLEVEL:loglevel};%{WORD:func};%{GREEDYDATA:msg}"); - _ = grokLogLocal.Parse(@"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165 + return grokLogLocal.Parse(@"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165 06-21-19 21:00:13:589265;156;WARN;main;DECODED: 775233900043 EMPTY DISTANCE: --------"); } } diff --git a/src/Grok.Net.Tests/UnitTests.cs b/src/Grok.Net.Tests/UnitTests.cs index 4e6ec7b..855ec78 100644 --- a/src/Grok.Net.Tests/UnitTests.cs +++ b/src/Grok.Net.Tests/UnitTests.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.RegularExpressions; using GrokNet; +using PCRE; using Xunit; namespace GrokNetTests @@ -311,7 +311,7 @@ public void Parse_Multiline_String_As_A_Single_Line_With_Regex_Options_Specified // Arrange const string timeKeyword = "loggingTime"; const string messageKeyword = "message"; - const RegexOptions options = RegexOptions.Singleline; + const PcreOptions options = PcreOptions.Singleline; var multilineGrok = new Grok($"%{{TIMESTAMP_ISO8601:{timeKeyword}}} %{{GREEDYDATA:{messageKeyword}}}", options); @@ -338,7 +338,7 @@ Second line public void Load_Custom_Patterns_From_Stream_And_Parse_With_Regex_Options_Specified() { // Arrange - const RegexOptions options = RegexOptions.Singleline; + const PcreOptions options = PcreOptions.Singleline; const string zipcode = "122001"; const string email = "Bob.Davis@microsoft.com"; @@ -356,7 +356,7 @@ public void Load_Custom_Patterns_From_Stream_And_Parse_With_Regex_Options_Specif public void Load_Custom_Patterns_And_Parse_With_Regex_Options_Specified() { // Arrange - const RegexOptions options = RegexOptions.Singleline; + const PcreOptions options = PcreOptions.Singleline; const string zipcode = "122001"; var customPatterns = new Dictionary { diff --git a/src/Grok.Net/Grok.Net.csproj b/src/Grok.Net/Grok.Net.csproj index 9dfcead..84762d6 100644 --- a/src/Grok.Net/Grok.Net.csproj +++ b/src/Grok.Net/Grok.Net.csproj @@ -19,7 +19,7 @@ - 1.2.0 + 2.0.0 @@ -32,6 +32,7 @@ + diff --git a/src/Grok.Net/Grok.cs b/src/Grok.Net/Grok.cs index 404dd09..9df24d5 100644 --- a/src/Grok.Net/Grok.cs +++ b/src/Grok.Net/Grok.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Reflection; using System.Text; -using System.Text.RegularExpressions; +using PCRE; namespace GrokNet { @@ -13,14 +13,14 @@ public class Grok private readonly string _grokPattern; private readonly Dictionary _patterns; private readonly Dictionary _typeMaps; - private Regex _compiledRegex; + private PcreRegex _compiledRegex; private IReadOnlyList _patternGroupNames; - private const RegexOptions _defaultRegexOptions = RegexOptions.Compiled | RegexOptions.ExplicitCapture; - private readonly RegexOptions _regexOptions; + private const PcreOptions _defaultRegexOptions = PcreOptions.Compiled | PcreOptions.ExplicitCapture; + private readonly PcreOptions _regexOptions; - private static readonly Regex _grokRegex = new Regex("%{(\\w+):(\\w+)(?::\\w+)?}", RegexOptions.Compiled); - private static readonly Regex _grokRegexWithType = new Regex("%{(\\w+):(\\w+):(\\w+)?}", RegexOptions.Compiled); - private static readonly Regex _grokWithoutName = new Regex("%{(\\w+)}", RegexOptions.Compiled); + private static readonly PcreRegex _grokRegex = new PcreRegex("%{(\\w+):(\\w+)(?::\\w+)?}", PcreOptions.Compiled); + private static readonly PcreRegex _grokRegexWithType = new PcreRegex("%{(\\w+):(\\w+):(\\w+)?}", PcreOptions.Compiled); + private static readonly PcreRegex _grokWithoutName = new PcreRegex("%{(\\w+)}", PcreOptions.Compiled); /// /// Initializes a new instance of the class with the specified Grok pattern. @@ -41,7 +41,7 @@ public Grok(string grokPattern) /// /// The Grok pattern to use. /// Additional regex options. - public Grok(string grokPattern, RegexOptions regexOptions) + public Grok(string grokPattern, PcreOptions regexOptions) : this(grokPattern) { _regexOptions = _defaultRegexOptions | regexOptions; @@ -65,7 +65,7 @@ public Grok(string grokPattern, Stream customPatterns) /// The Grok pattern to use. /// A stream containing custom patterns. /// Additional regex options. - public Grok(string grokPattern, Stream customPatterns, RegexOptions regexOptions) + public Grok(string grokPattern, Stream customPatterns, PcreOptions regexOptions) : this(grokPattern, regexOptions) { LoadCustomPatterns(customPatterns); @@ -84,12 +84,12 @@ public Grok(string grokPattern, IDictionary customPatterns) /// /// Initialized a new instance of the class with specified Grok pattern, - /// custom patterns if necessary, and custom . + /// custom patterns if necessary, and custom . /// /// The Grok pattern to use. /// Custom patterns to add. /// Additional regex options. - public Grok(string grokPattern, IDictionary customPatterns, RegexOptions regexOptions) + public Grok(string grokPattern, IDictionary customPatterns, PcreOptions regexOptions) : this(grokPattern, regexOptions) { LoadCustomPatterns(customPatterns); @@ -109,7 +109,7 @@ public GrokResult Parse(string text) var grokItems = new List(); - foreach (Match match in _compiledRegex.Matches(text)) + foreach (PcreMatch match in _compiledRegex.Matches(text)) { foreach (string groupName in _patternGroupNames) { @@ -157,14 +157,14 @@ private void ParsePattern() pattern = newPattern; } while (!done); - _compiledRegex = new Regex(pattern, _regexOptions); - _patternGroupNames = _compiledRegex.GetGroupNames().ToList(); + _compiledRegex = new PcreRegex(pattern, _regexOptions); + _patternGroupNames = _compiledRegex.PatternInfo.GroupNames.ToList(); } private void ProcessTypeMappings(ref string pattern) { - MatchCollection matches = _grokRegexWithType.Matches(string.IsNullOrEmpty(pattern) ? _grokPattern : pattern); - foreach (Match match in matches) + IEnumerable matches = _grokRegexWithType.Matches(string.IsNullOrEmpty(pattern) ? _grokPattern : pattern); + foreach (PcreMatch match in matches) { _typeMaps.Add(match.Groups[2].Value, match.Groups[3].Value); } @@ -258,7 +258,7 @@ private static void EnsurePatternIsValid(string pattern) { try { - _ = Regex.Match("", pattern); + _ = PcreRegex.Match("", pattern); } catch (Exception e) { @@ -266,17 +266,17 @@ private static void EnsurePatternIsValid(string pattern) } } - private string ReplaceWithName(Match match) + private string ReplaceWithName(PcreMatch match) { - Group group1 = match.Groups[2]; - Group group2 = match.Groups[1]; + PcreGroup group1 = match.Groups[2]; + PcreGroup group2 = match.Groups[1]; return _patterns.TryGetValue(group2.Value, out var str) ? $"(?<{group1}>{str})" : $"(?<{group1}>)"; } - private string ReplaceWithoutName(Match match) + private string ReplaceWithoutName(PcreMatch match) { - Group group = match.Groups[1]; + PcreGroup group = match.Groups[1]; if (_patterns.TryGetValue(group.Value, out _)) {