

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

# 可配置的解析器类型处理器
<a name="CloudWatch-Logs-Transformation-Configurable"></a>

本节包含有关可在日志事件转换器中使用的可配置数据解析器处理器的信息。

**Contents**
+ [parseJSON](#CloudWatch-Logs-Transformation-parseJSON)
+ [grok](#CloudWatch-Logs-Transformation-Grok)
  + [Grok 示例](#Grok-Examples)
    + [示例 1：使用 grok 从非结构化日志中提取字段](#Grok-Example1)
    + [示例 2：搭配使用 grok 和 parseJSON 从 JSON 日志事件中提取字段](#Grok-Example3)
    + [示例 3：FIELD\$1NAME 中带有点注释的 Grok 模式](#Grok-Example4)
  + [支持的 Grok 模式](#Grok-Patterns)
    + [常见日志格式示例](#Common-Log-Examples)
      + [Apache 日志示例](#Apache-Log-Example)
      + [NGINX 日志示例](#NGINX-Log-Example)
      + [Syslog 协议（RFC 5424）日志示例](#syslog5424-Log-Example)
+ [csv](#CloudWatch-Logs-Transformation-csv)
+ [parseKeyValue](#CloudWatch-Logs-Transformation-parseKeyValue)

## parseJSON
<a name="CloudWatch-Logs-Transformation-parseJSON"></a>

**parseJSON** 处理器解析 JSON 日志事件，并将提取的 JSON 键值对插入到目标位置。如果没有指定目标位置，则处理器会将键值对放置在根节点下。当使用 `parseJSON` 作为第一个处理器时，您必须使用 `@message` 作为源字段来解析整个日志事件。在初始 JSON 解析后，您可以在后续处理器中操作特定字段。

原始 `@message` 内容不变，新键会添加到消息中。


| 字段 | 说明 | 必填？ | 默认 | 限制 | 
| --- | --- | --- | --- | --- | 
|  source | 日志事件中待解析字段的路径。请使用点表示法访问子字段。例如，store.book |  否 | `@message`  | 最大长度：128 最大嵌套键深度：3 | 
|  destination | 已解析 JSON 的目标字段 |  否 | `Parent JSON node`  | 最大长度：128 最大嵌套键深度：3 | 

**示例**

假设摄取的日志事件如下所示：

```
{
    "outer_key": {
        "inner_key": "inner_value"
    }
}
```

如果我们有此 **parseJSON** 处理器：

```
[
   {
        "parseJSON": {
            "destination": "new_key"
        }
   }
]
```

转换后的日志事件将如下所示。

```
{
    "new_key": {
        "outer_key": {
            "inner_key": "inner_value"
        }
    }
}
```

## grok
<a name="CloudWatch-Logs-Transformation-Grok"></a>

使用 grok 处理器通过模式匹配来解析和构造非结构化数据。此处理器还可以从日志消息中提取字段。


| 字段 | 说明 | 必填？ | 默认 | 限制 | 注意 | 
| --- | --- | --- | --- | --- | --- | 
|  source | 要应用 Grok 匹配的字段路径 |  否 | `@message`  | 最大长度：128 最大嵌套键深度：3 | 
|  match | 要与日志事件匹配的 grok 模式  |  是 |  | 最大长度：512 最大 grok 模式：20 某些 grok 模式类型有单独的使用限制。以下模式可以任意组合使用，最多可使用五次：\$1URI, URIPARAM, URIPATHPARAM, SPACE, DATA, GREEDYDATA, GREEDYDATA\$1MULTILINE\$1 Grok 模式不支持类型转换。 对于常见的日志格式模式（APACHE\$1ACCESS\$1LOG、NGINX\$1ACCESS\$1LOG、 SYSLOG5424），仅支持在常见日志模式之后包含 DATA、GREEDYDATA 或 GREEDYDATA\$1MULTILINE 模式。  | [查看所有支持的 Grok 模式](#Grok-Patterns) | 

**Grok 模式的结构**

下面是支持的 grok 模式结构：

```
%{PATTERN_NAME:FIELD_NAME}
```
+ **PATTERN\$1NAME**：指用于匹配特定类型数据的预定义正则表达式。仅支持预定义的 [grok 模式](#Grok-Patterns)。不允许创建自定义模式。
+ **FIELD\$1NAME**：为提取的值分配名称。`FIELD_NAME` 是可选的，但是如果您不指定此值，则提取的数据将从转换后的日志事件中删除。如果 `FIELD_NAME` 使用点表示法（例如“parent.child”），则将其视为 JSON 路径。
+ **类型转换**：不支持显式类型转换。使用 p [TypeConverter ro](CloudWatch-Logs-Transformation-Datatype.md#CloudWatch-Logs-Transformation-typeConverter) cessor 转换由 grok 提取的任何值的数据类型。

要创建更复杂的匹配表达式，您可以组合多个 grok 模式。最多可以组合 20 个 grok 模式来匹配一个日志事件。例如，可以使用此模式组合 `%{NUMBER:timestamp} [%{NUMBER:db} %{IP:client_ip}:%{NUMBER:client_port}] %{GREEDYDATA:data}` 从 Redis 慢日志条目中提取字段，如下所示：

`1629860738.123456 [0 127.0.0.1:6379] "SET" "key1" "value1"`

### Grok 示例
<a name="Grok-Examples"></a>

#### 示例 1：使用 grok 从非结构化日志中提取字段
<a name="Grok-Example1"></a>

日志示例：

```
293750 server-01.internal-network.local OK "[Thread-000] token generated"
```

使用的转换器：

```
[
     {
         "grok": {
             "match": "%{NUMBER:version} %{HOSTNAME:hostname} %{NOTSPACE:status} %{QUOTEDSTRING:logMsg}"
         }
    }
]
```

输出：

```
{
  "version": "293750",
  "hostname": "server-01.internal-network.local",
  "status": "OK",
  "logMsg": "[Thread-000] token generated"
}
```

日志示例：

```
23/Nov/2024:10:25:15 -0900 172.16.0.1 200
```

使用的转换器：

```
[
    {
        "grok": {
            "match": "%{HTTPDATE:timestamp} %{IPORHOST:clientip} %{NUMBER:response_status}"
        }
    }
]
```

输出：

```
{
  "timestamp": "23/Nov/2024:10:25:15 -0900",
  "clientip": "172.16.0.1",
  "response_status": "200"
}
```

#### 示例 2：搭配使用 grok 和 parseJSON 从 JSON 日志事件中提取字段
<a name="Grok-Example3"></a>

日志示例：

```
{
    "timestamp": "2024-11-23T16:03:12Z",
    "level": "ERROR",
    "logMsg": "GET /page.html HTTP/1.1"
}
```

使用的转换器：

```
[
     {
        "parseJSON": {}
    },
    {
         "grok": {
            "source": "logMsg",
             "match": "%{WORD:http_method} %{NOTSPACE:request} HTTP/%{NUMBER:http_version}"
         }
    }
]
```

输出：

```
{
  "timestamp": "2024-11-23T16:03:12Z",
  "level": "ERROR",
  "logMsg": "GET /page.html HTTP/1.1",
  "http_method": "GET",
  "request": "/page.html",
  "http_version": "1.1"
}
```

#### 示例 3：FIELD\$1NAME 中带有点注释的 Grok 模式
<a name="Grok-Example4"></a>

日志示例：

```
192.168.1.1 GET /index.html?param=value 200 1234
```

使用的转换器：

```
[
    {
        "grok": {
            "match": "%{IP:client.ip} %{WORD:method} %{URIPATHPARAM:request.uri} %{NUMBER:response.status} %{NUMBER:response.bytes}"
        }
    }
]
```

输出：

```
{
  "client": {
    "ip": "192.168.1.1"
  },
  "method": "GET",
  "request": {
    "uri": "/index.html?param=value"
  },
  "response": {
    "status": "200",
    "bytes": "1234"
  }
}
```

### 支持的 Grok 模式
<a name="Grok-Patterns"></a>

下表列出了 `grok` 处理器支持的模式。

**常规 grok 模式**


| Grok 模式 | 说明 | 最大模式限制 | 示例 | 
| --- | --- | --- | --- | 
| USERNAME 或 USER | 匹配一个或多个字符，可以包括小写字母（a-z）、大写字母（A-Z）、数字（0-9）、点（.）、下划线（\$1）或连字符（-） | 20 |  输入：`user123.name-TEST` 模式：`%{USERNAME:name}` 输出：`{"name": "user123.name-TEST"}`  | 
| INT | 匹配可选的加号或减号，后跟一个或多个数字。 | 20 |  输入：`-456` 模式：`%{INT:num}` 输出：`{"num": "-456"}`  | 
| BASE10NUM | 匹配带有可选符号和小数点的整数或浮点数 | 20 |  输入：`-0.67` 模式：`%{BASE10NUM:num}` 输出：`{"num": "-0.67"}`  | 
| BASE16NUM | 匹配带有可选符号（\$1 或 -）和可选 0x 前缀的十进制和十六进制数字 | 20 |  输入：`+0xA1B2` 模式：`%{BASE16NUM:num}` 输出：`{"num": "+0xA1B2"}`  | 
| POSINT | 匹配不带前导零的正整数，由一个或多个数字组成（1-9 后跟 0-9） | 20 |  输入：`123` 模式：`%{POSINT:num}` 输出：`{"num": "123"}`  | 
| NONNEGINT | 匹配任何整数（由一个或多个数字 0-9 组成），包括零和带前导零的数字。 | 20 |  输入：`007` 模式：`%{NONNEGINT:num}` 输出：`{"num": "007"}`  | 
| WORD | 匹配由一个或多个单词字符（\$1w）组成的完整单词，包括字母、数字和下划线 | 20 |  输入：`user_123` 模式：`%{WORD:user}` 输出：`{"user": "user_123"}`  | 
| NOTSPACE | 匹配一个或多个非空格字符。 | 5 |  输入：`hello_world123` 模式：`%{NOTSPACE:msg}` 输出：`{"msg": "hello_world123"}`  | 
| SPACE | 匹配零个或多个空格字符。 | 5 |  输入：`" "` 模式：`%{SPACE:extra}` 输出：`{"extra": " "}`  | 
| DATA | 匹配任意字符（换行符除外）零次或多次，不贪婪。 | 5 |  输入：`abc def ghi` 模式：`%{DATA:x} %{DATA:y}` 输出：`{"x": "abc", "y": "def ghi"}`  | 
| GREEDYDATA | 匹配任意字符（换行符除外）零次或多次，贪婪。 | 5 |  输入：`abc def ghi` 模式：`%{GREEDYDATA:x} %{GREEDYDATA:y}` 输出：`{"x": "abc def", "y": "ghi"}`  | 
| GREEDYDATA\$1MULTILINE | 匹配任意字符（包括换行符）零次或多次，贪婪。 | 1 |  输入： `abc` `def` `ghi` 模式：`%{GREEDYDATA_MULTILINE:data}` 输出：`{"data": "abc\ndef\nghi"}`  | 
| QUOTEDSTRING | 将带引号的字符串（单引号或双引号）与转义字符匹配。 | 20 |  输入：`"Hello, world!"` 模式：`%{QUOTEDSTRING:msg}` 输出：`{"msg": "Hello, world!"}`  | 
| UUID | 匹配标准 UUID 格式：8 个十六进制字符，后跟三组 4 个十六进制字符，以 12 个十六进制字符结尾，全部用连字符分隔。 | 20 |  输入：`550e8400-e29b-41d4-a716-446655440000` 模式：`%{UUID:id}` 输出：`{"id": "550e8400-e29b-41d4-a716-446655440000"}`  | 
| URN | 匹配 URN（统一资源名称）语法。 | 20 |  输入：`urn:isbn:0451450523` 模式：`%{URN:urn}` 输出：`{"urn": "urn:isbn:0451450523"}`  | 

**AWS Grok 图案**


| 模式 | 说明 | 最大模式限制 | 示例 | 
| --- | --- | --- | --- | 
|  进行筛选  |  匹配 AWS Amazon 资源名称 (ARNs)，捕获分区（`aws``aws-cn`、或`aws-us-gov`）、服务、区域、账户 ID 以及最多 5 个由斜杠分隔的分层资源标识符。它与冒号之间缺少 ARNs 的信息不匹配。  | 5 |  输入：`arn:aws:iam:us-east-1:123456789012:user/johndoe` 模式：`%{ARN:arn}` 输出：`{"arn": "arn:aws:iam:us-east-1:123456789012:user/johndoe"}`  | 

**联网 grok 模式**


| Grok 模式 | 说明 | 最大模式限制 | 示例 | 
| --- | --- | --- | --- | 
| CISCOMAC | 匹配 4-4-4 十六进制格式的 MAC 地址。 | 20 |  输入：`0123.4567.89AB` 模式：`%{CISCOMAC:MacAddress}` 输出：`{"MacAddress": "0123.4567.89AB"}`  | 
| WINDOWSMAC | 将十六进制格式的 MAC 地址与连字符匹配 | 20 |  输入：`01-23-45-67-89-AB` 模式：`%{WINDOWSMAC:MacAddress}` 输出：`{"MacAddress": "01-23-45-67-89-AB"}`  | 
| COMMONMAC | 将十六进制格式的 MAC 地址与冒号匹配。 | 20 |  输入：`01:23:45:67:89:AB` 模式：`%{COMMONMAC:MacAddress}` 输出：`{"MacAddress": "01:23:45:67:89:AB"}`  | 
| MAC | 匹配 CISCOMAC、WINDOWSMAC 或 COMMONMAC grok 模式之一 | 20 |  输入：`01:23:45:67:89:AB` 模式：`%{MAC:m1}` 输出：`{"m1":"01:23:45:67:89:AB"}`  | 
| IPV6 | 匹配 IPv6 地址，包括压缩表单和 IPv4映射 IPv6 地址。 | 5 |  输入：`2001:db8:3333:4444:5555:6666:7777:8888` 模式：`%{IPV6:ip}` 输出：`{"ip": "2001:db8:3333:4444:5555:6666:7777:8888"}`  | 
| IPV4 | 匹配 IPv4 地址。 | 20 |  输入：`192.168.0.1` 模式：`%{IPV4:ip}` 输出：`{"ip": "192.168.0.1"}`  | 
| IP | 匹配% \$1IPv6\$1 支持 IPv4 的地址或% \$1IPv4\$1 支持的地址 IPv6  | 5 |  输入：`192.168.0.1` 模式：`%{IP:ip}` 输出：`{"ip": "192.168.0.1"}`  | 
| HOSTNAME 或 HOST | 匹配域名，包括子域 | 5 |  输入：`server-01.internal-network.local` 模式：`%{HOST:host}` 输出：`{"host": "server-01.internal-network.local"}`  | 
| IPORHOST | 匹配主机名或 IP 地址 | 5 |  输入：`2001:db8:3333:4444:5555:6666:7777:8888` 模式：`%{IPORHOST:ip}` 输出：`{"ip": "2001:db8:3333:4444:5555:6666:7777:8888"}`  | 
| HOSTPORT | 匹配 %\$1IPORHOST\$1 模式支持的 IP 地址或主机名，后跟冒号和端口号，并将端口号捕获为输出中的“PORT”。 | 5 |  输入：`192.168.1.1:8080` 模式：`%{HOSTPORT:ip}` 输出：`{"ip":"192.168.1.1:8080","PORT":"8080"}`  | 
| URIHOST | 匹配 %\$1IPORHOST\$1 模式支持的 IP 地址或主机名，可后跟冒号和端口号，并将端口捕获为“port”（如果存在）。 | 5 |  输入：`example.com:443 10.0.0.1` 模式：`%{URIHOST:host} %{URIHOST:ip}` 输出：`{"host":"example.com:443","port":"443","ip":"10.0.0.1"}`  | 

**Path grok 模式**


| Grok 模式 | 说明 | 最大模式限制 | 示例 | 
| --- | --- | --- | --- | 
| UNIXPATH | 匹配 URL 路径，可能包含查询参数。 | 20 |  输入：`/search?q=regex` 模式：`%{UNIXPATH:path}` 输出：`{"path":"/search?q=regex"}`  | 
| WINPATH | 匹配 Windows 文件路径。 | 5 |  输入：`C:\Users\John\Documents\file.txt` 模式：`%{WINPATH:path}` 输出：`{"path": "C:\\Users\\John\\Documents\\file.txt"}`  | 
| 路径 | 匹配 URL 或 Windows 文件路径 | 5 |  输入：`/search?q=regex` 模式：`%{PATH:path}` 输出：`{"path":"/search?q=regex"}`  | 
| TTY | 匹配终端和伪终端的 Unix 设备路径。 | 20 |  输入：`/dev/tty1` 模式：`%{TTY:path}` 输出：`{"path":"/dev/tty1"}`  | 
| URIPROTO | 匹配字母，可后跟加号（\$1）字符和其他字母或加号（\$1）字符 | 20 |  输入：`web+transformer` 模式：`%{URIPROTO:protocol}` 输出：`{"protocol":"web+transformer"}`  | 
| URIPATH | 匹配 URI 的路径组件 | 20 |  输入：`/category/sub-category/product_name` 模式：`%{URIPATH:path}` 输出：`{"path":"/category/sub-category/product_name"}`  | 
| URIPARAM | 匹配 URL 查询参数 | 5 |  输入：`?param1=value1&param2=value2` 模式：`%{URIPARAM:url}` 输出：`{"url":"?param1=value1&param2=value2"}`  | 
| URIPATHPARAM | 匹配 URI 路径，可后跟查询参数 | 5 |  输入：`/category/sub-category/product?id=12345&color=red` 模式：`%{URIPATHPARAM:path}` 输出：`{"path":"/category/sub-category/product?id=12345&color=red"}`  | 
| URI | 匹配完整的 URI | 5 |  输入：`https://user:password@example.com/path/to/resource?param1=value1&param2=value2` 模式：`%{URI:uri}` 输出：`{"path":"https://user:password@example.com/path/to/resource?param1=value1&param2=value2"}`  | 

**日期和时间 grok 模式**


| Grok 模式 | 说明 | 最大模式限制 | 示例 | 
| --- | --- | --- | --- | 
| MONTH | 将完整的或缩写的英文月份名称匹配为完整单词 | 20 |  输入：`Jan` 模式：`%{MONTH:month}` 输出：`{"month":"Jan"}` 输入：`January` 模式：`%{MONTH:month}` 输出：`{"month":"January"}`  | 
| MONTHNUM | 匹配 1 到 12 之间的月份数字，个位数月份可选择使用前导零。 | 20 |  输入：`5` 模式：`%{MONTHNUM:month}` 输出：`{"month":"5"}` 输入：`05` 模式：`%{MONTHNUM:month}` 输出：`{"month":"05"}`  | 
| MONTHNUM2 | 匹配 01 到 12 之间的两位数月份数字。 | 20 |  输入：`05` 模式：`%{MONTHNUM2:month}` 输出：`{"month":"05"}`  | 
| MONTHDAY | 匹配月份中的日期，从 1 到 31，可选择使用前导零。 | 20 |  输入：`31` 模式：`%{MONTHDAY:monthDay}` 输出：`{"monthDay":"31"}`  | 
| YEAR | 匹配两位或四位数的年份 | 20 |  输入：`2024` 模式：`%{YEAR:year}` 输出：`{"year":"2024"}` 输入：`24` 模式：`%{YEAR:year}` 输出：`{"year":"24"}`  | 
| DAY | 匹配完整或缩写的日期名称。 | 20 |  输入：`Tuesday` 模式：`%{DAY:day}` 输出：`{"day":"Tuesday"}`  | 
| HOUR | 以 24 小时制格式匹配小时，可选择使用前导零 (0)0-23。 | 20 |  输入：`22` 模式：`%{HOUR:hour}` 输出：`{"hour":"22"}`  | 
| MINUTE | 匹配分钟（00-59）。 | 20 |  输入：`59` 模式：`%{MINUTE:min}` 输出：`{"min":"59"}`  | 
| SECOND | 匹配代表秒 (0)0-60 的数字，可后跟小数点或冒号，以及一个或多个数字表示小数分钟 | 20 |  输入：`3` 模式：`%{SECOND:second}` 输出：`{"second":"3"}` 输入：`30.5` 模式：`%{SECOND:minSec}` 输出：`{"minSec":"30.5"}` 输入：`30:5` 模式：`%{SECOND:minSec}` 输出：`{"minSec":"30:5"}`  | 
| TIME | 将时间格式与小时、分钟和秒匹配，格式为 (H)H:mm:(s)s。秒包括闰秒 (0)0-60。 | 20 |  输入：`09:45:32` 模式：`%{TIME:time}` 输出：`{"time":"09:45:32"}`  | 
| DATE\$1US | 以 (M)M/(d)d/(yy)yy 或 (M)M-(d)d-(yy)yy 格式匹配日期。 | 20 |  输入：`11/23/2024` 模式：`%{DATE_US:date}` 输出：`{"date":"11/23/2024"}` 输入：`1-01-24` 模式：`%{DATE_US:date}` 输出：`{"date":"1-01-24"}`  | 
| DATE\$1EU | 以 (d)d/(M)M/(yy)yy、(d)d-(M)M-(yy)yy 或 (d)d.(M)M.(yy)yy 格式匹配日期。 | 20 |  输入：`23/11/2024` 模式：`%{DATE_EU:date}` 输出：`{"date":"23/11/2024"}` 输入：`1.01.24` 模式：`%{DATE_EU:date}` 输出：`{"date":"1.01.24"}`  | 
| ISO8601\$1时区 | 将 UTC 偏移量“Z”或时区偏移量与可选冒号进行匹配，格式为 [\$1-](H)H(:)mm。 | 20 |  输入：`+05:30` 模式：`%{ISO8601_TIMEZONE:tz}` 输出：`{"tz":"+05:30"}` 输入：`-530` 模式：`%{ISO8601_TIMEZONE:tz}` 输出：`{"tz":"-530"}` 输入：`Z` 模式：`%{ISO8601_TIMEZONE:tz}` 输出：`{"tz":"Z"}`  | 
| ISO8601\$1SECOND | 匹配代表秒 (0)0-60 的数字，可后跟小数点或冒号，以及一个或多个数字表示小数秒 | 20 |  输入：`60` 模式：`%{ISO8601_SECOND:second}` 输出：`{"second":"60"}`  | 
| 时间戳\$1 ISO8601 | 将 ISO8601 日期时间格式 (yy) yy-(M) M-(d) dT (H) H: mm: (s) (Z\$1 [\$1-] (H) H: mm) 与可选的秒数和时区进行匹配。 | 20 |  输入：`2023-05-15T14:30:00+05:30` 模式：`%{TIMESTAMP_ISO8601:timestamp}` 输出：`{"timestamp":"2023-05-15T14:30:00+05:30"}` 输入：`23-5-1T1:25+5:30` 模式：`%{TIMESTAMP_ISO8601:timestamp}` 输出：`{"timestamp":"23-5-1T1:25+5:30"}` 输入：`23-5-1T1:25Z` 模式：`%{TIMESTAMP_ISO8601:timestamp}` 输出：`{"timestamp":"23-5-1T1:25Z"}`  | 
| DATE | 使用 %\$1DATE\$1US\$1 匹配美国格式的日期，或者使用 %\$1DATE\$1EU\$1 匹配欧盟格式的日期 | 20 |  输入：`11/29/2024` 模式：`%{DATE:date}` 输出：`{"date":"11/29/2024"}` 输入：`29.11.2024` 模式：`%{DATE:date}` 输出：`{"date":"29.11.2024"}`  | 
| DATESTAMP | 匹配 %\$1DATE\$1，后跟 %\$1TIME\$1 模式，用空格或连字符分隔。 | 20 |  输入：`29-11-2024 14:30:00` 模式：`%{DATESTAMP:dateTime}` 输出：`{"dateTime":"29-11-2024 14:30:00"}`  | 
| TZ | 匹配常见的时区缩写（PST、PDT、MST、MDT、CST CDT、EST、EDT、UTC）。 | 20 |  输入：`PDT` 模式：`%{TZ:tz}` 输出：`{"tz":"PDT"}`  | 
| 日期戳\$1 RFC822 | 按以下格式匹配日期和时间：日 MonthName (D) D (YY) YY (H) H: mm: (s) s 时区 | 20 |  输入：`Monday Jan 5 23 1:30:00 CDT` 模式：`%{DATESTAMP_RFC822:dateTime}` 输出：`{"dateTime":"Monday Jan 5 23 1:30:00 CDT"}` 输入：`Mon January 15 2023 14:30:00 PST` 模式：`%{DATESTAMP_RFC822:dateTime}` 输出：`{"dateTime":"Mon January 15 2023 14:30:00 PST"}`  | 
| 日期戳\$1 RFC2822 | 匹配 RFC2822 日期时间格式：日，(d) d (yy) yy MonthName (H) H: mm: (s) s Z\$1 [\$1-] (H) H: mm | 20 |  输入：`Mon, 15 May 2023 14:30:00 +0530` 模式：`%{DATESTAMP_RFC2822:dateTime}` 输出：`{"dateTime":"Mon, 15 May 2023 14:30:00 +0530"}` 输入：`Monday, 15 Jan 23 14:30:00 Z` 模式：`%{DATESTAMP_RFC2822:dateTime}` 输出：`{"dateTime":"Monday, 15 Jan 23 14:30:00 Z"}`  | 
| DATESTAMP\$1OTHER | 按格式匹配日期和时间：日 MonthName (d) d (H) H: mm: (s) s 时区 (yy) yy | 20 |  输入：`Mon May 15 14:30:00 PST 2023` 模式：`%{DATESTAMP_OTHER:dateTime}` 输出：`{"dateTime":"Mon May 15 14:30:00 PST 2023"}`  | 
| DATESTAMP\$1EVENTLOG | 匹配不带分隔符的紧凑日期时间格式：(yy)yyMM(d)d(H)Hmm(s)s | 20 |  输入：`20230515143000` 模式：`%{DATESTAMP_EVENTLOG:dateTime}` 输出：`{"dateTime":"20230515143000"}`  | 

**日志 grok 模式**


| Grok 模式 | 说明 | 最大模式限制 | 示例 | 
| --- | --- | --- | --- | 
| LOGLEVEL | 匹配不同大小写和缩写形式的标准日志级别，包括：Alert/ALERT、Trace/TRACE、Debug/DEBUG、Notice/NOTICE、Info/INFO、Warn/Warning/WARN/WARNING、Err/Error/ERR/ERROR、Crit/Critical/CRIT/CRITICAL、Fatal/FATAL、Severe/SEVERE、Emerg/Emergency/EMERG/EMERGENCY | 20 |  输入：`INFO` 模式：`%{LOGLEVEL:logLevel}` 输出：`{"logLevel":"INFO"}`  | 
| HTTPDATE | 匹配日志文件中经常使用的日期和时间格式。格式：(d) d/MonthName/(yy) yy :( H) H: mm: (s) s 时区：匹配完整或缩写的英文月份名称（例如 MonthName：“一月” 或 “一月”）时区：匹配% \$1INT\$1 grok 模式 | 20 |  输入：`23/Nov/2024:14:30:00 +0640` 模式：`%{HTTPDATE:date}` 输出：`{"date":"23/Nov/2024:14:30:00 +0640"}`  | 
| SYSLOGTIMESTAMP | 将日期格式与 MonthName (d) d (H) H: mm :( s) s 匹配完整或缩写的英文月份名称（例如 MonthName：“Jan” 或 “January”） | 20 |  输入：`Nov 29 14:30:00` 模式：`%{SYSLOGTIMESTAMP:dateTime}` 输出：`{"dateTime":"Nov 29 14:30:00"}`  | 
| PROG | 匹配由字母、数字、点、下划线、正斜杠、百分号和连字符组成的程序名称。 | 20 |  输入：`user.profile/settings-page` 模式：`%{PROG:program}` 输出：`{"program":"user.profile/settings-page"}`  | 
| SYSLOGPROG | 匹配 PROG grok 模式，可后跟方括号中的进程 ID。 | 20 |  输入：`user.profile/settings-page[1234]` 模式：`%{SYSLOGPROG:programWithId}` 输出：`{"programWithId":"user.profile/settings-page[1234]","program":"user.profile/settings-page","pid":"1234"}`  | 
| SYSLOGH | 匹配 %\$1HOST\$1 或 %\$1IP\$1 模式 | 5 |  输入：`2001:db8:3333:4444:5555:6666:7777:8888` 模式：`%{SYSLOGHOST:ip}` 输出：`{"ip": "2001:db8:3333:4444:5555:6666:7777:8888"}`  | 
| SYSLOGFACILITY | 匹配十进制格式的 syslog 优先级。该值应括在尖括号（<>）中。 | 20 |  输入：`<13.6>` 模式：`%{SYSLOGFACILITY:syslog}` 输出：`{"syslog":"<13.6>","facility":"13","priority":"6"}`  | 

**常见的 log grok 模式**

您可以使用预定义的自定义 grok 模式来匹配 Apache、NGINX 和 Syslog 协议（RFC 5424）日志格式。使用这些特定模式时，它们必须是匹配配置中的第一个模式，并且不能有其他模式位于它们之前。此外，后面只有跟有一个 **DATA**。**GREEDYDATA** 或 **GREEDYDATA\$1MULTILINE** 模式。


| Grok 模式 | 说明 | 最大模式限制 | 
| --- | --- | --- | 
|  APACHE\$1ACCESS\$1LOG | 匹配 Apache 访问日志 | 1 | 
|  NGINX\$1ACCESS\$1LOG | 匹配 NGINX 访问日志 | 1 | 
|  SYSLOG5424 | 匹配 Syslog 协议（RFC 5424）日志 | 1 | 

下面展示了使用这些常见日志格式模式的有效和无效示例。

```
"%{NGINX_ACCESS_LOG} %{DATA}" // Valid
"%{SYSLOG5424}%{DATA:logMsg}" // Valid
"%{APACHE_ACCESS_LOG} %{GREEDYDATA:logMsg}" // Valid
"%{APACHE_ACCESS_LOG} %{SYSLOG5424}" // Invalid (multiple common log patterns used)
"%{NGINX_ACCESS_LOG} %{NUMBER:num}" // Invalid (Only GREEDYDATA and DATA patterns are supported with common log patterns)
"%{GREEDYDATA:logMsg} %{SYSLOG5424}" // Invalid (GREEDYDATA and DATA patterns are supported only after common log patterns)
```

#### 常见日志格式示例
<a name="Common-Log-Examples"></a>

##### Apache 日志示例
<a name="Apache-Log-Example"></a>

日志示例：

```
127.0.0.1 - - [03/Aug/2023:12:34:56 +0000] "GET /page.html HTTP/1.1" 200 1234
```

转换器：

```
[
     {
        "grok": {
            "match": "%{APACHE_ACCESS_LOG}"
        }
    }
]
```

输出：

```
{
    "request": "/page.html",
    "http_method": "GET",
    "status_code": 200,
    "http_version": "1.1",
    "response_size": 1234,
    "remote_host": "127.0.0.1",
    "timestamp": "2023-08-03T12:34:56Z"
}
```

##### NGINX 日志示例
<a name="NGINX-Log-Example"></a>

日志示例：

```
192.168.1.100 - Foo [03/Aug/2023:12:34:56 +0000] "GET /account/login.html HTTP/1.1" 200 42 "https://www.amazon.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
```

转换器：

```
[
     {
        "grok": {
            "match": "%{NGINX_ACCESS_LOG}"
        }
    }
]
```

输出：

```
{
    "request": "/account/login.html",
    "referrer": "https://www.amazon.com/",
    "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
    "http_method": "GET",
    "status_code": 200,
    "auth_user": "Foo",
    "http_version": "1.1",
    "response_size": 42,
    "remote_host": "192.168.1.100",
    "timestamp": "2023-08-03T12:34:56Z"
}
```

##### Syslog 协议（RFC 5424）日志示例
<a name="syslog5424-Log-Example"></a>

日志示例：

```
<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut="3" eventSource= "Application" eventID="1011"][examplePriority@32473 class="high"]
```

转换器：

```
[
     {
        "grok": {
            "match": "%{SYSLOG5424}"
        }
    }
]
```

输出：

```
{
  "pri": 165,
  "version": 1,
  "timestamp": "2003-10-11T22:14:15.003Z",
  "hostname": "mymachine.example.com",
  "app": "evntslog",
  "msg_id": "ID47",
  "structured_data": "exampleSDID@32473 iut=\"3\" eventSource= \"Application\" eventID=\"1011\"",
  "message": "[examplePriority@32473 class=\"high\"]"
}
```

## csv
<a name="CloudWatch-Logs-Transformation-csv"></a>

**csv** 处理器将日志事件中的逗号分隔值（CSV）解析为列。


| 字段 | 说明 | 必填？ | 默认 | 限制 | 
| --- | --- | --- | --- | --- | 
|  source | 日志事件中待解析字段的路径 |  否 | `@message`  | 最大长度：128 最大嵌套键深度：3 | 
|  分隔符 | 用于分隔原始逗号分隔值日志事件中的每列的字符 |  否 | `,`  | 最大长度：1，除非值为 `\t` 或 `\s`  | 
|  quoteCharacter | 用作单列数据的文本限定符的字符 |  否 | `"`  | 最大长度：1  | 
|  列 | 转换后的日志事件中列要使用的名称列表。 |  否 | `[column_1, column_2 ...]`  | CSV 最大列数：100 最大长度：128 最大嵌套键深度：3  | 
|  destination | 放置转换后的键值对的父字段 |  否 | `Root node`  | 最大长度：128 最大嵌套键深度：3  | 

将 `delimiter` 设置为 `\t` 将使用制表符分隔每列，`\t` 将使用单个空格字符分隔每列。

**示例**

假设摄取的部分日志事件如下所示：

```
'Akua Mansa':28:'New York: USA'
```

假设我们仅使用 **csv** 处理器：

```
[
     {
        "csv": {
            "delimiter": ":",
            "quoteCharacter": "'"
        }
    }
]
```

转换后的日志事件将如下所示。

```
{
  "column_1": "Akua Mansa",
  "column_2": "28",
  "column_3": "New York: USA"
}
```

**示例 2**

假设摄取的日志事件如下所示：

```
{
    "timestamp": "2024-11-23T16:03:12Z",
    "type": "user_data",
    "logMsg": "'Akua Mansa':28:'New York: USA'"
}
```

假设我们将事件解析为 JSON，他们使用 cs **v** 处理器解析一个 JSON 字段，指定列名和目标：

```
[
    {
        "parseJSON": {}
    },
    {
        "csv": {
            "source": "logMsg",
            "delimiter": ":",
            "quoteCharacter": "'",
            "columns":["name","age","location"],
            "destination": "msg"
        }
    }
]
```

转换后的日志事件将如下所示。

```
{
    "timestamp": "2024-11-23T16:03:12Z",
    "logMsg": "'Akua Mansa':28:'New York: USA'",
    "type": "user_data",
    "msg": {
        "name": "Akua Mansa",
        "age": "28",
        "location": "New York: USA"
    }
}
```

## parseKeyValue
<a name="CloudWatch-Logs-Transformation-parseKeyValue"></a>

使用**parseKeyValue**处理器将指定字段解析为键值对。您可以使用以下选项自定义处理器以解析字段信息。


| 字段 | 说明 | 必填？ | 默认 | 限制 | 
| --- | --- | --- | --- | --- | 
|  source | 日志事件中待解析字段的路径 |  否 | `@message`  | 最大长度：128 最大嵌套键深度：3 | 
|  destination | 要将提取的键值对放入的目标字段 |  否 |   | 最大长度：128  | 
|  fieldDelimiter | 在原始日志事件的键值对之间使用的字段分隔符字符串 |  否 | `&`  | 最大长度：128  | 
|  keyValueDelimiter | 在转换后的日志事件中每对的键和值之间使用的分隔符字符串 |  否 | `=`  | 最大长度：128  | 
|  nonMatchValue | 当键值对未成功拆分时要在结果的值字段中插入的值。 |  否 |   | 最大长度：128  | 
|  keyPrefix | 如果要为所有转换后的键添加前缀，请在此处指定。 |  否 |   | 最大长度：128  | 
|  overwriteIfExists | 如果目标键已存在，是否覆盖该键 |  否 | `false`  |   | 

**示例**

以以下日志事件为例：

```
key1:value1!key2:value2!key3:value3!key4
```

假设我们使用下面的处理器配置：

```
[
    {
        "parseKeyValue": {
            "destination": "new_key",
            "fieldDelimiter": "!",
            "keyValueDelimiter": ":",
            "nonMatchValue": "defaultValue",
            "keyPrefix": "parsed_"
        }
    }
]
```

转换后的日志事件将如下所示。

```
{
  "new_key": {
    "parsed_key1": "value1",
    "parsed_key2": "value2",
    "parsed_key3": "value3",
    "parsed_key4": "defaultValue"
  }
}
```