

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# CloudWatch 日志见解查询语言（Logs Insights QL）
<a name="CWL_AnalyzeLogData_LogsInsights"></a>

本节包括 Logs Insights QL 命令和函数的完整文档。它还包括此语言的示例查询。

有关您可以使用的其他查询语言的信息，请参阅[OpenSearch 服务 PPL](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_PPL.html)、[OpenSearch 服务 SQL](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_SQL.html) 和[CloudWatch Metrics Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/query_with_cloudwatch-metrics-insights.html)。

**Topics**
+ [CloudWatch 日志见解语言查询语法](CWL_QuerySyntax.md)
+ [开始使用 Logs Insights QL：查询教程](CWL_AnalyzeLogData_Tutorials.md)
+ [查询示例](CWL_QuerySyntax-examples.md)
+ [与之前的时间范围进行比较（差异）](CWL_AnalyzeLogData_Compare.md)
+ [在图形中可视化日志数据](CWL_Insights-Visualizing-Log-Data.md)

# CloudWatch 日志见解语言查询语法
<a name="CWL_QuerySyntax"></a>

 本节详细介绍 Logs Insights QL。查询语法支持不同的函数和运算，包括但不限于常规函数、算术和比较运算以及正则表达式。

**重要**  
为了避免因运行大型查询而产生过高的费用，请牢记以下最佳实践：  
仅为每个查询选择必要的日志组。
始终为查询指定尽可能窄的时间范围。
使用控制台运行查询时，请在关闭 L CloudWatch ogs Insights 控制台页面之前取消所有查询。否则，查询将继续运行直至完成。
向仪表板添加 CloudWatch Logs Insights 小组件时，请确保仪表板刷新频率不高，因为每次刷新都会启动一个新的查询。

要创建包含多个命令的查询，请使用竖线字符（**\$1**）分隔命令。

要创建包含注释的查询，请使用哈希字符（**\$1**）对注释进行分隔。

