I'm pulling in syslog ID 113019 from a Cisco ASA and it provides me with VPN disconnect information. However, the log entry does not tell me when the user originally connected. It provides the disconnect timestamp along with a duration. I want to calculate the connect timestamp by subtracting the disconnect time from duration. I am struggling to get the correct combination of eval commands to convert disconnect time and duration to epoch values to perform the subtraction.
Disconnect Time Format: Jun 11 19:06:03
Duration Time Format: 2d 4h:02m:25s
Assuming you have the disconnect time extracted as the event timestamp, and assuming you have the duration string extracted into a field called duration_string
, you can use something like this to pry the info from the string:
| stats count | eval _time = now() | eval duration_string = "2d 4h:02m:25s" | rex field=duration_string "(?<days>\d+)d (?<hours>\d+)h:(?<minutes>\d+)m:(?<seconds>\d+)s" | eval duration = ((days * 24 + hours) * 60 + minutes) * 60 + seconds | eval connect_time = _time - duration | fieldformat connect_time = strftime(connect_time, "%F %T") | table _time duration_string duration connect_time
Copy the entire search into an empty search box and run it.
Assuming you have the disconnect time extracted as the event timestamp, and assuming you have the duration string extracted into a field called duration_string
, you can use something like this to pry the info from the string:
| stats count | eval _time = now() | eval duration_string = "2d 4h:02m:25s" | rex field=duration_string "(?<days>\d+)d (?<hours>\d+)h:(?<minutes>\d+)m:(?<seconds>\d+)s" | eval duration = ((days * 24 + hours) * 60 + minutes) * 60 + seconds | eval connect_time = _time - duration | fieldformat connect_time = strftime(connect_time, "%F %T") | table _time duration_string duration connect_time
Copy the entire search into an empty search box and run it.
Try this:
... | rex field=duration_string "((?<days>\d+)d )?(?<hours>\d+)h:(?<minutes>\d+)m:(?<seconds>\d+)s" | eval duration = ((coalesce(days, 0) * 24 + hours) * 60 + minutes) * 60 + seconds | ...
You are seriously really good at this, that worked perfectly!
You could use the ?
quantifier in the regular expression to make the day part optional, and wrap the field days
as coalesce(days, 0)
in the calculation to deal with null values.
I can't give you a regex that works for all your variations because you didn't specify any variations.
Okay - Here are the variations I get. There are cases where the hours and days will have 1 digit or 2 digits. The minutes and seconds always have two digits.
Duration - 0h:10m:21s
Duration - 10h:18m:54s
Duration - 1d 9h:01m:19s
Duration - 7d 16h:13m:13s
This is only an example. Look at the query starting from rex
, that's where the generic part starts that can be applied to any duration string in that format.
Forgive my ignorance, that makes perfect sense now. The only remaining issue I have is not all durations end up in days (most don't). Could I run two separate evaluations (one for durations with days, one for durations without days) in the same query to cover both scenarios?
That did the trick! Thank you for that. Now, how can the "eval duration_string = "2d 4h:02m:25s" statement be fitted to encapsulate all the durations? With this query, it returns the single result since it's directly targeting one log entry that contains the duration of "2d 4h:02m:25s"
I do have the duration string extracted into a field called duration_string