You can use
%{SYSLOG5424SD:logtime} ApiLogger.%{LOGLEVEL:loglevel}: (?<API>w+ w+ w+):s*%{GREEDYDATA:json_field}
Then, you can parse the json_field
with JSON filter.
If you want to play around with regex, you should remember that regex engine parses a string from left to right by default. If you want to capture several fields with one regular expression, you should make sure the regex engine can "walk" all the way from one part to another. If you know what patterns there are, what types of chars there are between the two, it is great. If not, you can only rely on a .*
(%{GREEDYDATA}
) or .*?
(%{DATA}
) patterns.
So, as an excercise, you might have a look at
%{SYSLOG5424SD:logtime} %{JAVACLASS:loglevel}: (?<API>w+ w+ w+):s*{"endpoint":"(?<endpoint>[^"]*)","http_method":"(?<http_method>[A-Z]++).*?"user_id":(?<user_id>[0-9]++).*?"user_type":(?<user_type>[0-9]++).*?"http_response_code":(?<http_response_code>[0-9]++).*?"response":"(?<response>.*)"
Check the ++
in [0-9]++
and .*?
patterns between each field. The ++
possessive quantifier make sure the engine does not retry matching with the pattern that is modified by the quantifier again if the subsequent patterns fail to match. The [0-9]++
grabs a sequence of digits and does not give them away and if the subsequent patterns fail, the whole match fails. .*?
simply matches any zero or more chars other than line break chars, as few as possible. The last .*
is greedy, because it must match as many chars other than line break chars as possible.
See the regex demo.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…