Search code examples
regexelasticsearchlogstashlogstash-grokelk

Match version number parts in grok


I want to split a version string (e.g. 2.3.5) into three fields(major.minor.patch) using the grok filter.

What I tried:

%{NUMBER:major}.%{NUMBER:minor}.%{NUMBER:patch}

Result from Grok debugger: No Matches

enter image description here What I expected:

{
    major: 2,
    minor: 3,
    patch: 5
}

Solution

  • The parts of the version number are int values, hence, it makes sense to use INT rather than NUMBER that matches more than just integer values.

    Besides, the dot must be escaped to match a literal dot.

    Use

    %{INT:major}\.%{INT:minor}\.%{INT:patch}
    

    Test:

    enter image description here

    More details:

    The patterns are available in logstash repository:

    INT (?:[+-]?(?:[0-9]+))
    BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
    NUMBER (?:%{BASE10NUM})
    

    So, the pattern that results from ${NUMBER}... is

    (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))).(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))).(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
    

    and it does not match the input string because the (?>...) atomic group matches the dot as part of a float number and never gives it back since backtracking is disallowed into atomic group patterns.