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
{
major: 2,
minor: 3,
patch: 5
}
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:
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.