本文介绍在 Azure Monitor 日志中编写日志查询的基础知识,包括如何:
如果适用,本文提供了使用 Kusto 查询语言(KQL)和 Log Analytics 简单模式查询数据的示例。
注释
如果要从至少一个虚拟机收集数据,你可以在自己的环境中完成此练习。
所需的权限
例如,您必须具有 Microsoft.OperationalInsights/workspaces/query/*/read
权限才能访问您查询的 Log Analytics 工作区,该权限由 Log Analytics 读者内置角色 提供。
构建查询
查询可以从表名或 search
命令开始。 从表名开始是一个好主意,因为它定义了明确的查询范围。 它还提高了查询性能和结果的相关性。
注释
Azure Monitor 使用的 KQL 需区分大小写。 语言关键字通常采用小写形式。 在查询中使用表名或列名时,请确保使用正确的大小写,如架构窗格中所示。
基于表的查询
Azure Monitor 在表中组织日志数据,每个表由多个列组成。 所有表和列都显示在 Azure 门户中的 Log Analytics 中的架构窗格内。
选择一个你感兴趣的表格,然后看看其中的一些数据:
SecurityEvent
| take 10
上面的查询从 SecurityEvent
表返回 10 个结果(无特定顺序)。 这是浏览表的常用方法,有助于你了解其结构和内容。 让我们探讨它是如何建造的:
- 查询从表名
SecurityEvent
开始,表名定义了查询范围。 - 管道字符 (|) 用来分隔命令,第一个命令的输出是下一个命令的输入。 可以添加任意数目的管道元素。
- 管道之后是
take
运算符。 即使不添加| take 10
,也可运行查询。 该命令仍然有效,但最多可以返回 30,000 个结果。
搜索查询
搜索查询较为无序。 它们最适合查找在特定表的任何列中包含特定值的记录。
此查询会在 SecurityEvent
表中搜索包含“Cryptographic”一词的记录。在这些记录中,将返回并显示 10 条记录:
search in (SecurityEvent) "Cryptographic"
| take 10
如果你省略in (SecurityEvent)
部分并只运行search "Cryptographic"
,那么搜索将会遍历所有表。 此过程则会花费更长时间,而且效率更低。
重要
搜索查询通常比基于表的查询更慢,因为它们必须处理更多的数据。
限制结果
使用 take
运算符通过返回最多为指定数量的记录来查看记录的小样本。 例如:
SecurityEvent
| take 10
所选结果是任意的,并且不按特定顺序显示。 如果需要按特定顺序返回结果,请使用 sort
和 top
运算符。
对结果进行排序
本部分介绍了 sort
和 top
运算符及其参数 desc
和 asc
。 虽然 take
可用于获取一些记录,但不能按任何特定顺序选择或对结果进行排序。 要获取排序的视图,请使用 sort
和 top
。
排序
可以使用 sort
运算符 按指定的列对查询结果进行排序。 但 sort
不会限制查询返回的记录数。
例如,以下查询会返回 SecurityEvent
表的所有可用记录(最多可为 30,000 条记录),并按 TimeGenerated 列对其进行排序。
SecurityEvent
| sort by TimeGenerated
前面的查询可能会返回过多的结果。 此外,返回结果可能还需要一些时间。 此查询按 SecurityEvent
列将整个 TimeGenerated
表排序。 而 Analytics 门户仅限显示 30,000 条记录。 此方法不是最佳的。 获取最新记录的最佳方式是使用 top
运算符。
降序和升序
使用 desc
参数按降序对记录进行排序。 降序是用于 sort
和 top
的默认排序顺序,因此通常可以省略 desc
参数。
例如,以下两个查询返回的数据按 TimeGenerated 列按降序排序:
-
SecurityEvent | sort by TimeGenerated desc
-
SecurityEvent | sort by TimeGenerated
若要按升序排序,请指定 asc
。
顶部
使用 top
运算符在服务器端对整个表进行排序,然后仅返回排在前面的记录。
例如,以下查询会返回最新的 10 条记录:
SecurityEvent
| top 10 by TimeGenerated
输出如下所示:
筛选结果
要将查询结果限制为相关信息,最常用的方法是筛选。
要将筛选器添加到查询,请使用 where
运算符,后跟一个或多个条件。 例如,以下查询仅返回 SecurityEvent
条记录,其中 Level equals _8
:
SecurityEvent
| where Level == 8
编写筛选条件时,可使用以下表达式:
表达式 | DESCRIPTION | 示例: |
---|---|---|
== | 检查相等性 (区分大小写) |
Level == 8 |
=~ | 检查相等性 (不区分大小写) |
EventSourceName =~ "microsoft-windows-security-auditing" |
!=, <> | 检查不相等性 (两个表达式相同) |
Level != 4 |
and 、or |
需在条件之间使用 | Level == 16 or CommandLine != "" |
按多个条件进行筛选
若要按多个条件筛选,可使用以下方法之一:
使用 and
,如下所示:
SecurityEvent
| where Level == 8 and EventID == 4672
使用竖线逐个分隔多个 where
元素,如下所示:
SecurityEvent
| where Level == 8
| where EventID == 4672
注释
值可以是不同的类型,因此可能需要将其转换为正确的类型,以便进行比较。 例如,SecurityEvent Level
列的类型是 String,因此必须先将其强制转换为 int
或 long
等数字类型,然后才能对其使用数字运算符,如下所示:SecurityEvent | where toint(Level) >= 10
指定时间范围
可使用时间选取器或时间筛选器指定时间范围。
注释
如果在查询中包含时间范围,则时间选取器会自动更改为在查询中设置。 如果手动将时间选取器更改为其他值,Log Analytics 将应用两个时间范围中的较小值。
使用时间选择器
时间选取器显示在“运行”按钮的旁边,指示你只查询过去 24 小时的记录。 此默认时间范围应用于所有查询。 要获取仅过去一小时的记录,请选择“最后一小时”,然后重新运行查询。
向查询添加时间筛选器
还可以通过将时间筛选器添加到查询来定义自己的时间范围。
最好是紧接在表名后面添加时间筛选器:
SecurityEvent
| where TimeGenerated > ago(30m)
| where toint(Level) >= 10
在前面的时间筛选器中,ago(30m)
表示“30 分钟前”。此查询仅返回过去 30 分钟的记录(例如,表示为 30m)。 其他时间单位包括天(例如 2d)以及秒(例如 10s)。
在查询结果中包含或排除列
使用project
可以选择要包含在结果中的特定列:
SecurityEvent
| top 10 by TimeGenerated
| project TimeGenerated, Computer, Activity
上面的示例生成以下输出:
还可以使用project
来重命名列,并定义新列。 下一个示例使用 project
执行以下操作:
- 仅选择
Computer
和TimeGenerated
原始列。 - 将
Activity
列显示为EventDetails
。 - 创建名为
EventCode
的新列。substring()
函数用于仅获取Activity
字段中的前 4 个字符。
SecurityEvent
| top 10 by TimeGenerated
| project Computer, TimeGenerated, EventDetails=Activity, EventCode=substring(Activity, 0, 4)
定义和使用自定义字段
可使用 extend
来保留结果集中的所有原始列并定义其他列。 以下查询使用 extend
添加 EventCode
列。 此列可能不会显示在表结果的末尾。 需要展开记录的详细信息才能查看记录。
SecurityEvent
| top 10 by TimeGenerated
| extend EventCode=substring(Activity, 0, 4)
注释
在查询中使用 extend
运算符进行即席计算。 使用 引入时转换 在引入时转换或聚合数据,以便更高效的查询。
聚合和分组结果
聚合行组
使用 summarize
可以根据一个或多个列标识记录组,并向其应用聚合。 summarize
最常见的用途是 count
,可以返回每个组中的结果数。
以下查询检查过去一小时的所有 Perf
记录,按 ObjectName
将其分组,然后统计每个组中的记录数:
Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName
将多个列中的唯一值组合进行分组
有时,按多个维度定义组会很有利。 这些值的每个唯一组合定义了一个单独的组:
Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName, CounterName
执行数学或统计计算
另一个常见用途是对每个组执行数学或统计计算。 以下示例计算每台计算机的平均 CounterValue
:
Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer
遗憾的是,此查询的结果没有意义,因为我们混合了不同的性能计数器。 若要使结果更有意义,可分别计算每个 CounterName
和 Computer
组合的平均值 :
Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer, CounterName
按时间列汇总
此外,可基于时间列或其他连续值对结果进行分组。 不过,只汇总 by TimeGenerated
会针对时间范围内的每一毫秒创建组,因为这些值是唯一的。
若要创建基于连续值的组,最好是使用 bin
将范围划分为可管理的单位。 以下查询分析 Perf
记录,这些记录度量特定计算机上的可用内存 (Available MBytes
)。 它计算过去 7 天中每 1 小时时段的平均值:
Perf
| where TimeGenerated > ago(7d)
| where Computer == "DC01.na.contosohotels.com"
| where CounterName == "Available MBytes"
| summarize avg(CounterValue) by bin(TimeGenerated, 1h)
若要使输出更清晰,可选择通过时间图表的形式显示一段时间内的可用内存。 为此,请切换到图表视图,打开右侧的图表格式边栏,然后在图表类型中选择折线:
常见问题
本部分提供常见问题的解答。
为什么我在 Azure Monitor 日志中看到了重复记录?
你偶尔可能会注意到 Azure Monitor 日志中存在重复记录。 这种重复通常起因于以下两种情况之一:
- 管道中的组件进行了重试,以确保在目标位置可靠地完成交付。 此功能偶尔会导致一小部分的遥测项出现重复。
- 如果重复记录来自虚拟机,则表明你可能同时安装了 Log Analytics 代理和 Azure Monitor 代理。 如果你仍然需要安装 Log Analytics 代理,请将 Log Analytics 工作区配置为不再收集那些也由 Azure Monitor 代理使用的数据收集规则收集的数据。
后续步骤
- 有关在日志查询中使用字符串数据的详细信息,请参阅在 Azure Monitor 日志查询中使用字符串。
- 有关如何联接多个表中的数据的信息,请参阅 Azure Monitor 日志查询中的联接。
- 请在 KQL 语言参考中获取有关完整 Kusto 查询语言的文档。