**注意**  
 CloudWatch Logs Insights 会自动发现不同日志类型的字段，并生成以 **@** 字符开头的字段。有关这些字段的更多信息，请参阅 *Amazon CloudWatch 用户指南*中的[支持的日志和发现的字段](https://docs.aws.amazon.com/en_us/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html)。

下表简要介绍了每个命令。下表对每条命令进行了更全面的描述，并附有示例。

**注意**  
标准日志类中的日志组支持所有 Logs Insights QL 查询命令。不频繁访问日志类中的日志组支持除 `pattern`、`diff` 和 `unmask` 之外的所有 Logs Insights QL 查询命令。


|  |  | 
| --- |--- |
| **` anomaly`**  | 使用机器学习识别日志数据中的异常模式。 | 
| **` display`**  |  在查询结果中显示一个或多个特定字段。 | 
| **` fields`**  |  在查询结果中显示多个特定字段，并支持函数和操作，可用于修改字段值和创建用于查询的新字段。 | 
| **` filter`**  |  筛选查询，以仅返回与一个或多个条件匹配的日志事件。 | 
| **` filterIndex`**  |  强制查询尝试仅扫描已在字段索引提及的字段上编制索引并且还包含该字段索引的值的日志组。这样可以减少扫描量，因为它只尝试扫描这些日志组中包含此字段索引的查询中指定的值的日志事件。 不频繁访问日志类中的日志组不支持此命令。 | 
| **` pattern`**  | 自动将您的日志数据划分为不同模式。模式是在日志字段中重复出现的共享文本结构。 CloudWatch Logs Insights 为您提供了分析日志事件中发现的模式的方法。有关更多信息，请参阅 [模式分析](CWL_AnalyzeLogData_Patterns.md)。 | 
| **` diff`**  | 将在您请求的时间段内找到的日志事件与之前相同长度的时间段内的日志事件进行比较，以便您可以查找趋势并确定某些日志事件是否是新的。  | 
| **` parse`**  |  从日志字段中提取数据，以创建可以在查询中处理的提取字段。**`parse`** 同时支持使用通配符和正则表达式的 glob 模式。 | 
| **` sort`**  | 按升序（`asc`）或降序（`desc`）顺序显示返回的日志事件。 | 
| **` SOURCE`**  | 在查询中包含 `SOURCE` 参数是一种根据日志组名称前缀、账户标识符和日志组类指定要包含在查询中的大量日志组的有用方法。只有在 AWS CLI 或中以编程方式创建查询时，才支持此命令，而不是在 CloudWatch 控制台中创建查询。 | 
| **` stats`**  |  使用日志字段值计算聚合统计数据。 | 
| **` limit`**  | 指定您希望查询返回的最大日志事件数。对于 **`sort`** 返回“前 20 个”或“最近 20 个”结果很有用。 | 
| **` dedup`**  |  根据您指定的字段中的特定值删除重复的结果。 | 
| **` unmask`**  |  显示由于数据保护策略而屏蔽部分内容的日志事件的所有内容。有关日志组中数据保护的更多信息，请参阅 [通过屏蔽帮助保护敏感的日志数据](mask-sensitive-log-data.md)。 | 
|   **`[unnest](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-Unnest.html)`**   |   对输入列表进行扁平化以生成多条记录，列表中的每个元素都有一条记录。  | 
| **` lookup`**  | 通过匹配字段值，使用查找表中的数据丰富日志事件。使用查找表将用户详细信息、应用程序名称或产品信息等参考数据添加到查询结果中。 | 
| **[其他操作和函数](CWL_QuerySyntax-operations-functions.md)**  | CloudWatch Logs Insights 还支持许多比较、算术、日期时间、数字、字符串、IP 地址以及常规函数和操作。 | 

以下各节提供了有关 L CloudWatch ogs Insights 查询命令的更多详细信息。

**Topics**
+ [日志类中支持的 Logs Insights QL 命令](CWL_AnalyzeLogData_Classes.md)
+ [异常](CWL_QuerySyntax-Anomaly.md)
+ [**display**](CWL_QuerySyntax-Display.md)
+ [fields](CWL_QuerySyntax-Fields.md)
+ [筛选](CWL_QuerySyntax-Filter.md)
+ [filterIndex](CWL_QuerySyntax-FilterIndex.md)
+ [SOURCE](CWL_QuerySyntax-Source.md)
+ [模式](CWL_QuerySyntax-Pattern.md)
+ [diff](CWL_QuerySyntax-Diff.md)
+ [parse](CWL_QuerySyntax-Parse.md)
+ [排序](CWL_QuerySyntax-Sort.md)
+ [stats](CWL_QuerySyntax-Stats.md)
+ [limit](CWL_QuerySyntax-Limit.md)
+ [dedup](CWL_QuerySyntax-Dedup.md)
+ [unmask](CWL_QuerySyntax-Unmask.md)
+ [unnest](CWL_QuerySyntax-Unnest.md)
+ [lookup](CWL_QuerySyntax-Lookup.md)
+ [布尔值、比较、数值、日期时间和其他函数](CWL_QuerySyntax-operations-functions.md)
+ [包含特殊字符的字段](CWL_QuerySyntax-Guidelines.md)
+ [在查询中使用别名和注释](CWL_QuerySyntax-alias.md)

# 日志类中支持的 Logs Insights QL 命令
<a name="CWL_AnalyzeLogData_Classes"></a>

标准日志类中的日志组支持所有 Logs Insights QL 查询命令。不频繁访问日志类中的日志组支持除 `pattern`、`diff`、`filterIndex` 和 `unmask` 之外的所有查询命令。

# 异常
<a name="CWL_QuerySyntax-Anomaly"></a>

 使用 `anomaly` 可以通过机器学习自动识别日志数据中的异常模式和潜在问题。

`anomaly` 命令扩展了现有 `pattern` 功能，并利用高级分析来帮助识别日志数据中的潜在异常。您可以使用 `anomaly` 自动在日志中发现异常模式或行为，从而减少识别和解决操作问题所需的时间。

`anomaly` 命令与 ` pattern` 命令配合使用，首先识别日志模式，然后检测这些模式中的异常。您也可以将 `anomaly` 与 ` filter` 或 ` sort` 命令结合使用，将异常检测集中在数据的特定子集上。

**anomaly 命令输入**

 `anomaly` 命令通常在 ` pattern` 命令之后使用，用于分析日志数据中发现的模式。该命令不需要额外的参数，它会分析查询中前面命令的输出。

**已识别的异常类型**

 `anomaly` 命令可识别五种不同类型的异常：
+ *模式频率异常*：特定日志模式的异常频率，例如当应用程序开始生成比平时更多的错误消息时。
+ *新模式异常*：以前未曾见过的日志模式，可能表明日志中出现了新的错误或消息类型。
+ *令牌变异异常*：日志消息内容的意外更改，可能表示预期日志格式存在异常变化。
+ *数字令牌异常*：日志中数值的异常变化，可以帮助检测潜在性能问题或意外的指标变化。
+ *HTTP 错误代码异常*：与 HTTP 错误响应相关的模式，在监视 Web 应用程序时特别有用。 APIs

**anomaly 命令输入**

 `anomaly` 命令会保留输入数据中的所有字段并添加异常检测结果，以帮助识别日志数据中的异常模式。

**示例**

以下命令可识别日志数据中的模式，然后检测这些模式中的异常：

```
fields @timestamp, @message
| pattern @message
| anomaly
```

`anomaly` 命令可以与筛选结合使用，以专注于特定的日志类型：

```
fields @timestamp, @message
| filter @type = "REPORT"
| pattern @message
| anomaly
```

`anomaly` 命令可以与排序结合使用以整理结果：

```
fields @timestamp, @message
| filter @type = "ERROR"
| pattern @message
| anomaly
| sort @timestamp desc
```

# **display**
<a name="CWL_QuerySyntax-Display"></a>

 使用 `display` 在查询结果中显示一个或多个特定字段。

 `display` 命令仅显示您指定的字段。如果您的查询包含多个 `display` 命令，则查询结果仅会显示您在最终 `display` 命令中指定的一个或多个字段。

 **示例：显示一个字段** 

 该代码片段显示了一个查询示例，其使用解析命令从 `@message` 提取数据以创建提取字段 `loggingType` 和 `loggingMessage`。该查询将返回 `loggingType` 的值为 **ERROR**（错误）的所有日志事件。`display` 在查询结果中仅显示 `loggingMessage` 的值。

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

**提示**  
 在查询中只使用 `display` 一次。如果您在查询中多次使用 `display`，则查询结果会显示在最后使用的 `display` 命令中指定的字段。

# fields
<a name="CWL_QuerySyntax-Fields"></a>

 使用 `fields` 在查询结果中显示特定字段。

如果您的查询包含多个 `fields` 命令，且不包括 `display` 命令，则会显示在 `fields` 命令中指定的所有字段。

 **示例：显示特定字段** 

 以下示例显示一个查询，将返回 20 个日志事件并按降序显示这些事件。查询结果将显示 `@timestamp` 和 `@message` 的值。

```
fields @timestamp, @message
| sort @timestamp desc
| limit 20
```

当您希望使用 `fields` 支持的不同函数和操作来修改字段值并创建可在查询中使用的新字段时，请使用 `fields` 而不是 `display`。

您可以将 `fields` 命令与关键字 *as* 配合使用，以创建使用您的日志事件中的字段和函数的提取字段。例如，`fields ispresent as isRes` 将创建一个名为 `isRes` 的提取字段，并且该提取字段可在查询的其余部分中使用。

# 筛选
<a name="CWL_QuerySyntax-Filter"></a>

 使用 `filter` 获取与一个或多个条件匹配的日志事件。

 **示例：使用一个条件筛选日志事件** 

 该代码片段显示了一个查询示例，其将返回 `range` 的值大于 ***3000*** 的所有日志事件。该查询将结果限制为 20 个日志事件，并按 `@timestamp` 和降序对日志事件进行排序。

```
fields @timestamp, @message
| filter (range>3000)
| sort @timestamp desc
| limit 20
```

 **示例：使用多个条件筛选日志事件** 

 您可以使用关键字 `and` 和 `or` 组合多个条件。

 该代码片段显示了一个查询示例，其将返回 `range` 的值大于 ***3000*** 以及 `accountId` 的值等于 ***123456789012*** 的日志事件。该查询将结果限制为 20 个日志事件，并按 `@timestamp` 和降序对日志事件进行排序。

```
fields @timestamp, @message
| filter (range>3000 and accountId=123456789012)
| sort @timestamp desc
| limit 20
```

## 索引字段和 filter 命令
<a name="CWL_QuerySyntax-index"></a>

如果已为日志组创建字段索引，则可以利用这些字段索引来提高 `filter` 查询的效率并减少扫描量。例如，假设您为 `requestId` 创建了一个字段索引。然后，针对该日志组的任何 CloudWatch Logs Insights 查询，如果这些查询包含`filter requestId = value`或`filter requestId IN [value, value, ...]`将尝试跳过处理已知不包含索引字段的日志事件。通过尝试仅扫描已知包含该索引字段的日志事件，可以减少扫描量，查询速度更快。

有关字段索引和如何创建它们的更多信息，请参阅[创建字段索引以提高查询性能并减少扫描量](CloudWatchLogs-Field-Indexing.md)。

**重要**  
只有包含 `filter fieldName =...` 和 `filter fieldName IN...` 的查询将受益于字段索引改进。包含 `filter fieldName like` 的查询不使用索引，并且始终扫描所选日志组中的所有日志事件。

**示例：使用索引查找与特定请求 ID 相关的日志事件** 

 此示例假设您已在 `requestId` 上创建了字段索引。对于使用此字段索引的日志组，查询将利用字段索引来尝试扫描最少量的日志事件，以查找 `requestId` 值为 `123456` 的事件 

```
fields @timestamp, @message
| filter requestId = "1234656"
| limit 20
```

## 筛选命令中的匹配项和正则表达式
<a name="CWL_QuerySyntax-regex"></a>

筛选条件支持使用正则表达式。您可以使用以下比较运算符（`=`、`!=`、`<`、`<=`、`>`、`>=`）和布尔运算符（`and`、`or` 和 `not`）。

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

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

您可以使用关键字短语 `like` 和 `not like` 以匹配子字符串。您可以使用正则表达式运算符 `=~` 以匹配子字符串。要使用 `like` 和 `not like` 匹配子字符串，请将您要匹配的子字符串括在单引号或双引号中。您可以将正则表达式模式与 `like` 和 `not 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` 的值以字符串 `ServiceLog` 开头的匹配项。

```
fields f1, f2, f3
| filter f1 like /ServiceLog./
```

 您可以在句点符号（`.*`）之后放置星号，以创建一个返回尽可能多的匹配项的贪婪量词。例如，以下查询将返回 `f1` 的值不仅以字符串 `ServiceLog` 开头并且还包括字符串 `ServiceLog` 的匹配项。

```
fields f1, f2, f3
| filter f1 like /ServiceLog.*/
```

 可能的匹配项可以采用以下格式：
+  `ServiceLogSampleApiLogGroup` 
+  `SampleApiLogGroupServiceLog` 

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

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

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

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

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

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

# filterIndex
<a name="CWL_QuerySyntax-FilterIndex"></a>

 使用 `filterIndex` 可以强制查询仅扫描在查询中指定的字段上编制索引的日志组，从而返回已编制索引的数据 对于已在此字段上编制索引的日志组，它会进一步优化查询，跳过没有任何日志事件包含索引字段的查询中指定的字段的日志组。这样可以进一步减少扫描量，因为它会尝试仅扫描这些日志组中与此字段索引的查询中指定的值匹配的日志事件。有关字段索引和如何创建它们的更多信息，请参阅[创建字段索引以提高查询性能并减少扫描量](CloudWatchLogs-Field-Indexing.md)。

将 `filterIndex` 与索引字段结合使用，可以通过将实际搜索空间限制为具有字段索引的日志组和日志事件来帮助您高效地查询包含 PB 级日志数据的日志组。

例如，假设您已经在自己账户的某些日志组中为 `IPaddress` 创建了字段索引。然后，您可以创建以下查询，并选择查询账户中的所有日志组，以查找 `IPaddress` 字段包含值 `198.51.100.0` 的日志事件。

```
fields @timestamp, @message
| filterIndex IPaddress = "198.51.100.0"
| limit 20
```

`filterIndex` 命令会使此查询尝试跳过所有未针对 `IPaddress` 编制索引的日志组。此外，在已编制索引的日志组中，查询会跳过具有 `IPaddress` 字段但未观察到该字段的值为 `198.51.100.0` 的日志事件。

使用 `IN` 运算符可以将结果扩展到索引字段的多个值中的任意一个。以下示例查找 `IPaddress` 字段包含值 `198.51.100.0` 或 `198.51.100.1` 的日志事件。

```
fields @timestamp, @message 
| filterIndex IPaddress in ["198.51.100.0", "198.51.100.1"]
| limit 20
```

CloudWatch 日志为标准日志类中的所有日志组提供默认字段索引。默认字段索引可自动用于以下字段：
+ `@logStream`
+ `@aws.region`
+ `@aws.account`
+ `@source.log`
+ `@data_source_name`
+ `@data_source_type`
+ `@data_format`
+ `traceId`
+ `severityText`
+ `attributes.session.id`

CloudWatch 日志还为某些数据源名称和类型组合提供默认字段索引。默认字段索引自动适用于以下数据源名称和类型组合：


| 数据源名称和类型 | 默认字段索引 | 
| --- | --- | 
|  `amazon_vpc.flow`  |  `action` `logStatus` `region` `flowDirection` `type`  | 
|  `amazon_route53.resolver_query`  |  `query_type` `transport` `rcode`  | 
|  `aws_waf.access`  |  `action` `httpRequest.country`  | 
|  `aws_cloudtrail.data` ` aws_cloudtrail.management`  |  `eventSource` `eventName` `awsRegion` `userAgent` `errorCode` `eventType` `managementEvent` `readOnly` `eventCategory` `requestId`  | 

默认字段索引是对您在策略中定义的任何自定义字段索引的补充。默认字段索引不计入[字段索引配额](CloudWatchLogs-Field-Indexing-Syntax.md)。

## filterIndex 与 filter 之比较
<a name="CWL_QuerySyntax-FilterIndex-Filter"></a>

为了说明 `filterIndex` 和 `filter` 之间的区别，请考虑以下示例查询。假设您已经为四个日志组的 `IPaddress` 创建了字段索引，但没有为第五个日志组创建。以下使用 `filterIndex` 的查询将跳过扫描未为该字段编制索引的日志组。对于每个已编制索引的日志组，它会尝试仅扫描具有索引字段的日志事件，并且仅返回创建字段索引之后的结果。

```
fields @timestamp, @message 
| filterIndex IPaddress = "198.51.100.0" 
| limit 20
```

相反，如果对相同的五个日志组使用 `filter` 而不是 `filterIndex` 进行查询，则查询不仅会尝试扫描已编制索引的日志组中包含该值的日志事件，还会扫描未编制索引的第五个日志组，并且会扫描该第五个日志组中的每个日志事件。

```
fields @timestamp, @message 
| filter IPaddress = "198.51.100.0" 
| limit 20
```

# SOURCE
<a name="CWL_QuerySyntax-Source"></a>

`SOURCE`在使用 AWS CLI 或 API 创建查询时，在查询中包含是指定要包含在查询中的日志组 and/or 数据源的有用方法。只有 AWS CLI 和 API 支持该`SOURCE`命令， CloudWatch 控制台不支持该命令。使用 CloudWatch控制台启动查询时，您可以使用控制台界面来指定日志组。

查询日志组

要使用 `SOURCE` 指定要查询的日志组，可以使用以下关键字：
+ `namePrefix` 会针对名称以您指定的字符串开头的日志组运行查询。如果省略它，则会查询所有日志组。

  列表中最多可以包含五个前缀。
+ `accountIdentifier`对指定 AWS 账户中的日志组运行查询。仅当您在监控账户中运行查询时，这才有效。如果省略此项，则默认为查询所有关联的源账户和当前的监控账户。有关跨账户可观察性的更多信息，请参阅[CloudWatch 跨](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html)账户可观察性。

  列表中最多可以包含 20 个账户标识符。
+ `logGroupClass` 会针对指定日志类（标准或不频繁访问）中的日志组运行查询。如果省略此项，则默认使用标准日志类。有关日志类的更多信息，请参阅 [日志类](CloudWatch_Logs_Log_Classes.md)。

由于您可以通过这种方式指定大量日志组进行查询，因此我们建议您仅在利用已创建的字段索引的查询中使用 `SOURCE`。有关为日志组中的字段编制索引的更多信息，请参阅[创建字段索引以提高查询性能并减少扫描量](CloudWatchLogs-Field-Indexing.md)

以下示例选择了账户中的所有日志组。如果这是一个监控账户，则会选择监控账户及其所有源账户中的所有日志组。如果日志组总数超过 10,000 个，则会显示一条错误消息，提示您使用其他日志组选择方法来减少日志组的数量。

```
SOURCE logGroups()
```

以下示例选择了 `111122223333` 源账户中的日志组。如果您在 CloudWatch 跨账户可观察性的监控账户中启动查询，则默认情况下会选择所有源账户和监控账户中的日志组。

```
SOURCE logGroups(accountIdentifiers:['111122223333'])
```

下一个示例根据名称前缀选择日志组。

```
SOURCE logGroups(namePrefix: ['namePrefix1', 'namePrefix2'])
```

以下示例选择了不频繁访问日志类中的所有日志组。如果不包含 `class` 标识符，则默认情况下，查询仅适用于标准日志类中的日志组。

```
SOURCE logGroups(class: ['INFREQUENT_ACCESS'])
```

下一个示例选择 111122223333 账户中以特定名称前缀开头且属于标准日志类的日志组。命令中未提及日志类，因为“标准”是默认的日志类值。

```
SOURCE logGroups(accountIdentifiers:['111122223333'], namePrefix: ['namePrefix1', 'namePrefix2']
```

最后一个示例显示了如何在`SOURCE`命令中使用该`start-query` AWS CLI 命令。

```
aws logs start-query 
--region us-east-1 
--start-time 1729728200 
--end-time 1729728215 
--query-string "SOURCE logGroups(namePrefix: ['Query']) | fields @message | limit 5"
```

查询数据来源

`SOURCE`要用于指定要查询的数据源，可以使用`dataSource`关键字。列表中最多可以包含十个数据源。

 以下示例选择`amazon_vpc.flow`数据源。

```
SOURCE dataSource(['amazon_vpc.flow'])
```

 以下示例选择`amazon_vpc.flow`数据源并根据日志组名称前缀限制日志组。

```
SOURCE dataSource(['amazon_vpc.flow']) logGroups(namePrefix: ['namePrefix1'])
```

# 模式
<a name="CWL_QuerySyntax-Pattern"></a>

 使用 `pattern` 自动将您的日志数据划分为不同模式。

模式是在日志字段中重复出现的共有的文本结构。您可以使用`pattern`来显示新出现的趋势、监控已知错误以及识别频繁发生或成本高昂的日志行。 CloudWatch Logs Insights 还提供了一种控制台体验，您可以使用它来查找和进一步分析日志事件中的模式。有关更多信息，请参阅 [模式分析](CWL_AnalyzeLogData_Patterns.md)。

由于 `pattern` 命令会自动识别常见模式，因此您可以将其用作搜索和分析日志的起点。您还可以将 `pattern` 与 ` filter`、` parse` 或 ` sort` 命令结合使用，在更精细的查询中识别模式。

**模式命令输入**

 `pattern` 命令需要以下输入之一：`@message` 字段、使用 ` parse` 命令创建的提取字段或使用一个或多个[字符串函数](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-operations-functions.html#CWL_QuerySyntax-string-functions)操作的字符串。

如 CloudWatch 果 Logs 无法推断出动态令牌所代表的数据类型，则将其显示为 <Token-*number* >，并*number*指明与其他动态令牌相比，该标记在模式中的显示位置。

动态令牌的常见示例包括错误代码、IP 地址、时间戳和请求 IDs。

**模式命令输出**

 `pattern` 命令将生成以下输出：
+ `@pattern`：在日志事件字段中重复出现的共有的文本结构。在模式内变化的字段（例如请求 ID 或时间戳）由*令牌*表示。如果 CloudWatch Logs 可以确定动态令牌所代表的数据类型，则它会将该令牌显示为`<string-number>`。*string*是对令牌所代表的数据类型的描述。*number*显示了与其他动态代币相比，该代币在模式中的显示位置。

  CloudWatch Logs 根据对包含该名称的日志事件内容的分析来分配名称的字符串部分。

  如 CloudWatch 果 Logs 无法推断出动态令牌所代表的数据类型，则将其显示为 <Token-*number* >，并*number*指明与其他动态令牌相比，该标记在模式中的显示位置。

  例如，`[INFO] Request time: <Time-1> ms` 是日志消息 `[INFO] Request time: 327 ms` 的潜在输出。
+ `@ratio`：选定时间段的日志事件与符合已确定模式的指定日志组的比率。例如，如果所选日志组和时间段中有一半的日志事件符合模式，则 `@ratio` 返回 `0.50`
+ `@sampleCount`：选定时间段的日志事件与符合已确定模式的指定日志组的数量。
+ `@severityLabel`：日志严重性或级别，表示日志中包含的信息类型。例如，`Error`、`Warning`、`Info` 或 `Debug`。

**示例**

以下命令识别选定时间范围内指定日志组中具有相似结构的日志，并按模式和计数对其进行分组

```
pattern @message
```

`pattern` 命令可以与 ` filter` 命令结合使用

```
filter @message like /ERROR/
| pattern @message
```

`pattern` 命令可以与 ` parse` 和 ` sort` 命令结合使用

```
filter @message like /ERROR/
| parse @message 'Failed to do: *' as cause
| pattern cause
| sort @sampleCount asc
```

# diff
<a name="CWL_QuerySyntax-Diff"></a>

将您请求的时间段内找到的日志事件与之前相同长度的时间段内的日志事件进行比较。这样，您就可以查找趋势并发现特定日志事件是否是新的。

在 `diff` 命令中添加修饰符以指定要比较的时间段：
+ `diff` 将当前选定时间范围内的日志事件与紧接在前的时间范围内的日志事件进行比较。
+ `diff previousDay` 将当前选定时间范围内的日志事件与前一天同一时间的日志事件进行比较。
+ `diff previousWeek` 将当前选定时间范围内的日志事件与前一周同一时间的日志事件进行比较。
+ `diff previousMonth` 将当前选定时间范围内的日志事件与上个月同一时间的日志事件进行比较。

有关更多信息，请参阅 [与之前的时间范围进行比较（差异）](CWL_AnalyzeLogData_Compare.md)。

# parse
<a name="CWL_QuerySyntax-Parse"></a>

 使用 `parse` 从日志字段中提取数据并创建可以在查询中处理的提取字段。**`parse`**  同时支持使用通配符和正则表达式的 glob 模式。有关正则表达式语法的信息，请参阅 [支持的正则表达式（regex）语法](FilterAndPatternSyntax.md#regex-expressions)。

 您可以使用正则表达式解析嵌套的 JSON 字段。

**示例：解析嵌套的 JSON 字段**

 该代码片段显示了如何解析在摄取过程中展平的 JSON 日志事件。

```
{'fieldsA': 'logs', 'fieldsB': [{'fA': 'a1'}, {'fA': 'a2'}]}
```

 该代码片段显示了一个带有正则表达式的查询，其将提取 `fieldsA` 和 `fieldsB` 的值以创建提取字段 `fld` 和 `array`。

```
parse @message "'fieldsA': '*', 'fieldsB': ['*']" as fld, array
```

**已命名的捕获组**

配合正则表达式一起使用 **`parse`** 时，可以使用已命名的捕获组将模式捕获到字段中。语法为 `parse @message (?<Name>pattern)`。

下面的示例使用 VPC 流日志上的一个捕获组将 ENI 提取到名为“`NetworkInterface`”的字段中。

```
parse @message /(?<NetworkInterface>eni-.*?) / | display NetworkInterface, @message
```

**注意**  
 JSON 日志事件在摄取过程中会被展平。目前，不支持使用 glob 表达式解析嵌套的 JSON 字段。您只能解析所含日志事件字段数不超过 200 的 JSON 日志事件。解析嵌套的 JSON 字段时，必须格式化查询中的正则表达式，使其与 JSON 日志事件的格式匹配。

## 解析命令的示例
<a name="CWL_QuerySyntax-parse-examples"></a>

**使用 glob 表达式来从日志字段 `@message` 提取字段 `@user`、`@method` 和 `@latency`，并对于 `@method` 和 `@user` 的每个唯一组合返回平均延迟。**

```
parse @message "user=*, method:*, latency := *" as @user,
    @method, @latency | stats avg(@latency) by @method,
    @user
```

**使用正则表达式从日志字段 `@message` 提取字段 `@user2`、`@method2` 和 `@latency2`，并对于 `@method2` 和 `@user2` 的每个唯一组合返回平均延迟。**

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

**提取字段 `loggingTime`、`loggingType` 和 `loggingMessage`，筛选出包含 `ERROR` 或 `INFO` 字符串的日志事件，然后仅显示包含 `ERROR` 字符串的事件的 `loggingMessage` 和 `loggingType` 字段。**

```
FIELDS @message
    | PARSE @message "* [*] *" as loggingTime, loggingType, loggingMessage
    | FILTER loggingType IN ["ERROR", "INFO"]
    | DISPLAY loggingMessage, loggingType = "ERROR" as isError
```

# 排序
<a name="CWL_QuerySyntax-Sort"></a>

 使用 `sort` 按指定字段依升序（`asc`）或降序（`desc`）顺序显示日志事件。您可以将其与 `limit` 命令一起使用，创建“前 N 个”或“后 N 个”查询。

该排序算法是自然排序的更新版本。如果按升序排序，则使用以下逻辑。
+  所有非数字值均位于所有数字值之前。*数字值*是仅包含数字的值，而不是数字和其他字符的混合。
+ 对于非数字值，该算法将连续的数字字符和连续的字母字符分组为单独的块进行比较。它按 Unicode 值对非数字部分进行排序，并首先按长度对数字部分进行排序，然后按其数值进行排序。

有关 Unicode 顺序的更多信息，请参阅 [List of Unicode characters](https://en.wikipedia.org/wiki/List_of_Unicode_characters)。

例如，以下是按升序排序的结果。

```
!:	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sorted by unicode order
#
*%04
0#	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Alphanumeric starting with numbers
5A
111A   >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Starts with more digits than 5A, so it sorted to be later than 5A
2345_
@	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2345 is compared with @ in the unicode order, 
@_
A	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Values starting with letters
A9876fghj
a12345hfh
0	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Number values
01
1
2
3
```

如果按降序进行排序，则排序结果是相反的。

例如，以下针对 Amazon VPC 流日志的查询会发现主机间的前 15 个数据包传输。

```
stats sum(packets) as packetsTransferred by srcAddr, dstAddr
    | sort packetsTransferred  desc
    | limit 15
```

# stats
<a name="CWL_QuerySyntax-Stats"></a>

 使用 `stats` 创建日志数据的可视化效果，例如条形图、折线图和堆叠面积图。这可以帮助您更有效地识别日志数据中的模式。 CloudWatch Logs Insights 为使用该`stats`函数和一个或多个聚合函数的查询生成可视化效果。

例如，Route 53 日志组中的以下查询返回按查询类型显示 Route 53 记录每小时分布的可视化结果。

```
stats count(*) by queryType, bin(1h)
```

所有此类查询都可以生成条形图。如果查询使用 `bin()` 函数，按一个字段对数据随时间的变化进行分组，您还可以查看折线图和堆叠面积图。

`bin` 函数支持以下时间单位和缩写。对于所有包含多个字符的单位和缩写，支持添加复数形式。这样，`hr` 和 `hrs` 都可以指定小时数。
+ `millisecond` `ms` `msec`
+ `second` `s` `sec`
+ `minute` `m` `min`
+ `hour` `h` `hr`
+ `day` `d` 
+ `week` `w` 
+ `month` `mo` `mon`
+ `quarter` `q` `qtr`
+ `year` `y` `yr`

**Topics**
+ [可视化时间序列数据](#CWL_Insights-Visualizing-TimeSeries)
+ [可视化按字段分组的日志数据](#CWL_Insights-Visualizing-ByFields)
+ [在单个查询中使用多个 stats 命令](#CWL_QuerySyntax-stats-multi)
+ [用于统计数据的函数](#CWL_QuerySyntax-stats-functions)

## 可视化时间序列数据
<a name="CWL_Insights-Visualizing-TimeSeries"></a>

时间序列可视化适用于具有以下特征的查询：
+ 此查询包含一个或多个聚合函数。有关更多信息，请参阅 [Aggregation Functions in the Stats Command](#CWL_Insights_Aggregation_Functions)。
+ 此查询使用 `bin()` 函数按一个字段对数据分组。

这些查询可以生成折线图、堆叠面积图、条形图和饼图。

**示例**

有关完整的教程，请参阅[教程：运行生成时间序列可视化的查询](CWL_AnalyzeLogData_VisualizationQuery.md)。

以下是更多适用于时间序列可视化的示例查询。

以下查询将生成 `myfield1` 字段的平均值的可视化（每 5 分钟创建一个数据点）。每个数据点都是前一个五分钟的日志中的 `myfield1` 值的平均值的聚合。

```
stats avg(myfield1) by bin(5m)
```

以下查询根据不同字段生成三个值的可视化（每 5 分钟创建一个数据点）。由于查询包含聚合函数并使用 `bin()` 作为分组字段，因此生成了可视化。

```
stats avg(myfield1), min(myfield2), max(myfield3) by bin(5m)
```

**折线图和堆叠面积图限制**

如果查询聚合日志条目信息但不使用 `bin()` 函数，则可以生成条形图。但是，这种查询无法生成折线图或堆叠面积图。有关这些查询类型的更多信息，请参阅[可视化按字段分组的日志数据](#CWL_Insights-Visualizing-ByFields)。

## 可视化按字段分组的日志数据
<a name="CWL_Insights-Visualizing-ByFields"></a>

您可以为使用 `stats` 函数以及一个或多个聚合函数的查询生成条形图。有关更多信息，请参阅 [Aggregation Functions in the Stats Command](#CWL_Insights_Aggregation_Functions)。

要查看可视化，请运行查询。接下来，选择 **Visualization（可视化）**选项卡，选择 **Line（折线图）**旁边的箭头，然后选择 **Bar（条形图）**。在条形图中，可视化限制为最多 100 个条形。

**示例**

有关完整的教程，请参阅[教程：运行生成按日志字段分组的可视化的查询](CWL_AnalyzeLogData_VisualizationFieldQuery.md)。以下部分包括更多适用于按字段可视化的示例查询。

以下 VPC 流日志查询针对每个目标地址，查找每个会话所传输的平均字节数。

```
stats avg(bytes) by dstAddr
```

您还可以生成每个结果值包含多个条形图的图表。例如，以下 VPC 流日志查询针对每个目标地址，查找每个会话所传输的平均字节数和最大字节数。

```
stats avg(bytes), max(bytes) by dstAddr
```

以下查询为每个查询类型查找 Amazon Route 53 查询日志的数量。

```
stats count(*) by queryType
```

## 在单个查询中使用多个 stats 命令
<a name="CWL_QuerySyntax-stats-multi"></a>

您可以在单个查询中使用多达两个 `stats` 命令。这可让您对第一个聚合的输出执行额外的聚合。

**示例：使用两个 `stats` 命令进行查询**

例如，以下查询首先查找 5 分钟条柱中的总流量，然后计算这些 5 分钟条柱中的最高、最低和平均流量。

```
FIELDS strlen(@message) AS message_length
| STATS sum(message_length)/1024/1024 as logs_mb BY bin(5m)
| STATS max(logs_mb) AS peak_ingest_mb, 
        min(logs_mb) AS min_ingest_mb, 
        avg(logs_mb) AS avg_ingest_mb
```

**示例：将多个 stats 命令与其他函数（例如 `filter`、`fields`、`bin`）结合**

您可以在单个查询中将两个 `stats` 命令与其他命令（例如 `filter` 和 `fields`）结合。例如，以下查询查找会话中不同 IP 地址的数量并按客户端平台查找会话数，筛选这些 IP 地址，最后找到每个客户端平台的会话请求平均值。

```
STATS count_distinct(client_ip) AS session_ips, 
      count(*) AS requests BY session_id, client_platform
| FILTER session_ips > 1
| STATS count(*) AS multiple_ip_sessions, 
        sum(requests) / count(*) AS avg_session_requests BY client_platform
```

可以在带有多个 `stats` 命令的查询中使用 `bin` 和 `dateceil` 函数。例如，以下查询首先将消息组合成 5 分钟的块，然后将这些 5 分钟的块聚合为 10 分钟的块，并计算每个 10 分钟块内的最高、最低和平均流量。

```
FIELDS strlen(@message) AS message_length
| STATS sum(message_length) / 1024 / 1024 AS logs_mb BY BIN(5m) as @t
| STATS max(logs_mb) AS peak_ingest_mb, 
        min(logs_mb) AS min_ingest_mb,
        avg(logs_mb) AS avg_ingest_mb BY dateceil(@t, 10m)
```

**注释和限制**

一个查询最多可以有两个 `stats` 命令。无法更改此配额。

如果您使用 `sort` 或 `limit` 命令，则它必须出现在第二个 `stats` 命令之后。如果它出现在第二个 `stats` 命令之前，则查询无效。

当一个查询有两个 `stats` 命令时，查询的部分结果要等到第一个 `stats` 聚合完成后才会开始显示。

在单个查询的第二个 `stats` 命令中，您只能引用第一个 `stats` 命令中定义的字段。例如，以下查询无效，因为 `@message` 字段在第一个 `stats` 聚合后将不可用。

```
FIELDS @message
| STATS SUM(Fault) by Operation
# You can only reference `SUM(Fault)` or Operation at this point
| STATS MAX(strlen(@message)) AS MaxMessageSize # Invalid reference to @message
```

在第一个 `stats` 命令之后引用的任何字段都必须在此第一个 `stats` 命令中定义。

```
STATS sum(x) as sum_x by y, z
| STATS max(sum_x) as max_x by z
# You can only reference `max(sum_x)`, max_x or z at this point
```

**重要**  
`bin` 函数始终隐式使用 `@timestamp` 字段。这意味着，如果未使用第一个 `stats` 命令传播 `timestamp` 字段，就无法在第二个 `stats` 命令中使用 `bin`。例如，以下查询无效。  

```
FIELDS strlen(@message) AS message_length
 | STATS sum(message_length) AS ingested_bytes BY @logStream
 | STATS avg(ingested_bytes) BY bin(5m) # Invalid reference to @timestamp field
```
相反，在第一个 `stats` 命令中定义 `@timestamp` 字段，然后就可以在第二个 `stats` 命令中结合 `dateceil` 使用该字段，如下例所示。  

```
FIELDS strlen(@message) AS message_length
 | STATS sum(message_length) AS ingested_bytes, max(@timestamp) as @t BY @logStream
 | STATS avg(ingested_bytes) BY dateceil(@t, 5m)
```

## 用于统计数据的函数
<a name="CWL_QuerySyntax-stats-functions"></a><a name="CWL_Insights_Aggregation_Functions"></a>

CloudWatch Logs Insights 支持统计数据聚合函数和统计数据非聚合函数。

 在 `stats` 命令中使用统计聚合函数，并将其用作其他函数的参数。


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|  `avg(fieldName: NumericLogField)` |  数字 |  指定的字段中值的平均值。  | 
|  `count()` `count(fieldName: LogField)` |  数字 |  计算日志事件的数量。`count()`（或 `count(*)`）对查询返回的所有事件进行计数，而 `count(fieldName)` 对包含所指定字段名称的所有记录进行计数。  | 
|  `count_distinct(fieldName: LogField)` |  数字 |  返回字段的唯一值的数量。如果字段具有非常高的基数（包含许多唯一值），则 `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)` |  数字 |  指定的字段中值的标准偏差。  | 
|  `sum(fieldName: NumericLogField)` |  数字 |  指定的字段中值的总和。  | 

 **统计非聚合函数** <a name="CWL_Insights_Non-Aggregation_Functions"></a>

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


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|  `earliest(fieldName: LogField)` |  LogField |  从查询的日志中具有最早时间戳的日志事件返回 `fieldName` 的值。  | 
|  `latest(fieldName: LogField)` |  LogField |  从查询的日志中具有最晚时间戳的日志事件返回 `fieldName` 的值。  | 
|  `sortsFirst(fieldName: LogField)` |  LogField |  返回在查询的日志中排在第一位的 `fieldName` 的值。  | 
|  `sortsLast(fieldName: LogField)` |  LogField |  返回在查询的日志中排在最后一位的 `fieldName` 的值。  | 

# limit
<a name="CWL_QuerySyntax-Limit"></a>

 使用 `limit` 指定您希望查询返回的日志事件数。如果省略 `limit`，则查询将在结果中返回多达 10,000 个日志事件。

例如，下面的示例仅返回最近 25 个日志事件。

```
fields @timestamp, @message | sort @timestamp desc | limit 25
```

# dedup
<a name="CWL_QuerySyntax-Dedup"></a>

 使用 `dedup` 根据您指定的字段中的特定值删除重复的结果。您可以将 `dedup` 与一个或多个字段配合使用。如果为一个字段指定 `dedup`，则会仅为该字段的每个唯一值返回一个日志事件。如果指定多个字段，则会为这些字段的每个唯一值组合返回一个日志事件。

重复项会根据排序顺序被丢弃，只保留排序顺序中的第一个结果。我们建议您在 `dedup` 执行命令之前对结果进行排序。如果在运行 `dedup` 之前未对结果进行排序，则会运用使用 `@timestamp` 时的默认降序排序顺序。

在评估中，NULL 值不被视为重复值。任何指定字段的值为 NULL 值的日志事件都将被保留。要消除具有 NULL 值的字段，请运用使用 `isPresent(field)` 函数的 **`filter`**。

在 `dedup` 命令之后可以在查询中使用的唯一查询命令是 `limit`。

当您在查询`dedup`中使用时，控制台会显示一条消息，例如**显示 Y 条记录中的 X**，其中 X 是已删除重复数据的结果数，Y 是重复数据删除前匹配的记录总数。这表示重复的记录已被删除，但并不意味着数据丢失。

 **示例：仅查看名为 `server` 的字段的每个唯一值的最新日志事件** 

 以下示例仅显示 `server` 每个唯一值的最新事件的 `timestamp`、`server`、`severity` 和 `message` 字段。

```
fields @timestamp, server, severity, message 
| sort @timestamp desc 
| dedup server
```

有关 CloudWatch Logs Insights 查询的更多示例，请参阅[常规查询](CWL_QuerySyntax-examples.md#CWL_QuerySyntax-examples-general)。

# unmask
<a name="CWL_QuerySyntax-Unmask"></a>

 使用 `unmask` 显示由于数据保护策略而屏蔽部分内容的日志事件的所有内容。要使用此命令，必须具备 `logs:Unmask` 权限。

有关日志组中数据保护的更多信息，请参阅 [通过屏蔽帮助保护敏感的日志数据](mask-sensitive-log-data.md)。

# unnest
<a name="CWL_QuerySyntax-Unnest"></a>

 使用 `unnest` 可以对输入列表进行扁平化以生成多条记录，列表中的每个元素都有一条记录。根据字段包含的项目数量，此命令会丢弃当前记录并生成新记录。每条记录都包含 `unnested_field`，它代表一个项目。其他所有字段均来自原始记录。

 `unnest` 的输入是 `LIST`，它来自 `jsonParse` 函数。有关更多信息，请参阅[结构类型](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-operations-functions.html#CWL_QuerySyntax-structure-types)。任何其他类型（例如，`MAP`、`String` 和 `numbers`）都被视为 `unnest` 中包含一个项目的列表。

**命令结构**  
 以下示例描述了此命令的格式。

```
unnest field into unnested_field
```

**示例查询**  
 以下示例解析了 JSON 对象字符串并展开字段事件列表。

```
fields jsonParse(@message) as json_message 
| unnest json_message.events into event
| display event.name
```

此示例查询的日志事件可能是一个 JSON 字符串，如下所示：

```
{
   "events": [
        {
            "name": "exception"
        },
        {
            "name": "user action"
        }
   ]
}
```

在本例中，示例查询会在查询结果中生成两条记录，一条记录的 `event.name` 为 `exception`，另一条记录的 `event.name` 为 **user action**。

**示例查询**  
 以下示例会对列表进行扁平化，然后筛选出项目。

```
fields jsonParse(@message) as js 
| unnest js.accounts into account 
| filter account.type = "internal"
```

**示例查询**  
 以下示例会对列表进行扁平化以进行聚合。

```
fields jsonParse(trimmedData) as accounts 
| unnest accounts into account 
| stats sum(account.droppedSpans) as n by account.accountId 
| sort n desc 
| limit 10
```

# lookup
<a name="CWL_QuerySyntax-Lookup"></a>

使用`lookup`查找表中的参考数据来丰富查询结果。查询表包含您上传到 Amazon Logs 的 CSV CloudWatch 数据。运行查询时，该`lookup`命令会将日志事件中的字段与查找表中的字段进行匹配，并将指定的输出字段附加到结果中。

对数据丰富场景使用查找表，例如 IDs将用户映射到用户详细信息、将产品代码映射到产品信息或将错误代码映射到错误描述。

## 创建和管理对照表
<a name="CWL_QuerySyntax-Lookup-tables"></a>

必须先创建对照表，然后才能在查询中使用该`lookup`命令。您可以通过 CloudWatch 控制台或使用 Amazon L CloudWatch ogs API 创建和管理查询表。

**创建对照表（控制台）**  


1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1. 在导航窗格中，选择 “**设置”**，然后选择 “**日志**” 选项卡。

1. 滚动到 “**查找表**”，然后选择 “**管理**”。

1. 选择 “**创建对照表”**。

1. 输入查找表的名称。名称只能包含字母数字字符、连字符和下划线。

1. （可选）输入描述。

1. 上传 CSV 文件。该文件必须包含带有列名的标题行，使用 UTF-8 编码，且不超过 10 MB。

1. （可选）指定用于加密表数据的密 AWS KMS 钥。

1. 选择**创建**。

创建对照表后，您可以在 L CloudWatch ogs Insights 查询编辑器中查看该表。选择 “**查找表**” 选项卡以浏览可用表及其字段。

要更新查找表，请选择该表，然后选择**操作**、**更新**。上传新的 CSV 文件以替换所有现有内容。要删除对照表，请选择**操作**，**删除**。

**注意**  
每个账户最多可以创建 100 个查询表 AWS 区域。CSV 文件的最大大小为 10 MB。您也可以使用 Amazon CloudWatch 日志 API 管理查询表。有关更多信息，请参阅 *Amazon CloudWatch 日志 API 参考[CreateLookupTable](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLookupTable.html)*中的。

**注意**  
如果使用 KMS 密钥对查找表进行加密，则调用者必须拥有该密钥（用于加密查找表的 KMS 密钥）的`kms:Decrypt`权限，才能将 `StartQuery` API 用于引用该查找表的查询。有关更多信息，请参阅 [使用加密 CloudWatch 日志中的查找表 AWS Key Management Service](encrypt-lookup-tables-kms.md)。

## 查找的查询语法
<a name="CWL_QuerySyntax-Lookup-syntax"></a>

**命令结构**  
下面显示了此命令的格式。

```
lookup table lookup-field as log-field [,...] output-mode output-field[,...]
```

该命令使用以下参数：
+ `table`-要使用的查找表的名称。
+ `lookup-field`-查找表中要与之匹配的字段。
+ `log-field`— 日志事件中要匹配的字段。匹配精确且区分大小写。
+ `output-mode`— 指定`OUTPUT`将输出字段添加到结果中。如果日志事件中已存在同名字段，则该字段将被覆盖。
+ `output-field`— 查找表中要添加到结果中的一个或多个字段。

**示例：使用用户详细信息丰富日志事件**  
假设您有一个日志组，其中包含包含一个`id`字段的事件，以及一个`user_data`以`id``name``email`、和列命名的查找表`department`。以下查询使用查询表中的用户名、电子邮件和部门来丰富每个日志事件。

```
fields action, status, name, email, department
| lookup user_data id OUTPUT name, email, department
```

**示例：使用带聚合的查找**  
您可以将查找输出字段与聚合函数一起使用。以下查询使用用户详细信息丰富日志事件，然后统计按电子邮件地址分组的事件。

```
fields user_id, action, username, email, department
| lookup user_data user_id OUTPUT username, email, department
| stats count(*) by email
```

**示例：使用带过滤器的查找**  
您可以根据查询返回的字段筛选结果。以下查询丰富了日志事件，然后筛选出仅显示来自特定部门的事件。

```
fields user_id, action
| lookup user_data user_id OUTPUT username, email, department
| filter department = "Engineering"
```

# 布尔值、比较、数值、日期时间和其他函数
<a name="CWL_QuerySyntax-operations-functions"></a>

 CloudWatch Logs Insights 支持查询中的许多其他操作和功能，如以下各节所述。

**Topics**
+ [算术运算符](#CWL_QuerySyntax-operations-arithmetic)
+ [布尔运算符](#CWL_QuerySyntax-operations-Boolean)
+ [比较运算符](#CWL_QuerySyntax-operations-comparison)
+ [数值运算符](#CWL_QuerySyntax-operations-numeric)
+ [结构类型](#CWL_QuerySyntax-structure-types)
+ [日期时间函数](#CWL_QuerySyntax-datetime)
+ [常见函数](#CWL_QuerySyntax-general-functions)
+ [JSON 函数](#CWL_QuerySyntax-json-functions)
+ [IP 地址字符串函数](#CWL_QuerySyntax-IPaddress-functions)
+ [字符串函数](#CWL_QuerySyntax-string-functions)

## 算术运算符
<a name="CWL_QuerySyntax-operations-arithmetic"></a>

 算术运算接受数值数据类型作为参数并返回数值结果。在 `filter` 和 `fields` 命令中使用算术运算并将其用作其他函数的参数。


| 操作 | 说明 | 
| --- | --- | 
|  `a + b` |  加  | 
|  `a - b` |  减  | 
|  `a * b` |  乘  | 
|  `a / b` |  除  | 
|  `a ^ b` |   幂（`2 ^ 3` 返回 `8`）   | 
|  `a % b` |   余额或模数（`10 % 3` 返回 `1`）   | 

## 布尔运算符
<a name="CWL_QuerySyntax-operations-Boolean"></a>

 使用布尔运算符 `and`、`or` 和 `not`。

**注意**  
 仅在返回 **TRUE** 或 **FALSE** 值的函数中使用布尔运算符。

## 比较运算符
<a name="CWL_QuerySyntax-operations-comparison"></a>

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


| 运算符 | 说明 | 
| --- | --- | 
|   `=`   |   Equal   | 
|   `!=`   |   Not equal   | 
|   `<`   |   Less than   | 
|  `>` |   Greater than   | 
|  `<=` |   小于或等于   | 
|   `>=`   |   大于或等于   | 

## 数值运算符
<a name="CWL_QuerySyntax-operations-numeric"></a>

 数值运算接受数值数据类型作为参数并返回数值结果。在 `filter` 和 `fields` 命令中使用数值运算并将其用作其他函数的参数。


| 操作 | 结果类型 | 说明 | 
| --- | --- | --- | 
|   `abs(a: number)`   |   number   |   绝对值   | 
|   `ceil(a: number)`   |   数字   |   舍入到上限（大于 `a` 的值的最小整数）   | 
|   `floor(a: number)`   |  数字 |   舍入到下限（小于 `a` 的值的最大整数）   | 
|   `greatest(a: number, ...numbers: number[])`   |   数字   |   返回最大值   | 
|   `least(a: number, ...numbers: number[])`   |  数字 |   返回最小值   | 
|   `log(a: number)`   |   数字   |   自然对数   | 
|   `sqrt(a: number)`   |   数字   |   平方根   | 

## 结构类型
<a name="CWL_QuerySyntax-structure-types"></a>

 地图或列表是 L CloudWatch ogs Insights 中的一种结构类型，允许您访问和使用属性进行查询。

**示例：获取映射或列表**  
 使用 `jsonParse` 可以将 json 字符串字段解析为地图或列表。

```
fields jsonParse(@message) as json_message
```

**示例：访问属性**  
 使用点访问运算符（map.attribute）可以访问映射中的项。如果映射中的某属性包含特殊字符，请使用反引号将属性名称括起来（map.attributes.`special.char`）。

```
fields jsonParse(@message) as json_message
| stats count() by json_message.status_code
```

 使用方括号访问运算符（list[index]）可以检索列表中特定位置的项。

```
fields jsonParse(@message) as json_message
| filter json_message.users[1].action = "PutData"
```

 当键名中出现特殊字符时，请用反引号（``）将特殊字符括起来。

```
fields jsonParse(@message) as json_message
| filter json_message.`user.id` = "123"
```

**示例：空结果**  
 对于字符串、数字和日期时间函数，映射和列表会被视为空值。

```
fields jsonParse(@message) as json_message
| display toupper(json_message)
```

 将映射和列表与任何其他字段进行比较会得出 `false`。

**注意**  
 不支持在 `dedup`、`pattern`、`sort` 和 `stats` 中使用映射和列表。

## 日期时间函数
<a name="CWL_QuerySyntax-datetime"></a>

 **日期时间函数** 

 在 `fields` 和 `filter` 命令中使用日期时间函数并将其用作其他函数的参数。使用这些函数为使用聚合函数的查询创建时间存储桶。使用由数字和下列项之一组成的时间段：
+ `ms` 代表毫秒 
+ `s` 代表秒 
+ `m` 代表分钟 
+ `h` 代表小时 

 例如，`10m` 为 10 分钟，`1h` 为 1 小时。

**注意**  
为日期时间函数使用最合适的时间单位。 CloudWatch 日志会根据您选择的时间单位对您的请求进行上限。例如，对于使用 `s` 的任何请求，它将最大值限制为 60。因此，如果您指定`bin(300s)`， CloudWatch Logs 实际上将其实现为 60 秒，因为 60 是一分钟内的秒数，因此 CloudWatch Logs 不会使用大于 60 的数字`s`。要创建 5 分钟的存储桶，请改用 `bin(5m)`。  
`ms` 的上限为 1000，`s` 和 `m` 的上限为 60，`h` 的上限为 24。

下表包含可在查询命令中使用的不同日期时间函数列表。该表列出了每个函数的结果类型，并包含对每个函数的描述。

**提示**  
 在创建查询命令时，您可以使用时间间隔选择器选择要查询的时间段。例如，您可以设置 5 到 30 分钟的时间间隔；1、3 和 12 小时间隔；或者自定义时间范围。您还可以设置特定日期之间的时间段。


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|  `bin(period: Period)` |  Timestamp |  将 `@timestamp` 的值四舍五入到指定的时间段，然后截断。例如，`bin(5m)` 将 `@timestamp` 的值四舍五入到最近的 5 分钟。 您可以使用它将某个查询中的多个日志条目分为一组。以下示例返回每小时的异常数量。 <pre>filter @message like /Exception/ <br />    | stats count(*) as exceptionCount by bin(1h)<br />    | sort exceptionCount desc</pre> `bin` 函数支持以下时间单位和缩写。对于所有包含多个字符的单位和缩写，支持添加复数形式。这样，`hr` 和 `hrs` 都可以指定小时数。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-operations-functions.html)  | 
|  `datefloor(timestamp: Timestamp, period: Period)` |  Timestamp |  将时间戳截断到指定的时间段。例如，`datefloor(@timestamp, 1h)` 将 `@timestamp` 的所有值截断至小时底部。  | 
|  `dateceil(timestamp: Timestamp, period: Period)` |  Timestamp |  将时间戳向上舍入到指定的时间段，然后截断。例如，`dateceil(@timestamp, 1h)` 将 `@timestamp` 的所有值截断至小时顶部。  | 
|  `fromMillis(fieldName: number)` |  Timestamp |  将输入字段解释为自 Unix epoch 以来的毫秒数并将其转换为时间戳。  | 
|  `toMillis(fieldName: Timestamp)` |  数字 |  将在命名字段中找到的时间戳转换为表示自 Unix epoch 以来毫秒数的数字。例如，`toMillis(@timestamp)` 将时间戳 `2022-01-14T13:18:031.000-08:00` 转换为 `1642195111000`。  | 
|  `now()`  |  数字  |  返回查询处理开始的时间，以 epoch 秒为单位。此函数不接受任何参数。 您可以使用它根据当前时间筛选查询结果。 例如，以下查询将返回过去两小时内的所有 4xx 错误： <pre>parse @message "Status Code: *;" as statusCode\n <br />| filter statusCode >= 400 and statusCode <= 499  \n <br />| filter toMillis(@timestamp) >= (now() * 1000 - 7200000)</pre> 以下示例会返回过去五小时内所有包含 `error` 或 `failure` 字样的日志条目 <pre>fields @timestamp, @message <br />| filter @message like /(?i)(error|failure)/ <br />| filter toMillis(@timestamp) >= (now() * 1000 - 18000000)</pre>  | 

**注意**  
 目前， CloudWatch Logs Insights 不支持筛选带有人类可读时间戳的日志。

## 常见函数
<a name="CWL_QuerySyntax-general-functions"></a>

 **常见函数** 

 在 `fields` 和 `filter` 命令中使用常规函数并将其用作其他函数的参数。


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|   `ispresent(fieldName: LogField)`   |   布尔值   |   如果字段存在，则返回 `true`   | 
|   `coalesce(fieldName: LogField, ...fieldNames: LogField[])`   |   LogField   |   返回列表中的第一个非 null 值   | 

## JSON 函数
<a name="CWL_QuerySyntax-json-functions"></a>

 **json 函数** 

 在 `fields` 和 `filter` 命令中使用 JSON 函数并将其用作其他函数的参数。


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|   `jsonParse(fieldName: string)`   |   映射 \$1 列表 \$1 空   |   当输入为 JSON 对象的字符串表示形式或 JSON 数组时，返回映射或列表。如果输入不是其中一种表示形式，则返回空值。  | 
|   `jsonStringify(fieldName: Map \| List)`   |   字符串   |   从映射或列表数据中返回 JSON 字符串。  | 

## IP 地址字符串函数
<a name="CWL_QuerySyntax-IPaddress-functions"></a>

 **IP 地址字符串函数** 

 在 `filter` 和 `fields` 命令中使用 IP 地址字符串函数并将其用作其他函数的参数。


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|  `isValidIp(fieldName: string)` |  布尔值 |  `true`如果该字段为有效 IPv4 或 IPv6 地址，则返回。  | 
|  `isValidIpV4(fieldName: string)` |  布尔值 |  `true`如果该字段是有效 IPv4 的地址，则返回。  | 
|  `isValidIpV6(fieldName: string)` |  布尔值 |  `true`如果该字段是有效 IPv6 的地址，则返回。  | 
|  `isIpInSubnet(fieldName: string, subnet: string)` |  布尔值 |  `true`如果该字段为指定的 v4 IPv4 或 v6 子网内的有效 IPv6 地址或地址，则返回。指定子网时，请使用 CIDR 表示法（例如 `192.0.2.0/24` 或 `2001:db8::/32`），其中 `192.0.2.0` 或 `2001:db8::` 是 CIDR 块的起点。  | 
|  `isIpv4InSubnet(fieldName: string, subnet: string)` |  布尔值 |  `true`如果该字段是指定 v4 子网内的有效 IPv4 地址，则返回。指定子网时，请使用 CIDR 表示法（例如 `192.0.2.0/24`），其中 `192.0.2.0` 是 CIDR 块的起点。  | 
|  `isIpv6InSubnet(fieldName: string, subnet: string)` |  布尔值 |  `true`如果该字段是指定 v6 子网内的有效 IPv6 地址，则返回。指定子网时，请使用 CIDR 表示法（例如 `2001:db8::/32`），其中 `2001:db8::` 是 CIDR 块的起点。  | 

## 字符串函数
<a name="CWL_QuerySyntax-string-functions"></a>

 **字符串函数** 

 在 `fields` 和 `filter` 命令中使用字符串函数并将其用作其他函数的参数。


| 函数 | 结果类型 | 说明 | 
| --- | --- | --- | 
|  `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)` |  数字 |  返回 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)` |  数字 |  如果 `str` 包含 `searchValue`，则返回 1，否则返回 0。  | 

# 包含特殊字符的字段
<a name="CWL_QuerySyntax-Guidelines"></a>

如果字段包含除 `@` 符号或句点（`.`）之外的非字母数字字符，则必须用反引号字符（```）将该字段括起来。例如，日志字段 `foo-bar` 必须括在反引号中（``foo-bar``），因为它包含连字符（`-`），这是非字母数字字符。

# 在查询中使用别名和注释
<a name="CWL_QuerySyntax-alias"></a>

 创建包含别名的查询。使用别名重命名日志字段或将值提取到字段中时重命名。使用关键字 `as` 为日志字段或结果提供别名。可以在查询中使用多个别名。可以在以下命令中使用别名：
+  `fields` 
+  `parse` 
+  `sort` 
+  ` stats ` 

 以下示例演示了如何创建包含别名的查询。

 **示例** 

 查询中在 `fields` 命令中包含别名。

```
fields @timestamp, @message, accountId as ID
| sort @timestamp desc
| limit 20
```

 查询将返回字段 `@timestamp`、`@message` 和 `accountId` 的值。结果按降序排序且限制在 20 个。`accountId` 的值在别名 `ID` 下列出。

 **示例** 

 查询在 `sort` 和 `stats` 命令中包含别名。

```
stats count(*) by duration as time 
| sort time desc
```

 查询计算字段 `duration` 出现在日志组中的次数，然后按降序对结果进行排序。`duration` 的值在别名 `time` 下列出。

## 使用注释
<a name="CWL_QuerySyntax-comments"></a>

 CloudWatch 日志见解支持查询中的评论。使用哈希字符（**\$1**）分隔备注。您可以使用备注忽略查询或文档查询中的行。

 **示例：查询** 

 运行以下查询时，将忽略第二行。

```
fields @timestamp, @message, accountId
# | filter accountId not like "7983124201998"
| sort @timestamp desc
| limit 20
```

# 开始使用 Logs Insights QL：查询教程
<a name="CWL_AnalyzeLogData_Tutorials"></a>

以下各部分包括示例查询教程，可帮助您开始使用 Logs Insights QL。

**Topics**
+ [教程：运行和修改示例查询](CWL_AnalyzeLogData_RunSampleQuery.md)
+ [教程：使用聚合函数运行查询](CWL_AnalyzeLogData_AggregationQuery.md)
+ [教程：运行生成按日志字段分组的可视化的查询](CWL_AnalyzeLogData_VisualizationFieldQuery.md)
+ [教程：运行生成时间序列可视化的查询](CWL_AnalyzeLogData_VisualizationQuery.md)

# 教程：运行和修改示例查询
<a name="CWL_AnalyzeLogData_RunSampleQuery"></a>

以下教程可帮助您开始使用 Log CloudWatch s Insights。您可以在 Logs Insights QL 中运行示例查询，然后了解如何修改并重新运行它。

要运行查询，您必须已经在日志中存储了 CloudWatch 日志。如果您已经在使用 CloudWatch 日志，并且已经设置了日志组和日志流，则可以开始使用了。如果您使用诸如 AWS CloudTrail Amazon Route 53 或 Amazon VPC 之类的服务，并且已将这些服务的日志设置为进入日志，则可能已经有 CloudWatch 日志。有关向 Logs 发送 CloudWatch 日志的更多信息，请参阅[CloudWatch 日志入门](CWL_GettingStarted.md)。

L CloudWatch ogs Insights 中的查询要么返回一组来自日志事件的字段，要么返回对日志事件执行的数学聚合或其他操作的结果。本教程演示了一个查询，该查询返回您的日志事件列表。

## 运行示例查询
<a name="CWL_AnalyzeLogData_RunQuerySample"></a>

**运行 L CloudWatch ogs Insights 示例查询**

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1. 在导航窗格中，选择 **Logs**（日志），然后选择 **Logs Insights**（日志洞察）。

   在 **Logs Insights** 页面上，查询编辑器包含 Logs Insights QL 中的一个默认查询，它将返回 20 个最近的日志事件。

1. 在**选择日志组**下拉菜单中，选择要查询的一个或多个日志组。

    如果这是 CloudWatch 跨账户可观察性的监控账户，则可以在源账户和监控账户中选择日志组。单个查询可以同时查询来自不同账户的日志。

   您可以按日志组名称、账户 ID 或账户标签筛选日志组。

   当您选择标准日志类中的日志组时， CloudWatch Logs Insights 会自动检测该组中的数据字段。要查看这些搜索到的字段，请选择页面右上方的 **Fields**（字段）菜单。
**注意**  
仅标准日志类中的日志组支持已发现字段。有关日志类的更多信息，请参阅 [日志类](CloudWatch_Logs_Log_Classes.md)。

1. （可选）使用时间间隔选择器选择要查询的时间段。

   您可以选择 5 到 30 分钟的间隔；1、3 和 12 小时间隔；或者自定义时间范围。

1. 选择 **Run**（运行）以查看结果。

   在本教程中，结果包括 20 个最近添加的日志事件。

   CloudWatch 日志显示一段时间内日志组中日志事件的条形图。该条形图显示日志组中与查询和时间范围匹配的事件分布情况，而不仅仅是表中显示的事件。

1. 要查看返回的日志事件的所有字段，请选择编号事件左侧的三角形下拉图标。

## 修改示例查询
<a name="CWL_AnalyzeLogData_ModifySampleQuery"></a>

在本教程中，您将修改示例查询以显示 50 个最新的日志事件。

如果您尚未运行上一教程，请立即运行。本教程开始于前一教程结束的位置。

**注意**  
L CloudWatch ogs Insights 中提供的一些示例查询使用`head`或`tail`命令代替`limit`。这些命令现正被弃用并已替换为 `limit`。在写入的所有查询中使用 `limit` 而非 `head` 或 `tail`。

**修改 “ CloudWatch 日志见解” 示例查询**

1. 在查询编辑器中，将 **20** 更改为 **50**，然后选择 **Run（运行）**。

   显示新查询的结果。假设在默认时间范围内日志组中有足够的数据，则现在将列出 50 个日志事件。

1. （可选）您可以保存已创建的查询。要保存此查询，请选择 **Save（保存）**。有关更多信息，请参阅 [保存并重新运行 Logs Insig CloudWatch hts 查询](CWL_Insights-Saving-Queries.md)。

## 将筛选命令添加到示例查询
<a name="CWL_AnalyzeLogData_FilterQuery"></a>

本教程说明如何在查询编辑器中对查询进行更有效的更改。在本教程中，您将基于检索的日志事件中的某个字段筛选上一个查询的结果。

如果您尚未运行前面的教程，请立即运行。本教程开始于前一教程结束的位置。

**将筛选命令添加到前一查询**

1. 确定要筛选的字段。要查看过去 15 分钟内 CloudWatch 日志在所选日志组中包含的日志事件中检测到的最常见**字**段，以及每个字段出现在这些日志事件中的百分比，请选择页面右侧的字段。

   要查看特定日志事件中包含的字段，请选择该行左侧的图标。

   **awsRegion** 字段可能会显示在您的日志事件中，具体取决于日志中的事件。对于本教程的其余部分，我们使用 **awsRegion** 作为筛选字段，但如果该字段不可用，则您可以使用其他字段。

1. 在查询编辑器框中，将光标放在 **50** 之后，然后按 Enter。

1. 在新行上，首先输入 \$1（竖线字符）和一个空格。L CloudWatch ogs Insights 查询中的命令必须用竖线字符分隔。

1. 输入 **filter awsRegion="us-east-1"**。

1. 选择**运行**。

   此查询再次运行，现在将显示与新筛选器匹配的 50 个最新结果。

   如果您筛选不同的字段并获得错误结果，则您可能需要对字段名称进行转义。如果字段名称包含非字母数字字符，则必须在字段名称前后放入反引号字符（`），例如 **`error-code`="102"**。

   必须将反引号字符用于包含非字母数字字符的字段名称，但不能用于值。值始终包含在引号（"）中。

Logs Insights QL 包含强大的查询能力，包括若干命令和对于正则表达式、数学和统计运算的支持。有关更多信息，请参阅 [CloudWatch 日志见解语言查询语法](CWL_QuerySyntax.md)。

# 教程：使用聚合函数运行查询
<a name="CWL_AnalyzeLogData_AggregationQuery"></a>

您可以通过 `stats` 命令使用聚合函数并将其用作其他函数的参数。在本教程中，您会运行一个查询命令，该命令将计算包含指定字段的录入事件的数量。查询命令返回按指定字段的一个值或多个值分组的总计数。有关聚合函数的更多信息，请参阅 *Amazon L CloudWatch ogs 用户指南*中[支持的操作和函数](https://docs.aws.amazon.com/en_us/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html#CWL_QuerySyntax-operations-functions)。

**使用聚合函数运行查询**

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1. 在导航窗格中，选择 **Logs**（日志），然后选择 **Logs Insights**（日志洞察）。

1. 确认已选中 **Logs Insights QL** 选项卡。

1. 在**选择日志组**下拉菜单中，选择要查询的一个或多个日志组。

    如果这是 CloudWatch 跨账户可观察性的监控账户，则可以在源账户和监控账户中选择日志组。单个查询可以同时查询来自不同账户的日志。

   您可以按日志组名称、账户 ID 或账户标签筛选日志组。

   选择日志组时，如果日志组是标准类 CloudWatch 日志组，Logs Insights 会自动检测该日志组中的数据字段。要查看这些搜索到的字段，请选择页面右上方的 **Fields**（字段）菜单。

1. 在查询编辑器中删除原定设置查询，然后输入以下命令：

   ```
   stats count(*) by fieldName
   ```

1. *fieldName*替换为 “字段” 菜单中已发现的**字段**。

   **字段**菜单位于页面的右上角，显示 Logs Insights 在您的 CloudWatch 日志组中检测到的所有已发现字段。

1. 选择 **Run**（运行）以查看查询结果。

   查询结果会显示日志组中与查询命令匹配的记录数以及按指定字段一个值或多个值分组的总计数。

# 教程：运行生成按日志字段分组的可视化的查询
<a name="CWL_AnalyzeLogData_VisualizationFieldQuery"></a>

当您运行的查询使用 `stats` 函数按日志条目中一个或多个字段的值来分组所返回的结果时，您可以使用条形图、饼图、折线图或堆叠面积图来查看结果。这可帮助您更有效地将日志中的趋势可视化。

**运行查询进行可视化**

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1. 在导航窗格中，选择 **Logs**（日志），然后选择 **Logs Insights**（日志洞察）。

1. 在 **Select log group(s)**（选择日志组）在下拉菜单中，选择要查询的一个或多个日志组。

    如果这是 CloudWatch 跨账户可观察性的监控账户，则可以在源账户和监控账户中选择日志组。单个查询可以同时查询来自不同账户的日志。

   您可以按日志组名称、账户 ID 或账户标签筛选日志组。

1. 在查询编辑器中，删除当前内容，然后输入以下 `stats` 函数并选择 **Run query（运行查询）**。

   ```
   stats count(*) by @logStream 
       | limit 100
   ```

   对于每个日志流，结果显示日志组中的日志事件数量。结果限制为 100 行。

1. 选择**可视化**选项卡。

1. 选择 **Line（折线图）**旁边的箭头，然后选择 **Bar（条形图）**。

   此时将出现条形图，其中显示日志组中各个日志流的条形图。

# 教程：运行生成时间序列可视化的查询
<a name="CWL_AnalyzeLogData_VisualizationQuery"></a>

当您运行使用 `bin()` 函数按时间段对返回的结果进行分组的查询时，您可以使用折线图、堆叠面积图、饼图或条形图来查看结果。这有助于您更有效地将日志事件随时间变化的趋势可视化。

**运行查询进行可视化**

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1. 在导航窗格中，选择 **Logs**（日志），然后选择 **Logs Insights**（日志洞察）。

1. 确认已选中 **Logs Insights QL** 选项卡。

1. 在**选择日志组**下拉菜单中，选择要查询的一个或多个日志组。

    如果这是 CloudWatch 跨账户可观察性的监控账户，则可以在源账户和监控账户中选择日志组。单个查询可以同时查询来自不同账户的日志。

   您可以按日志组名称、账户 ID 或账户标签筛选日志组。

1. 在查询编辑器中，删除当前内容，然后输入以下 `stats` 函数并选择 **Run query（运行查询）**。

   ```
   stats count(*) by bin(30s)
   ```

   结果显示 Logs 在每 30 秒周期内收到的日志组中 CloudWatch 日志事件的数量。

1. 选择**可视化**选项卡。

   结果显示为折线图。要切换到条形图、饼图或堆叠面积图，请在图形左上角选择 **Line（折线图）**旁边的箭头。

# 查询示例
<a name="CWL_QuerySyntax-examples"></a>

本节包含可在[CloudWatch控制台](https://console.aws.amazon.com/cloudwatch/)中运行的一般和有用的查询命令列表。有关如何运行查询命令的信息，请参阅 *Amazon L CloudWatch ogs 用户指南*中的[教程：运行和修改示例查询](https://docs.aws.amazon.com/en_us/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_RunSampleQuery.html)。

有关查询语法的更多信息，请参阅 [CloudWatch 日志见解语言查询语法](CWL_QuerySyntax.md)。

**Topics**
+ [常规查询](#CWL_QuerySyntax-examples-general)
+ [Lambda 日志的查询](#CWL_QuerySyntax-examples-Lambda)
+ [Amazon VPC 流日志的查询](#CWL_QuerySyntax-examples-VPC)
+ [Route 53 日志的查询](#CWL_QuerySyntax-examples-Route53)
+ [查询日 CloudTrail 志](#CWL_QuerySyntax-examples-CloudTrail)
+ [查询 Amazon API Gateway](#CWL_QuerySyntax-examples-APIGateway)
+ [NAT 网关的查询](#CWL_QuerySyntax-examples-NATGateway)
+ [查询 Apache 服务器日志](#CWL_QuerySyntax-examples-Apache)
+ [针对亚马逊的查询 EventBridge](#CWL_QuerySyntax-examples-EventBridge)
+ [解析命令的示例](#CWL_QuerySyntax-examples-parse)

## 常规查询
<a name="CWL_QuerySyntax-examples-general"></a>

**查找 25 个最近添加的日志事件。**

```
fields @timestamp, @message | sort @timestamp desc | limit 25
```

**获取每小时异常数量的列表。**

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

**获取非异常的日志事件的列表。**

```
fields @message | filter @message not like /Exception/
```

**获取 `server` 字段每个唯一值的最新日志事件。**

```
fields @timestamp, server, severity, message 
| sort @timestamp asc 
| dedup server
```

**针对每个 `severity` 类型获取 `server` 字段每个唯一值的最新日志事件。**

```
fields @timestamp, server, severity, message 
| sort @timestamp desc 
| dedup server, severity
```

## Lambda 日志的查询
<a name="CWL_QuerySyntax-examples-Lambda"></a>

**确定超额配置的内存量。**

```
filter @type = "REPORT"
    | stats max(@memorySize / 1000 / 1000) as provisonedMemoryMB,
        min(@maxMemoryUsed / 1000 / 1000) as smallestMemoryRequestMB,
        avg(@maxMemoryUsed / 1000 / 1000) as avgMemoryUsedMB,
        max(@maxMemoryUsed / 1000 / 1000) as maxMemoryUsedMB,
        provisonedMemoryMB - maxMemoryUsedMB as overProvisionedMB
```

**创建延迟报告。**

```
filter @type = "REPORT" |
    stats avg(@duration), max(@duration), min(@duration) by bin(5m)
```

**搜索慢速函数调用，并消除可能因重试或客户端代码而产生的重复请求。在此查询中，`@duration` 以毫秒为单位。**

```
fields @timestamp, @requestId, @message, @logStream 
| filter @type = "REPORT" and @duration > 1000
| sort @timestamp desc
| dedup @requestId 
| limit 20
```

## Amazon VPC 流日志的查询
<a name="CWL_QuerySyntax-examples-VPC"></a>

**查找跨主机的前 15 个数据包传输：**

```
stats sum(packets) as packetsTransferred by srcAddr, dstAddr
    | sort packetsTransferred  desc
    | limit 15
```

**查找给定子网上传输字节数最多的 15 个主机。**

```
filter isIpv4InSubnet(srcAddr, "192.0.2.0/24")
    | stats sum(bytes) as bytesTransferred by dstAddr
    | sort bytesTransferred desc
    | limit 15
```

**查找使用 UDP 作为数据传输协议的 IP 地址。**

```
filter protocol=17 | stats count(*) by srcAddr
```

**在捕获时段内查找跳过流记录的 IP 地址。**

```
filter logStatus="SKIPDATA"
    | stats count(*) by bin(1h) as t
    | sort t
```

**为每个连接查找一条记录，以帮助解决网络连接问题。**

```
fields @timestamp, srcAddr, dstAddr, srcPort, dstPort, protocol, bytes 
| filter logStream = 'vpc-flow-logs' and interfaceId = 'eni-0123456789abcdef0' 
| sort @timestamp desc 
| dedup srcAddr, dstAddr, srcPort, dstPort, protocol 
| limit 20
```

## Route 53 日志的查询
<a name="CWL_QuerySyntax-examples-Route53"></a>

**查找每小时每种查询类型的记录分布。**

```
stats count(*) by queryType, bin(1h)
```

**查找具有最高请求数的 10 个 DNS 解析程序。**

```
stats count(*) as numRequests by resolverIp
    | sort numRequests desc
    | limit 10
```

**按服务器未能完成 DNS 请求的域和子域查找记录数。**

```
filter responseCode="SERVFAIL" | stats count(*) by queryName
```

## 查询日 CloudTrail 志
<a name="CWL_QuerySyntax-examples-CloudTrail"></a>

**查找每项服务的日志条目数、事件类型和 AWS 区域。**

```
stats count(*) by eventSource, eventName, awsRegion
```

**查找在给定 AWS 区域中启动或停止的 Amazon EC2 主机。**

```
filter (eventName="StartInstances" or eventName="StopInstances") and awsRegion="us-east-2"
```

**查找 AWS 区域、用户名和 ARNs 新创建的 IAM 用户。**

```
filter eventName="CreateUser"
    | fields awsRegion, requestParameters.userName, responseElements.user.arn
```

**查找在调用 API `UpdateTrail` 时发生异常的记录数。**

```
filter eventName="UpdateTrail" and ispresent(errorCode)
    | stats count(*) by errorCode, errorMessage
```

**查找使用 TLS 1.0 或 1.1 的日志条目**

```
filter tlsDetails.tlsVersion in [ "TLSv1", "TLSv1.1" ]
| stats count(*) as numOutdatedTlsCalls by userIdentity.accountId, recipientAccountId, eventSource, eventName, awsRegion, tlsDetails.tlsVersion, tlsDetails.cipherSuite, userAgent
| sort eventSource, eventName, awsRegion, tlsDetails.tlsVersion
```

**查找使用 TLS 1.0 或 1.1 的服务调用数**

```
filter tlsDetails.tlsVersion in [ "TLSv1", "TLSv1.1" ]
| stats count(*) as numOutdatedTlsCalls by eventSource
| sort numOutdatedTlsCalls desc
```

## 查询 Amazon API Gateway
<a name="CWL_QuerySyntax-examples-APIGateway"></a>

查找最近 10 个 4XX 错误

```
fields @timestamp, status, ip, path, httpMethod
| filter status>=400 and status<=499
| sort @timestamp desc
| limit 10
```

确定 Amazon API Gateway 访问日志组中运行时间最长的 10 个 Amazon API Gateway 请求

```
fields @timestamp, status, ip, path, httpMethod, responseLatency
| sort responseLatency desc
| limit 10
```

返回 Amazon API Gateway 访问日志组中最受欢迎的 API 路径列表

```
stats count(*) as requestCount by path
| sort requestCount desc
| limit 10
```

为 Amazon API Gateway 访问日志组创建集成延迟报告

```
filter status=200
| stats avg(integrationLatency), max(integrationLatency), 
min(integrationLatency) by bin(1m)
```

## NAT 网关的查询
<a name="CWL_QuerySyntax-examples-NATGateway"></a>

如果您发现 AWS 账单中的费用高于正常水平，则可以使用 L CloudWatch ogs Insights 来查找排名靠前的贡献者。有关以下查询命令的更多信息，请参阅[如何在 VPC 中找到通过 NAT 网关的流量的最大贡献者？](https://aws.amazon.com/premiumsupport/knowledge-center/vpc-find-traffic-sources-nat-gateway/) 在 AWS 高级支持页面上。

**注意**  
在以下查询命令中，将 "x.x.x.x" 替换为 NAT 网关的私有 IP，然后用 VPC CIDR 范围的前两个八位字节替换 "y.y"。

**查找通过 NAT 网关发送流量最多的实例。**

```
filter (dstAddr like 'x.x.x.x' and srcAddr like 'y.y.') 
| stats sum(bytes) as bytesTransferred by srcAddr, dstAddr
| sort bytesTransferred desc
| limit 10
```

**确定 NAT 网关中进出实例的流量。**

```
filter (dstAddr like 'x.x.x.x' and srcAddr like 'y.y.') or (srcAddr like 'xxx.xx.xx.xx' and dstAddr like 'y.y.')
| stats sum(bytes) as bytesTransferred by srcAddr, dstAddr
| sort bytesTransferred desc
| limit 10
```

**确定 VPC 中实例最常与之进行上传和下载的互联网目标。**

*****对于上载*****

```
filter (srcAddr like 'x.x.x.x' and dstAddr not like 'y.y.') 
| stats sum(bytes) as bytesTransferred by srcAddr, dstAddr
| sort bytesTransferred desc
| limit 10
```

*****对于下载*****

```
filter (dstAddr like 'x.x.x.x' and srcAddr not like 'y.y.') 
| stats sum(bytes) as bytesTransferred by srcAddr, dstAddr
| sort bytesTransferred desc
| limit 10
```

## 查询 Apache 服务器日志
<a name="CWL_QuerySyntax-examples-Apache"></a>

您可以使用 CloudWatch Logs Insights 查询 Apache 服务器日志。有关以下查询的更多信息，请参阅 AWS 云运营[与迁移博客上的使用 CloudWatch 日志见解简化 Apache 服务器](https://aws.amazon.com/blogs/mt/simplifying-apache-server-logs-with-amazon-cloudwatch-logs-insights/)日志。

**找到最相关的字段，以便您可以在应用程序的 */admin* 路径中审阅访问日志并查看流量。**

```
fields @timestamp, remoteIP, request, status, filename| sort @timestamp desc
| filter filename="/var/www/html/admin"
| limit 20
```

**使用状态代码“200”（成功）查找访问主页的唯一 GET 请求数量。**

```
fields @timestamp, remoteIP, method, status
| filter status="200" and referrer= http://34.250.27.141/ and method= "GET"
| stats count_distinct(remoteIP) as UniqueVisits
| limit 10
```

**查找 Apache 服务重新启动的次数。**

```
fields @timestamp, function, process, message
| filter message like "resuming normal operations"
| sort @timestamp desc
| limit 20
```

## 针对亚马逊的查询 EventBridge
<a name="CWL_QuerySyntax-examples-EventBridge"></a>

获取按 EventBridge 事件详情类型分组的事件数量

```
fields @timestamp, @message
| stats count(*) as numberOfEvents by `detail-type`
| sort numberOfEvents desc
```

## 解析命令的示例
<a name="CWL_QuerySyntax-examples-parse"></a>

**使用 glob 表达式来从日志字段 `@message` 提取字段 `@user`、`@method` 和 `@latency`，并对于 `@method` 和 `@user` 的每个唯一组合返回平均延迟。**

```
parse @message "user=*, method:*, latency := *" as @user,
    @method, @latency | stats avg(@latency) by @method,
    @user
```

**使用正则表达式从日志字段 `@message` 提取字段 `@user2`、`@method2` 和 `@latency2`，并对于 `@method2` 和 `@user2` 的每个唯一组合返回平均延迟。**

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

**提取字段 `loggingTime`、`loggingType` 和 `loggingMessage`，筛选出包含 `ERROR` 或 `INFO` 字符串的日志事件，然后仅显示包含 `ERROR` 字符串的事件的 `loggingMessage` 和 `loggingType` 字段。**

```
FIELDS @message
    | PARSE @message "* [*] *" as loggingTime, loggingType, loggingMessage
    | FILTER loggingType IN ["ERROR", "INFO"]
    | DISPLAY loggingMessage, loggingType = "ERROR" as isError
```

# 与之前的时间范围进行比较（差异）
<a name="CWL_AnalyzeLogData_Compare"></a>

您可以使用 L CloudWatch ogs Insights 和 Logs Insights QL 来比较日志事件在一段时间内的变化。您可以将最近时间范围内提取的日志事件与紧接的前一个时间段的日志进行比较。或者，您可以与类似的过去时间段进行比较。这可以帮助您发现日志中的错误是最近引入的还是已经发生的，并可以帮助您发现其他趋势。

比较查询仅返回结果中的模式，而不是原始日志事件。返回的模式将帮助您快速查看一段时间内日志事件的趋势和变化。运行比较查询并获得模式结果后，您可以查看自己感兴趣的模式的示例原始日志事件。有关日志模式的更多信息，请参阅 [模式分析](CWL_AnalyzeLogData_Patterns.md)。

当您运行比较查询时，系统会根据两个不同的时间段分析您的查询：您选择的原始查询时间段和比较时间段。比较时间段的长度始终与原始查询时间段的长度相同。比较的默认时间间隔如下。
+ **上一时间段** — 与查询时间段之前的时间段进行比较。
+ **前一天** — 与查询时间段之前一天的时间段进行比较。
+ **上一周** — 与查询时间段之前一周的时间段进行比较。
+ **上个月** — 与查询时间段之前一个月的时间段进行比较。

**注意**  
使用比较的查询会产生类似于在合并时间范围内运行单个 CloudWatch Logs Insights 查询的费用。有关更多信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/)。

**运行比较查询**

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1. 在导航窗格中，依次选择**日志**、**Logs Insights**。

   查询框中会出现默认查询。

1. 确认已选中 **Logs Insights QL** 选项卡。

1. 保留默认查询或输入其他查询。

1. 在**选择日志组**下拉菜单中，选择要查询的一个或多个日志组。

1. （可选）使用时间间隔选择器选择要查询的时间段。默认查询针对的是前一小时的日志数据。

1. 在时间范围选择器中，选择**比较**。然后选择要与原始日志进行比较的上一个时间段，并选择**应用**。

1. 选择**运行查询**。

   为了使查询从比较时间段获取数据，将在您的查询中附加 `diff` 命令。

1. 选择**模式**选项卡以查看结果。

   该表将显示以下信息：
   + 每个**模式**，模式的可变部分替换为动态令牌符号 `<string-number>`。*string*是对令牌所代表的数据类型的描述。*number*显示了与其他动态代币相比，该代币在模式中的显示位置。有关更多信息，请参阅 [模式分析](CWL_AnalyzeLogData_Patterns.md)。
   + **事件计数**是原始的、较新的时间段内具有该模式的日志事件的数量。
   + **差异事件计数**是当前时间段与比较时间段内匹配的日志事件数之间的差异。正差异表示当前时间段内此类事件较多。
   + **差异描述**简要总结了当前时间段和比较时间段之间的模式变化。
   + **严重性类型**是具有此模式的日志事件的可能严重性，基于在日志事件中发现的字词（例如 `FATAL`、`ERROR` 和 `WARN`）。

1. 要进一步检查列表中的某个模式，请在**检查**列中选择其中一个模式的图标。

   将出现**模式检查**窗格并显示以下内容：
   + **模式**。选择模式内的一个令牌来分析该令牌的值。
   + 直方图，显示查询的时间范围内模式的出现次数。这可以帮助您识别有趣的趋势，例如某种模式的出现突然增加。
   + **日志示例**选项卡显示一些与所选模式匹配的日志事件。
   + 如果您已选择动态令牌，则**令牌值**选项卡会显示所选动态令牌的值。
**注意**  
每个令牌最多可捕获 10 个令牌值。代币数量可能不精确。 CloudWatch 日志使用概率计数器来生成代币数量，而不是绝对值。
   + **相关模式**选项卡显示与您正在检查的模式几乎同时频繁出现的其他模式。例如，如果 `ERROR` 消息的模式通常伴随另一个标记为 `INFO` 并带有附加详细信息的日志事件，则此处显示该模式。

# 在图形中可视化日志数据
<a name="CWL_Insights-Visualizing-Log-Data"></a>

您可以使用条形图、折线图和堆积面积图等可视化来更有效地识别日志数据中的模式。 CloudWatch Logs Insights 为使用该`stats`函数和一个或多个聚合函数的查询生成可视化效果。有关更多信息，请参阅[统计数据](CWL_QuerySyntax-Stats.md)。