Given a table with columns "RawData" and "_ResourceId", which is the Azure ARM ID, I want to parse a string from a server log file like:
"09:08:52,198 INFO [web.org.perfmon4j.extras.jbossweb7.P....."
and pull parts of the string into my custom table for later analysis.
The Kusto KQL query in the Azure Log Analytics editor:
suggest_CL
| project dt = todatetime(extract("^([\\:0-9]+)\\,([0-9]+)", 1,
"09:08:52,198 INFO [web.org.perfmon4j.extras.jbossweb7.P")),
dtstr = extract("^([\\:0-9]+)\\,([0-9]+)", 1,
"09:08:52,198 INFO [web.org.perfmon4j.extras.jbossweb7.P"),
statictimestr = "09:09:52",
statictime = todatetime("09:09:52"),
_ResourceId, RawData
where suggest_CL
is the Custom Table
The dtstr
column shows that the regex works and returns the correct time value.
I include some test strings:
statictimestr = "09:09:52",
This is a simple time only string. The doc says it will use today's date if the date is not included.
statictime = todatetime("09:09:52"),
This is the above string converted to datetime
The output is
dt [UTC] | dtstr | statictimestr | statictime [UTC] |
---|---|---|---|
09:08:52 | 09:09:52 | 2023-06-15T09:09:52Z |
and the dt
column is empty, implying that the todatetime(...)
expression evaluated to null. The statictime
column is noted as [UTC]
, so the parsing of the time-only expression was successful for the string literal. Outputting isnull(todatetime(...))
shows true
.
The output of the extract(regex)
expression is NOT parsed correctly.
Another SO question answers by saying the format is incorrect. There seems to be more problem here than that, like a bug handling function expressions as an argument to todatetime()
. That possibility was expressed in the other question.
Any ideas?
todatetime()
has different implementations for constant values and for calculated values - not the same set of formats is supported in both. The official set of supported formats (for both) is documented here.
This is why for an unsupported format, it may work for you when you provide a constant value, but may not otherwise.
For unsuppported formats, one thing you could try is to parse the separate date parts using the parse
operator, then use the make_datetime()
function to create a datetime value out of them.
For example:
print input = "09:08:52,198 INFO [web.org.perfmon4j.extras.jbossweb7.P....."
| parse input with hours:int ":" minutes:int ":" seconds:double "," *
| extend dt = make_datetime(datetime_part("Year", now()), datetime_part("Month", now()), datetime_part("Day", now()), hours, minutes, seconds)