I added a constructor for adding custom patterns by IEnumerable<(string, string)>, because I thought Stream is not neccessary in all the use cases
I noticed, that the default constructor loads custom patterns from a manifest file and added a comment, wether this is a good idea
While the PatternViolations list I added might be a quick fix for the silently ignores errors problem, I'm not sure, that this is a good design decision in the long term. I would think over an API redesign calling Grok statically with a fluent interface removing all logic from the constructor... Maybe there is also room for using async/await. Example see below (just an idea, maybe we should discuss that as soon as you have more time):
public class Grok
{
// I prefer IEnumberable over Dictionary because of thread safety
private IEnumerable<(string, string)> _patterns;
private Grok(string definition)
{
// ...
}
public static Grok Define(string definition)
{
EnsureDefintionIsValid(definition);
return new Grok(definition);
}
public Grok WithPatterns(IEnumerable<(string, string)> patterns)
{
var patternsArray = patterns.ToArray();
EnsurePatternsAreValid(patternsArray);
_patterns = patternsArray;
return this;
}
private void EnsurePatternsAreValid(IEnumerable<(string, string)> patterns)
{
// ...
}
private static void EnsureDefintionIsValid(string definition)
{
// ...
}
public bool TryMatch(string subject, out IEnumerable<GrokItem> matches)
{
matches = new List<GrokItem>();
// ...
return true;
}
}
try {
var matcher = Grok.Define("%{ZIPCODE:zipcode}:%{EMAILADDRESS:email}").WithPatterns(new[] {
("ZIPCODE", "[1-9]{1}[0-9]{2}\\s{0,1}[0-9]{3}"),
("FLOAT", "[+-]?([0-9]*[.,])?[0-9]+"),
});
if(matcher.TryMatch("122 001:Bob.Davis@microsoft.com", out var matches)) {
Console.WriteLine("Matches found: " + matches.Count);
} else {
Console.WriteLine("No matches found");
};
} catch(GrokDefinitionException e) {
Console.WriteLine("Invalid definition: " + e.Message);
} catch(GrokPatternException pe) {
Console.WriteLine("Invalid custom pattern: " + e.Message);
}
Hey there,
here is the PR you mentioned in #52.
Some notes:
IEnumerable<(string, string)>
, because I thoughtStream
is not neccessary in all the use casesPatternViolations
list I added might be a quick fix for the silently ignores errors problem, I'm not sure, that this is a good design decision in the long term. I would think over an API redesign callingGrok
statically with a fluent interface removing all logic from the constructor... Maybe there is also room for usingasync/await
. Example see below (just an idea, maybe we should discuss that as soon as you have more time):