Reputation: 9936
I think I'm looking for a negative lookbehind regex, but I can't figure out the syntax.
I want to match a word in a single message field, but only when the word is not preceded by certain other words. The word may appear multiple times in the same message field -- as long as it's stand-alone somewhere, it should match.
Specifically, we have an alert to watch the logs for timeouts, and one of the match criteria is when the word "timeout" is part of the logged message. The trouble is that the message field also contains the stack trace, and the logs also contain many error events which are not timeouts. The stack trace often includes the word timeout
as an argument to one or more methods for many different error conditions. These produce false positives (often, 50% of the alert results are not real timeouts). As arguments, they also specify the data type, such as TimeSpan timeout
or Int32 timeout
which is the type of multi-word "phrase" I'm trying to exclude/ignore.
These examples are slightly modified for simplicity.
An event that should match (the word "timeout" is stand-alone, even though it also exists as part of the unwanted "TimeSpan timeout" phrase later in the same message field):
Message: System.TimeoutException: The request channel timed out. Increase the timeout value.
StackTrace:
at System.ServiceModel.Request(Message message, TimeSpan timeout)
at ...(etc - many more lines of stacked calls)...
An example of log data that should not match, the word "timeout" doesn't exist stand-alone:
Message: System.EndpointNotFoundException: There was no endpoint listening at https://xxxxx.
StackTrace:
at System.ServiceModel.Pool.EstablishConnection(TimeSpan timeout)
at ...(etc)...
I thought this criteria would work, but it does not, it excludes real timeouts (like the first example) when those errors also have a stack trace with the TimeSpan timeout
argument:
"timeout" NOT "TimeSpan timeout"
After I started thinking about regex, I tried a query along these lines but it appears to still match the TimeSpan timeout
portions. I'm pretty new to Splunk and I've never used lookbehind regex so I suspect I just screwed up the details here. My thinking with the first "timeout" is to just quickly discard anything that doesn't mention "timeout" at all, then I thought the negative lookback regex would discard anything but events where "timeout" appears stand-alone:
index=foo "timed out" OR "timeout" | regex _raw="(?<!TimeSpan )timeout"
Edit: The regex by itself seems to be correct, see https://regex101.com/r/rZxkvm/1 ... so the problem is how I'm using it within a Splunk query.
(Please note I'm not interested in completely different criteria -- I realize in these examples I could search for something like *TimeoutException
which is a common-enough naming pattern, but we have some systems for which the approach I've described is the only way to reliably identify real timeout errors and exclude false-positives.)
Upvotes: 1
Views: 326
Reputation: 20737
If you're trying to detect the word "timeout" in the message body then this would do it:
^Message:.*:.*\btimeout\b
https://regex101.com/r/ORmGIh/1/
Upvotes: 1