CloudWatch Logs Insights 查询语法 - Amazon CloudWatch Logs
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

CloudWatch Logs Insights 查询语法

CloudWatch Logs Insights 支持您用来对日志组执行查询的查询语言。查询语法支持不同的函数和运算,包括但不限于常规函数、算术和比较运算以及正则表达式。您可以创建包含多个查询命令的查询。使用 Unix 风格的管道字符 (|) 将查询中的查询命令分开。有关查询语法的更多信息,请参阅支持的运算和函数

CloudWatch Logs Insights 支持在查询中使用备注。CloudWatch Logs Insights 会忽略以哈希符号 (#) 开头的行。CloudWatch Logs Insights 会自动发现多种日志类型的字段,并生成以 @ 符号开头的字段。有关 CloudWatch Logs 自动生成的字段的更多信息,请参阅 Amazon CloudWatch 用户指南中的支持的日志和搜索到的字段

CloudWatch Logs Insights 查询命令

下表列出了 CloudWatch Logs Insights 支持的查询命令,并包含基本示例。有关常规查询和其他日志类型的查询示例,请参阅 Amazon CloudWatch Logs 用户指南中的 示例查询

命令 说明 示例

display

指定要在查询结果中显示的字段。如果您在查询中多次指定此命令,则仅使用您在最后一次的命令中指定的字段。

以下示例查询包含字段 @messageparse 命令从消息日志格式中提取值并创建临时字段 loggingTypeloggingMessage。查询只会筛选出将 ERROR 作为 loggingType 值的录入事件,并在结果中只显示这些事件的 loggingMessage

fields @message | parse @message "[*] *" as loggingType, loggingMessage | filter loggingType = "ERROR" | display loggingMessage

fields

从日志事件检索指定的字段,以供显示。

您可以使用字段命令中的函数和运算来修改要显示的字段值,并创建新字段以供在查询的其余部分中使用。

以下示例对于日志组中的所有日志事件显示字段 foo-baraction 以及 f3f4 之间差异的绝对值。

fields `foo-bar`, action, abs(f3-f4)

以下示例创建并显示一个临时字段 opStatus。每个日志条目的 opStatus 的值是 OperationStatusCode 字段的值的串联,这些值之间会使用一个连字符。

fields concat(Operation, '-', StatusCode) as opStatus

filter

根据一个或多个条件筛选查询的结果。filter 命令支持各种运算符和表达式。有关更多信息,请参阅 筛选命令中的匹配项和正则表达式

以下示例对 f1 字段中的值超过 2000 的所有录入事件,检索 f2f3duration 字段。

fields f1, f2, f3 | filter (duration>2000)

以下示例展示了类似查询,但查询结果不会显示单独的字段。反而,查询结果会针对持续时间超过 2000 的所有录入事件,显示 @timestamp 字段以及 @message 字段中的所有日志数据。

filter (duration>2000)

以下示例针对 f1 为 10 或 f3 大于 25 的所有录入事件检索 f1f2 字段。

fields f1, f2 | filter (f1=10 or f3>25)

以下示例返回字段 statusCode 包含介于 200 与 299 之间的值的录入事件。

fields f1 | filter statusCode like /2\d\d/

下一个示例返回字段 statusCode 不包含介于 200 与 299 之间的值的录入事件。

fields f1 | filter statusCode not like /2\d\d/

以下示例返回 statusCode 为 "300"、"400" 或 "500" 的录入事件。

fields @timestamp, @message | filter statusCode in [300,400,500]

最后一个示例返回 Type 字段中的值不为“foo”、“bar”或“1”的日志事件。

fields @timestamp, @message | filter Type not in ["foo","bar",1]

stats

使用日志字段值计算聚合统计数据。您可以将 bystats 命令一起使用来指定一个或多个条件。您可以使用条件将统计数据分组。

stats 命令支持以下运算符:sum()avg()count()min()max()

以下示例对 f2 的每个唯一值计算 f1 的平均值。

stats avg (f1) by f2

以下示例计算每小时的异常数量。

filter @message like /Exception/ | stats count(*) as exceptionCount by bin(1h) | sort exceptionCount desc

在示例中,as 将临时字段 exceptionCount 下消息中出现单词 "Exception" 的次数的总计数分组,by 将字段 bin(1h) 下的统计数据分组。

sort

对检索的日志事件排序。同时支持升序 (asc) 和降序 (desc)。

以下示例根据 f1 的值对返回的事件按降序排序,并显示字段 f1f2f3

fields f1, f2, f3 | sort f1 desc

limit

指定查询返回的日志事件数。

您可以使用此选项将结果限制为较少的数量,以查看一小部分相关结果。您还可以使用值为介于 1000 到 10000 之间数字的 limit,将控制台中显示的查询结果行数增加到超过默认值 1000 行的数量。

如果未指定限制,则查询默认为最多显示 1000 行。

以下示例根据 @timestamp 的值以降序对事件进行排序,并按排序顺序显示前 25 个事件的 f1f2 字段。在这种情况下,排序顺序是按最近的时间戳,因此会返回最新的 25 个事件。

sort @timestamp desc | limit 25 | display f1, f2

parse

从日志字段提取数据,并创建一个或多个您可以在查询中进一步处理的临时字段。

parse 命令支持 glob 表达式和正则表达式。

对于 glob 表达式,请将常量字符串(用单引号或双引号括起来的字符)与 parse 命令配合使用。使用星号 (*) 替换变量文本。星号起到通配符的作用。在星号之后使用关键字 as 将通配符值提取到临时字段中,并为它们提供一个别名。

在正则表达式两旁加上正斜杠 (/)。在该表达式中,要提取的匹配字符串的每段均包含在一个命名的捕获组中。(?<name>.*) 是一个命名的捕获组示例,其中 name 为名称,.* 为模式。

使用此单个日志行作为示例:

25 May 2019 10:24:39,474 [ERROR] {foo=2, bar=data} The error was: DataIntegrityException

以下两个 parse 表达式各自执行以下操作:创建临时字段 levelconfigexceptionlevel 具有值 ERRORconfig 具有值 {foo=2, bar=data},而 exception 具有值 DataIntegrityException。第一个示例使用 glob 表达式,第二个表达式使用正则表达式。

parse @message "[*] * The error was: *" as level, config, exception
parse @message /\[(?<level>\S+)\]\s+(?<config>\{.*\})\s+The error was: (?<exception>\S+)/

使用此单个日志行作为示例:

25 May 2019 10:24:39,474 user=user1234, method=sampleMehod, latency := 216

以下示例使用正则表达式从日志字段 @message 提取临时字段 user2method2latency2,并针对 method2user2 的每个唯一组合返回平均延迟。

parse @message /user=(?<user2>.*?), method:(?<method2>.*?), latency := (?<latency2>.*?)/ | stats avg(latency2) by method2, user2

使用查询命令的指南

您必须将查询中命名的日志字段(包括除 @ 符号、句点 (.) 和非字母数字字符以外的字符)括在反引号键 (`) 中。例如,必须将日志字段 foo-bar 括在反引号键 (`foo-bar`) 中,因为它包含连字符 (-),它是非字母数字字符。

可以使用 display 命令显示要在查询结果中看到的一个或多个字段。display 命令仅会显示您指定的文件。如果您的查询包含多个 display 命令,则查询结果仅会显示您在最终 display 命令中指定的一个或多个字段。

您可以将 fields 命令与关键字 as 配合使用,以创建使用您的录入事件中的字段和函数的临时字段。例如,fields ispresent as isRes 将创建一个名为 isRes 的临时字段,并且该临时字段可在查询的其余部分中使用。

isRes 的值等于 0 或 1,具体取决于 resolverArn 是否是发现的字段。如果您的查询包含多个 fields 命令,且不包括 display 命令,则会显示在 fields 命令中指定的所有字段。

筛选命令中的匹配项和正则表达式

筛选条件支持使用正则表达式。您可以使用以下比较运算符(=!=<<=>>=)和布尔运算符(andornot)。

注意

我们假定您熟悉正则表达式。CloudWatch Logs Insights 支持 Hyperscan,这是一个多正则表达式匹配库。有关 Hyperscan 的更多信息,请参阅 Hyperscan 网站

您可以使用关键字 in 来测试集合成员资格并检查数组中的元素。要检查数组中的元素,请将该数组放在 in 之后。您可以将布尔运算符 notin 配合使用。您可以创建查询,它们使用 in 返回字段是字符串匹配项的录入事件。这些字段必须是完整字符串。例如,下面的代码片段显示了一个查询,它使用 in 返回字段 logGroup 是完整字符串 example_group 的录入事件。

fields @timestamp, @message | filter logGroup in ["example_group"]

您可以使用关键字短语 likenot like 以匹配子字符串。您可以使用正则表达式运算符 =~ 以匹配子字符串。要使用 likenot like 匹配子字符串,请将您要匹配的子字符串括在单引号或双引号中。您可以将正则表达式模式与 likenot like 配合使用。要使用正则表达式运算符匹配子字符串,请将您要匹配的子字符串括在正斜杠中。下面的示例包含多个代码片段,它们展示您如何能够使用 filter 命令匹配子字符串。

示例:匹配子字符串

以下示例将返回 f1 包含单词 Exception 的录入事件。所有三个示例都区分大小写。

第一个示例使用 like 匹配子字符串。

fields f1, f2, f3 | filter f1 like "Exception"

第二个示例使用 like 和正则表达式模式匹配子字符串。

fields f1, f2, f3 | filter f1 like /Exception/

最后一个示例使用正则表达式匹配子字符串。

fields f1, f2, f3 | filter f1 =~ /Exception/

示例:使用通配符匹配子字符串

您可以使用星号 (*) 作为正则表达式中的通配符来匹配子字符串。下面的示例将返回 f1 包含以字母 E 开头的单词的多个录入事件。此示例区分大小写。

fields f1, f2, f3 | filter f3 like /E*/
注意

您可以在星号之前放置一个句点 (.*),以创建一个返回尽可能多的匹配项的贪婪量词。

示例:从匹配项中排除子字符串

下面的示例将显示一个查询,它将返回 f1 不包含单词 Exception 的多个录入事件。此示例区分大小写。

fields f1, f2, f3 | filter f1 not like "Exception"

示例:使用不区分大小写的模式匹配子字符串

您可以使用 like 和正则表达式匹配不区分大小写的子字符串。在您要匹配的子字符串前放置以下参数 (?i)。下面的示例将显示一个查询,它将返回 f1 包含单词 Exceptionexception 的多个录入事件。

fields f1, f2, f3 | filter f1 like /(?i)Exception/

在查询中使用别名

您可以使用 as 在查询中创建一个或多个别名。fieldsstatssort 命令中支持别名。

您可以为日志字段以及运算和函数的结果创建别名。

示例

以下示例说明在查询命令中使用别名。

fields abs(myField) as AbsoluteValuemyField, myField2

myField 的绝对值返回为 AbsoluteValuemyField,还返回字段 myField2

stats avg(f1) as myAvgF1 | sort myAvgF1 desc

f1 值的平均值计算为 myAvgF1 并按该值的降序将它们返回。

在查询中使用注释

您可以在查询中使用 # 字符注释掉行。将忽略以 # 字符开头的行。这可用于记录您的查询或暂时对某个调用忽略复杂查询的一部分,而不删除该行。

在以下示例中,将忽略查询的第二行。

fields @timestamp, @message # | filter @message like /delay/ | limit 20

支持的运算和函数

此查询语言支持多种类型的运算和函数,如下面的表中所示。

比较运算

您可以在 filter 命令中使用比较运算并将其用作其他函数的参数。比较运算接受所有数据类型作为参数,并返回布尔值结果。

= != < <= > >=

布尔运算符

您可以使用布尔运算符 andornot。您只能在返回布尔值的函数中使用这些布尔运算符。

算术运算

您可以在 filterfields 命令中使用算术运算并将其用作其他函数的参数。算术运算接受数值数据类型作为参数并返回数值结果。

运算 说明

a + b

a - b

a * b

a / b

a ^ b

幂。2 ^ 3 返回 8

a % b

余额或模数。10 % 3 返回 1

数值运算

您可以在 filterfields 命令中使用数值运算并将其用作其他函数的参数。数值运算接受数值数据类型作为参数并返回数值结果。

运算 结果类型 说明

abs(a: number)

number

绝对值。

ceil(a: number)

number

舍入到上限(大于 a 的值的最小整数)。

floor(a: number)

number

舍入到下限(小于 a 的值的最大整数)。

greatest(a: number, ...numbers: number[])

number

返回最大值。

least(a: number, ...numbers: number[])

number

返回最小值。

log(a: number)

number

自然对数。

sqrt(a: number)

number

平方根。

常规函数

您可以在 filterfields 命令中使用常规函数并将其用作其他函数的参数。

函数 结果类型 说明

ispresent(fieldName: LogField)

布尔值

如果字段存在,则返回 true

coalesce(fieldName: LogField, ...fieldNames: LogField[])

LogField

返回列表中的第一个非 null 值。

字符串函数

您可以在 filterfields 命令中使用字符串函数并将其用作其他函数的参数。

函数 结果类型 说明

isempty(fieldName: string)

数字

如果字段缺失或为空字符串,则返回 1

isblank(fieldName: string)

数字

如果字段缺失或为空字符串,或只包含空格,则返回 1

concat(str: string, ...strings: string[])

字符串

连结字符串。

ltrim(str: string)

ltrim(str: string, trimChars: string)

字符串

如果函数没有第二个参数,它将删除字符串左侧的空格。如果函数有第二个字符串参数,它将不会删除空格。相反,它会从 str 左侧删除 trimChars 中的字符。例如,ltrim("xyZxyfooxyZ","xyZ") 将返回 "fooxyZ"

rtrim(str: string)

rtrim(str: string, trimChars: string)

字符串

如果函数没有第二个参数,它将删除字符串右侧的空格。如果函数有第二个字符串参数,它将不会删除空格。相反,它会从 str 右侧删除 trimChars 字符。例如,rtrim("xyZfooxyxyZ","xyZ") 将返回 "xyZfoo"

trim(str: string)

trim(str: string, trimChars: string)

字符串

如果函数没有第二个参数,它将删除字符串两端的空格。如果函数有第二个字符串参数,它将不会删除空格。相反,它会从 str 两端删除 trimChars 字符。例如,trim("xyZxyfooxyxyZ","xyZ") 将返回 "foo"

strlen(str: string)

number

返回 Unicode 代码点中字符串的长度。

toupper(str: string)

字符串

将字符串转换为大写。

tolower(str: string)

字符串

将字符串转换为小写。

substr(str: string, startIndex: number)

substr(str: string, startIndex: number, length: number)

字符串

返回从由数值参数指定的索引到字符串末尾的子字符串。如果该函数具有二个参数,它包含要检索的子字符串的长度。例如,substr("xyZfooxyZ",3, 3) 将返回 "foo"

replace(fieldName: string, searchValue: string, replaceValue: string)

字符串

fieldName: string 中出现的所有 searchValue 替换为 replaceValue

例如,函数 replace(logGroup,"smoke_test","Smoke") 搜索录入事件,其中字段 logGroup 包含字符串值 smoke_test,并使用字符串 Smoke 替换该值。

strcontains(str: string, searchValue: string)

number

如果 str 包含 searchValue,则返回 1,否则返回 0。

日期时间函数

您可以在 filterfields 命令中使用日期时间函数并将其用作其他函数的参数。您可以使用这些函数为使用聚合函数的查询创建时间存储桶。您也可以使用包括一个数字的时间段,m 表示分钟,h 表示小时。例如,10m 为 10 分钟,1h 为 1 小时。下表包含可在查询命令中使用的不同日期时间函数的列表。该表列出了每个函数的结果类型,并包含对每个函数的描述。

注意

在创建查询命令时,您可以使用时间间隔选择器选择要查询的时间段。例如,您可以设置 5 到 30 分钟的时间间隔;1、3 和 12 小时间隔;或者自定义时间范围。您还可以设置特定日期之间的时间段。有关如何运行查询命令的信息,请参阅《Amazon CloudWatch Logs 用户指南》中的教程:运行和修改示例查询

函数 结果类型 说明

bin(period: Period)

时间戳

@timestamp 的值四舍五入到指定的时间段,然后截断。例如,bin(5m)@timestamp 的值舍入为 5 分钟,然后截断。

datefloor(timestamp: Timestamp, period: Period)

时间戳

将时间戳截断到指定的时间段。例如,datefloor(@timestamp, 1h)@timestamp 的所有值截断至小时底部。

dateceil(timestamp: Timestamp, period: Period)

时间戳

将时间戳向上舍入到指定的时间段,然后截断。例如,dateceil(@timestamp, 1h)@timestamp 的所有值截断至小时顶部。

fromMillis(fieldName: number)

时间戳

将输入字段解释为自 Unix 纪元以来的毫秒数并将其转换为时间戳。

toMillis(fieldName: Timestamp)

number

将在命名字段中找到的时间戳转换为表示自 Unix 纪元以来毫秒数的数字。例如,toMillis(@timestamp) 将时间戳 2022-01-14T13:18:031.000-08:00 转换为 1642195111000

注意

目前,CloudWatch Logs Insights 不支持使用人类可读的时间戳筛选日志。

IP 地址函数

您可以在 filterfields 命令中使用 IP 地址字符串函数并将其用作其他函数的参数。

函数 结果类型 说明

isValidIp(fieldName: string)

布尔值

如果字段是有效的 IPv4 或 IPv6 地址,则返回 true

isValidIpV4(fieldName: string)

布尔值

如果字段是有效的 IPv4 地址,则返回 true

isValidIpV6(fieldName: string)

布尔值

如果字段是有效的 IPv6 地址,则返回 true

isIpInSubnet(fieldName: string, subnet: string)

布尔值

如果字段是指定的 v4 或 v6 子网中有效的 IPv4 或 IPv6 地址,则返回 true。指定子网时,请使用 CIDR 表示法,例如 192.0.2.0/242001:db8::/32

isIpv4InSubnet(fieldName: string, subnet: string)

布尔值

如果字段是指定的 v4 子网中有效的 IPv4 地址,则返回 true。指定子网时,请使用 CIDR 表示法,例如 192.0.2.0/24

isIpv6InSubnet(fieldName: string, subnet: string)

布尔值

如果字段是指定的 v6 子网中有效的 IPv6 地址,则返回 true。指定子网时,请使用 CIDR 表示法,例如 2001:db8::/32

统计聚合函数

您可以在 stats 命令中使用聚合函数并将其用作其他函数的参数。

函数 结果类型 说明

avg(fieldName: NumericLogField)

number

指定的字段中值的平均值。

count()

count(fieldName: LogField)

number

计算日志事件的数量。count()(或 count(*))对查询返回的所有事件进行计数,而 count(fieldName) 对包含所指定字段名称的所有记录进行计数。

count_distinct(fieldName: LogField)

number

返回字段的唯一值的数量。如果字段具有非常高的基数(包含许多唯一值),则 count_distinct 返回的值只是一个近似值。

max(fieldName: LogField)

LogFieldValue

所查询的日志中此日志字段的值的最大值。

min(fieldName: LogField)

LogFieldValue

所查询的日志中此日志字段的值的最小值。

pct(fieldName: LogFieldValue, percent: number)

LogFieldValue

百分位数指示某个值在数据集中的相对位置。例如,pct(@duration, 95) 返回 @duration 值,95% 的 @duration 值低于此值,5% 的值高于此值。

stddev(fieldName: NumericLogField)

number

指定的字段中值的标准偏差。

sum(fieldName: NumericLogField)

number

指定的字段中值的总和。

统计非聚合函数

您可以在 stats 命令中使用非聚合函数并将其用作其他函数的参数。

函数 结果类型 说明

earliest(fieldName: LogField)

LogField

从查询的日志中具有最早时间戳的日志事件返回 fieldName 的值。

latest(fieldName: LogField)

LogField

从查询的日志中具有最晚时间戳的日志事件返回 fieldName 的值。

sortsFirst(fieldName: LogField)

LogField

返回在查询的日志中排在第一位的 fieldName 的值。

sortsLast(fieldName: LogField)

LogField

返回在查询的日志中排在最后一位的 fieldName 的值。