

# 配置 JSON 和纯文本日志格式
<a name="monitoring-cloudwatchlogs-logformat"></a>

将日志输出捕获为 JSON 键值对，可以更轻松地在调试函数时进行搜索和筛选。使用 JSON 格式的日志，您还可以在日志中添加标签和上下文信息。这可以帮助您对大量日志数据执行自动分析。除非您的开发工作流程依赖于使用纯文本格式 Lambda 日志的现有工具，否则我们建议您为日志格式选择 JSON。

**Lambda 托管实例**  
Lambda 托管实例仅支持 JSON 日志格式。当您创建托管实例函数时，Lambda 会自动将日志格式配置为 JSON，且您无法将其更改为纯文本格式。有关托管实例的更多信息，请参阅[Lambda 托管实例](lambda-managed-instances.md)。

对于所有 Lambda 托管的运行时系统，您可以选择将函数的系统日志以非结构化纯文本格式还是 JSON 格式发送到 CloudWatch Logs。系统日志是由 Lambda 生成的日志，有时也被称为平台事件日志。

对于[支持的运行时系统](#monitoring-cloudwatchlogs-logformat-supported)，当您使用支持的内置日志记录方法之一时，Lambda 还能以结构化的 JSON 格式输出函数的应用程序日志（您的函数代码生成的日志）。当您为这些运行时系统配置函数的日志格式时，您选择的配置将同时应用于系统日志和应用程序日志。

对于支持的运行时系统，如果您的函数使用支持的日志库或方法，则无需对 Lambda 的现有代码进行任何更改，即可在结构化的 JSON 中捕获日志。

**注意**  
使用 JSON 日志格式可以添加额外的元数据，并将日志消息编码为包含一系列键值对的 JSON 对象。因此，函数日志消息的大小可能会增加。

## 支持的运行时系统和日志记录方法
<a name="monitoring-cloudwatchlogs-logformat-supported"></a>

 Lambda 目前支持为以下运行时系统输出 JSON 结构化应用程序日志的选项。


| 语言 | 支持的版本 | 
| --- | --- | 
| Java | Amazon Linux 1 上除 Java 8 之外的所有 Java 运行时系统 | 
| .NET | .NET 8 及更高版本 | 
| Node.js | Node.js 16 及更高版本 | 
| Python | Python 3.8 及更高版本 | 
| Rust | 不适用 | 

为了让 Lambda 以结构化的 JSON 格式将函数的应用程序日志发送到 CloudWatch，您的函数必须使用以下内置日志记录工具来输出日志：
+ **Java**：`LambdaLogger` 记录器或 Log4j2。有关更多信息，请参阅 [Java Lambda 函数日志记录和监控](java-logging.md)。
+ **.NET**：上下文对象上的 `ILambdaLogger` 实例。有关更多信息，请参阅 [C\$1 Lambda 函数日志记录和监控](csharp-logging.md)。
+ **Node.js**：控制台方法 `console.trace`、`console.debug`、`console.log`、`console.info`、`console.error` 和 `console.warn`。有关更多信息，请参阅 [Node.js Lambda 函数日志记录和监控](nodejs-logging.md)。
+ **Python**：标准 Python `logging` 库。有关更多信息，请参阅 [Python Lambda 函数日志记录和监控](python-logging.md)。
+ **Rust**：`tracing` crate。有关更多信息，请参阅 [Rust Lambda 函数日志记录和监控](rust-logging.md)。

对于其他托管 Lambda 运行时系统，Lambda 本身目前仅支持以结构化的 JSON 格式捕获系统日志。但是，您仍然可以在任何运行时系统中使用输出 JSON 格式日志输出的日志记录工具（例如 Powertools for AWS Lambda），以结构化的 JSON 格式捕获应用程序日志。

## 默认日志格式
<a name="monitoring-cloudwatchlogs-format-default"></a>

目前，所有 Lambda 运行时系统的默认日志格式均为纯文本。对于 Lambda 托管实例，日志格式始终为 JSON，且无法更改。

如果您已经在使用像 Powertools for AWS Lambda 这样的日志库来生成 JSON 结构化格式的函数日志，则在选择 JSON 日志格式后无需更改代码。Lambda 不会对任何已采用 JSON 编码的日志进行双重编码，因此仍将像以前一样捕获函数的应用程序日志。

## 系统日志的 JSON 格式
<a name="monitoring-cloudwatchlogs-JSON-system"></a>

当您将函数的日志格式配置为 JSON 时，每个系统日志项（平台事件）都将被捕获为一个 JSON 对象，并且包含带有以下键的键值对：
+ `"time"` - 生成日志消息的时间
+ `"type"` - 正在记录的事件类型
+ `"record"` - 日志输出的内容

`"record"` 值的格式因所记录的事件类型而异。有关更多信息，请参阅 [遥测 API `Event` 对象类型](telemetry-schema-reference.md#telemetry-api-events)。有关分配给系统日志事件的日志级别的更多信息，请参阅 [系统日志级别的事件映射](monitoring-cloudwatchlogs-log-level.md#monitoring-cloudwatchlogs-log-level-mapping)。

为了进行比较，以下两个示例以纯文本和结构化的 JSON 格式显示了相同的日志输出。请注意，在大多数情况下，系统日志事件以 JSON 格式输出时所含的信息要多于以纯文本格式输出时所含的信息。

**Example 纯文本：**  

```
2024-03-13 18:56:24.046000 fbe8c1   INIT_START  Runtime Version: python:3.12.v18  Runtime Version ARN: arn:aws:lambda:eu-west-1::runtime:edb5a058bfa782cb9cedc6d534ac8b8c193bc28e9a9879d9f5ebaaf619cd0fc0
```

**Example 结构化的 JSON：**  

```
{
  "time": "2024-03-13T18:56:24.046Z",
  "type": "platform.initStart",
  "record": {
    "initializationType": "on-demand",
    "phase": "init",
    "runtimeVersion": "python:3.12.v18",
    "runtimeVersionArn": "arn:aws:lambda:eu-west-1::runtime:edb5a058bfa782cb9cedc6d534ac8b8c193bc28e9a9879d9f5ebaaf619cd0fc0"
  }
}
```

**注意**  
[使用遥测 API 访问扩展的实时遥测数据](telemetry-api.md) 始终以 JSON 格式发出平台事件，例如 `START` 和 `REPORT`。配置 Lambda 发送到 CloudWatch 的系统日志的格式不会影响 Lambda 遥测 API 的行为。

## 应用程序日志的 JSON 格式
<a name="monitoring-cloudwatchlogs-JSON-application"></a>

当您将函数的日志格式配置为 JSON 时，使用支持的日志记录库和方法编写的应用程序日志输出将被捕获为 JSON 对象，其中包含带有以下键的键值对。
+ `"timestamp"` - 生成日志消息的时间
+ `"level"` - 分配给消息的日志级别
+ `"message"` - 日志消息的内容
+ `"requestId"`（Python、.NET 和 Node.js）或 `"AWSrequestId"`（Java）：函数调用的唯一请求 ID

根据函数使用的运行时系统和日志记录方法，此 JSON 对象还可能包含其他密钥对。例如，在 Node.js 中，如果函数通过 `console` 方法使用多个参数记录错误对象，则 JSON 对象将包含带有键 `errorMessage`、`errorType`、和 `stackTrace` 的额外键值对。要了解有关不同 Lambda 运行时系统中的 JSON 格式日志的更多信息，请参阅 [Python Lambda 函数日志记录和监控](python-logging.md)、[Node.js Lambda 函数日志记录和监控](nodejs-logging.md) 和 [Java Lambda 函数日志记录和监控](java-logging.md)。

**注意**  
对于系统日志和应用程序日志，Lambda 用于时间戳值的键不同。对于系统日志，Lambda 使用密钥 `"time"` 来与遥测 API 保持一致。对于应用程序日志，Lambda 遵循支持的运行时系统并使用 `"timestamp"` 的惯例。

为了进行比较，以下两个示例以纯文本和结构化的 JSON 格式显示了相同的日志输出。

**Example 纯文本：**  

```
2024-10-27T19:17:45.586Z 79b4f56e-95b1-4643-9700-2807f4e68189 INFO some log message
```

**Example 结构化的 JSON：**  

```
{
    "timestamp":"2024-10-27T19:17:45.586Z",
    "level":"INFO",
    "message":"some log message",
    "requestId":"79b4f56e-95b1-4643-9700-2807f4e68189"
}
```

## 设置函数的日志格式
<a name="monitoring-cloudwatchlogs-set-format"></a>

要配置函数的日志格式，您可以使用 Lambda 控制台或 AWS Command Line Interface（AWS CLI）。您还可以使用 [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html) 和 [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html) Lambda API 命令、AWS Serverless Application Model（AWS SAM）[AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) 资源以及 CloudFormation [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html) 资源来配置函数的日志格式。

更改函数的日志格式不会影响 CloudWatch Logs 中存储的现有日志。只有新的日志才会使用更新的格式。

如果您将函数的日志格式更改为 JSON 且未设置日志级别，则 Lambda 会自动将函数的应用程序日志级别和系统日志级别设置为 INFO。这意味着 Lambda 仅向 CloudWatch Logs 发送 INFO 及以下级别的日志输出。要了解有关应用程序和系统日志级别筛选的更多信息，请参阅 [日志级别筛选](monitoring-cloudwatchlogs-log-level.md) 

**注意**  
对于 Python 运行时系统，当函数的日志格式设置为纯文本时，默认的日志级别设置为 WARN。这意味着 Lambda 仅向 CloudWatch Logs 发送 WARN 及以下级别的日志输出。将函数的日志格式更改为 JSON 可更改此默认行为。要了解有关 Python 中的日志记录的更多信息，请参阅 [Python Lambda 函数日志记录和监控](python-logging.md)。

对于发出嵌入式指标格式（EMF）日志的 Node.js 函数，将函数的日志格式更改为 JSON 可能会导致 CloudWatch 无法识别您的指标。

**重要**  
如果您的函数使用 Powertools for AWS Lambda（TypeScript）或开源的 EMF 客户端库来发出 EMF 日志，请将 [Powertools](https://github.com/aws-powertools/powertools-lambda-typescript) 和 [EMF](https://www.npmjs.com/package/aws-embedded-metrics) 库更新到最新版本，以确保 CloudWatch 能够继续正确解析您的日志。如果您切换到 JSON 日志格式，我们还建议您进行测试以确保与函数的嵌入式指标兼容。有关发出 EMF 日志的 node.js 函数的更多建议，请参阅 [使用带有结构化的 JSON 日志的嵌入式指标格式（EMF）客户端库](nodejs-logging.md#nodejs-logging-advanced-emf)。

**配置函数的日志格式（控制台）**

1. 打开 Lamba 控制台的[函数](https://console.aws.amazon.com/lambda/home#/functions)页面。

1. 选择函数

1. 在函数配置页面上，选择**监控和操作工具**。

1. 在**日志记录配置**窗格中，选择**编辑**。

1. 在**日志内容**下，为**日志格式**选择**文本**或 **JSON**。

1. 选择**保存**。

**要更改现有函数的日志格式（AWS CLI）**
+ 要更改现有函数的日志格式，请使用 [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) 命令。将 `LoggingConfig` 中的 `LogFormat` 选项设置为 `JSON` 或 `Text`。

  ```
  aws lambda update-function-configuration \
    --function-name myFunction \
    --logging-config LogFormat=JSON
  ```

**要在创建函数时设置日志格式（AWS CLI）**
+ 要在创建新函数时配置日志格式，请使用 [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) 命令中的 `--logging-config` 选项。将 `LogFormat` 设置为 `JSON` 或 `Text`。以下示例命令创建 Node.js 函数，该函数以结构化 JSON 格式输出日志。

  如果您在创建函数时未指定日志格式，Lambda 将使用您选择的运行时系统版本的默认日志格式。有关默认日志记录格式的信息，请参阅 [默认日志格式](#monitoring-cloudwatchlogs-format-default)。

  ```
  aws lambda create-function \ 
    --function-name myFunction \ 
    --runtime nodejs24.x \
    --handler index.handler \
    --zip-file fileb://function.zip \
    --role arn:aws:iam::123456789012:role/LambdaRole \
    --logging-config LogFormat=JSON
  ```