在 Azure Log Analytics 的查询中解析 IIS 日志

Parse IIS logs in Azure Log Analytics' Query

A​​zure Log Analytics(又名 OMS)使用 Kusto QL。我们将 IIS 日志从 docker 容器发送到 Log Analytics,我打算使用以下查询来解析条目:

ContainerLog
| extend fields  = split(LogEntry, ' ')
| extend appname = tostring(fields[16])
| extend path = tostring(fields[4])

这是我手动解析的 2 条不同的记录:

date       time     s-ip           cs-method  cs-uri-stem                     cs-uri-query     s-port   cs-username                c-ip           cs(User-Agent)                                                                  cs(Referer)                    sc-status  sc-substatus  sc-win32-status  time-taken   x-forwarded-for                  container-app
2019-11-29 17:37:49 ddd.dd.dd.ddd  GET        /ping.aspx                      -                80       -                          dd.dd.ddd.d    Go-http-client/1.1                                                              -                              200        0             0                12           dd.dd.ddd.d                      OurCustomValue  
2019-11-29 17:33:36 ddd.dd.dd.ddd  GET        /js/js_v4/jquery-functions.js   v=26.35.0.0      80       7vgnwjAzOsKcUpseaPykcQ--   dd.dd.ddd.d    Mozilla/5.0+(Windows+NT+10.0 +Win64 +x64 +rv:70.0)+Gecko/20100101+Firefox/70.0  https://site.domain.com/       200        0             0                14           dd.ddd.dd.dd:55001,+dd.dd.ddd.d  OurCustomValue  

问题是 "User Agent" 字段可能包含 space,这会混淆解析器并将其拆分为其他字段。因此,User-Agent 之后列出的字段的所有索引都将关闭。例如,第二条记录的最后一个字段不会位于索引 16(从 0 开始),而是 19。

是否有更好的方法来解析这些日志,例如,通过定义字段的数量或类型?

您可以尝试以下方向。

注意: 如果您实际上不需要区分 user_agentreferer 字段,那么您可以将它们都放在一个单个字段,这就是下面的示例所做的(如果您确实需要它们,您可以稍后在第一次调用 parse 之后应用特定的逻辑来解析该字段)

datatable(s:string)
[
    '2019-11-29 17:37:49 ddd.dd.dd.ddd GET /ping.aspx - 80 - dd.dd.ddd.d Go-http-client/1.1 - 200 0 0 12 dd.dd.ddd.d OurCustomValue', 
    '2019-11-29 17:33:36 ddd.dd.dd.ddd GET /js/js_v4/jquery-functions.js v=26.35.0.0 80 7vgnwjAzOsKcUpseaPykcQ-- dd.dd.ddd.d Mozilla/5.0+(Windows+NT+10.0 +Win64 +x64 +rv:70.0)+Gecko/20100101+Firefox/70.0  https://site.domain.com/ 200 0 0 14 dd.ddd.dd.dd:55001,+dd.dd.ddd.d OurCustomValue',
]
| parse s with d:datetime " " t:timespan " " s_ip " " cs_method " " cs_uri_stem " " cs_uri_query " " s_port:int " " cs_username " " c_ip " " cs_user_agent " " sc_status:int " " sc_substatus:int " " sc_win32_status:int " " time_taken:int " " x_forwarded_for " " container_app
| project appname = container_app, path = cs_uri_stem, browser_family = parse_user_agent(cs_user_agent, "browser").Browser.Family

这将输出:

| appname        | path                          | browser_family |
|----------------|-------------------------------|----------------|
| OurCustomValue | /ping.aspx                    | Go-http-client |
| OurCustomValue | /js/js_v4/jquery-functions.js | Firefox        |