

# Ruby Lambda 函数日志记录和监控
<a name="ruby-logging"></a>

AWS Lambda 将代表您自动监控 Lambda 函数并将日志记录发送至 Amazon CloudWatch。您的 Lambda 函数带有一个 CloudWatch Logs 日志组以及函数的每个实例的日志流。Lambda 运行时环境会将每个调用的详细信息发送到日志流，然后中继函数代码的日志和其他输出。有关更多信息，请参阅 [将 Lambda 函数日志发送到 CloudWatch Logs](monitoring-cloudwatchlogs.md)。

本页旨在介绍如何从 Lambda 函数的代码生成日志输出，并使用 AWS Command Line Interface、Lambda 控制台或 CloudWatch 控制台访问日志。

**Topics**
+ [创建返回日志的函数](#ruby-logging-output)
+ [在 Ruby 中使用 Lambda 高级日志记录控件](#ruby-logging-advanced)
+ [在 Lambda 控制台中查看日志](#ruby-logging-console)
+ [在 CloudWatch 控制台中查看日志](#ruby-logging-cwconsole)
+ [使用 AWS Command Line Interface（AWS CLI）查看日志](#ruby-logging-cli)
+ [删除日志](#ruby-logging-delete)
+ [使用 Ruby 日志记录库](#ruby-logging-lib)

## 创建返回日志的函数
<a name="ruby-logging-output"></a>

要从函数代码输出日志，您可以使用 `puts` 语句或使用写入到 `stdout` 或 `stderr` 的任何日志记录库。以下示例记录环境变量和事件对象的值。

**Example lambda\_function.rb**  

```
# lambda_function.rb

def handler(event:, context:)
    puts "## ENVIRONMENT VARIABLES"
    puts ENV.to_a
    puts "## EVENT"
    puts event.to_a
end
```

**Example 日志格式**  

```
START RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95 Version: $LATEST
## ENVIRONMENT VARIABLES
environ({'AWS_LAMBDA_LOG_GROUP_NAME': '/aws/lambda/my-function', 'AWS_LAMBDA_LOG_STREAM_NAME': '2020/01/31/[$LATEST]3893xmpl7fac4485b47bb75b671a283c', 'AWS_LAMBDA_FUNCTION_NAME': 'my-function', ...})
## EVENT
{'key': 'value'}
END RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95
REPORT RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95  Duration: 15.74 ms  Billed Duration: 147 ms Memory Size: 128 MB Max Memory Used: 56 MB  Init Duration: 130.49 ms
XRAY TraceId: 1-5e34a614-10bdxmplf1fb44f07bc535a1   SegmentId: 07f5xmpl2d1f6f85 Sampled: true
```

Ruby 运行时记录每次调用的 `START`、`END` 和 `REPORT` 行。报告行提供了以下详细信息：

**REPORT 行数据字段**
+ **RequestId** – 调用的唯一请求 ID。
+ **Duration**（持续时间）– 函数的处理程序方法处理事件所花费的时间。
+ **Billed Duration**（计费持续时间）– 针对调用计费的时间量。
+ **Memory Size**（内存大小）– 分配给函数的内存量。
+ **Max Memory Used**（最大内存使用量）– 函数使用的内存量。如果调用共享执行环境，Lambda 会报告所有调用使用的最大内存。此行为可能会导致报告值高于预期。
+ **Init Duration**（初始持续时间）– 对于提供的第一个请求，为运行时在处理程序方法外部加载函数和运行代码所花费的时间。
+ **XRAY TraceId** – 对于追踪的请求，为 [AWS X-Ray 追踪 ID](services-xray.md)。
+ **SegmentId** – 对于追踪的请求，为 X-Ray 分段 ID。
+ **Sampled**（采样）– 对于追踪的请求，为采样结果。

如需更详细的日志，请使用 [使用 Ruby 日志记录库](#ruby-logging-lib)。

## 在 Ruby 中使用 Lambda 高级日志记录控件
<a name="ruby-logging-advanced"></a>

为了让您可以更好地控制如何捕获、处理和使用函数日志，Lambda 提供在 Ruby 中使用高级日志记录控件的功能。对于 Ruby 4.0 及更高版本的运行时，您可以配置以下日志记录选项：
+ **日志格式** - 为函数日志选择纯文本或结构化的 JSON 格式
+ **日志级别** - 对于 JSON 格式的日志，选择 Lambda 发送到 Amazon CloudWatch 的日志的详细信息级别，例如 ERROR、DEBUG 或 INFO
+ **日志组** - 选择您的函数发送日志的目标 CloudWatch 日志组

有关这些日志记录选项的更多信息以及如何通过配置来使用函数的说明，请参阅 [为 Lambda 函数配置高级日志记录控件](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)。

要详细了解如何在 Ruby Lambda 函数中使用日志格式和日志级别选项，请参阅以下各节中的指南。

### 在 Ruby 中使用结构化的 JSON 日志
<a name="ruby-logging-json"></a>

如果您为函数的日志格式选择 JSON，Lambda 会将 Ruby 标准 `Logger` 库输出的日志作为结构化的 JSON 发送到 CloudWatch。每个 JSON 日志对象包含至少四个键值对和以下键：
+ `"timestamp"` - 生成日志消息的时间
+ `"level"` - 分配给消息的日志级别
+ `"message"` - 日志消息的内容
+ `"requestId"` - 函数调用的唯一请求 ID

Ruby `Logger` 库还可以向此 JSON 对象添加其他键值对，例如 `"logger"`。

以下各节中的示例显示了当您将函数的日志格式配置为 JSON 时，如何在 CloudWatch Logs 中捕获使用 Ruby `Logger` 库生成的日志输出。

请注意，如果您使用 `puts` 方法生成基本日志输出（如 [创建返回日志的函数](#ruby-logging-output) 中所述），则即使您将函数的日志记录格式配置为 JSON，Lambda 也会将这些输出捕获为纯文本。

### 使用 Ruby Logger 库的标准 JSON 日志输出
<a name="ruby-logging-json-standard"></a>

以下示例代码段和日志输出显示了当函数的日志格式被设置为 JSON 时，如何在 CloudWatch Logs 中捕获使用 Ruby `Logger` 库生成的标准日志输出。

**Example Ruby 日志记录代码示例**  

```
require 'logger'

def lambda_handler(event:, context:)
  logger = Logger.new($stdout)
  logger.info("Inside the handler function")
end
```

**Example JSON 日志记录示例**  

```
{
    "timestamp": "2025-10-27T19:17:45.586Z",
    "level": "INFO",
    "message": "Inside the handler function",
    "requestId": "79b4f56e-95b1-4643-9700-2807f4e68189"
}
```

### 在 JSON 中记录额外的参数
<a name="ruby-logging-json-extra-params"></a>

当函数的日志格式设置为 JSON 时，通过将额外键值对的哈希传递到日志输出，您还可以使用 Ruby `Logger` 库记录其他参数。

**Example Ruby 日志记录代码示例**  

```
require 'logger'
require 'json'

def lambda_handler(event:, context:)
  logger = Logger.new($stdout)
  extra_params = { "a" => "b", "b" => [3] }
  logger.info({ message: "extra parameters example" }.merge(extra_params).to_json)
end
```

**Example JSON 日志记录示例**  

```
{
    "timestamp": "2025-11-02T15:26:28Z",
    "level": "INFO",
    "message": "extra parameters example",
    "requestId": "3dbd5759-65f6-45f8-8d7d-5bdc79a3bd01",
    "a": "b",
    "b": [
        3
    ]
}
```

### 在 JSON 中记录异常
<a name="ruby-logging-json-exceptions"></a>

以下代码段显示了当您将日志格式配置为 JSON 时，如何在函数的日志输出中捕获 Ruby 异常。请注意，使用 `logger.error` 生成的带有异常的日志输出被分配了日志级别 ERROR。

**Example Ruby 日志记录代码示例**  

```
require 'logger'

def lambda_handler(event:, context:)
  logger = Logger.new($stdout)
  begin
    raise "exception"
  rescue => e
    logger.error(e)
  end
end
```

**Example JSON 日志记录示例**  

```
{
    "timestamp": "2025-11-02T16:18:57Z",
    "level": "ERROR",
    "message": "exception",
    "stackTrace": [
        "  /var/task/lambda_function.rb:4:in `lambda_handler'"
    ],
    "errorType": "RuntimeError",
    "errorMessage": "exception",
    "requestId": "3f9d155c-0f09-46b7-bdf1-e91dab220855",
    "location": "/var/task/lambda_function.rb:lambda_handler:6"
}
```

### 在 Ruby 中使用日志级别筛选
<a name="ruby-logging-log-level"></a>

通过配置日志级别筛选，您可以选择仅将特定日志记录级别或更低级别的日志发送到 CloudWatch Logs。要了解如何为您的函数配置日志级别筛选，请参阅 [日志级别筛选](monitoring-cloudwatchlogs-log-level.md)。

为了让 AWS Lambda 根据日志级别筛选应用程序日志，您的函数必须使用 JSON 格式的日志。您可以通过两种方式实现这一点：
+ 使用标准 Ruby `Logger` 库创建日志输出，并将您的函数配置为使用 JSON 日志格式。然后 AWS Lambda 会使用 [在 Ruby 中使用结构化的 JSON 日志](#ruby-logging-json) 中所述的 JSON 对象中的 `"level"` 键值对筛选日志输出。要了解如何配置函数的日志格式，请参阅 [为 Lambda 函数配置高级日志记录控件](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)。
+ 使用其他日志记录库或方法在代码中创建 JSON 结构化日志，其中包含定义日志输出级别的 `"level"` 键值对。

您也可以使用 `puts` 语句输出包含日志级别标识符的 JSON 对象。以下 `puts` 语句生成 JSON 格式的输出，其中日志级别设置为 INFO。如果您的函数的日志记录级别设置为 INFO、DEBUG 或 TRACE，则 AWS Lambda 会将 JSON 对象发送到 CloudWatch Logs。

```
puts '{"msg":"My log message", "level":"info"}'
```

要让 Lambda 筛选函数的日志，还必须在 JSON 日志输出中包含一个 `"timestamp"` 键值对。必须以有效的 [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) 时间戳格式指定时间。如果您未提供有效的时间戳，Lambda 将为日志分配 INFO 级别并为您添加时间戳。

### 使用备用日志记录库
<a name="ruby-logging-alt-library"></a>

如果您需要使用 `logger` 库的自定义版本，可以将其包含在部署包或 Lambda 层中，然后将 `RUBYLIB` 环境变量设置为库的 `lib` 目录。Lambda 运行时将加载您的版本，而不是捆绑的版本。

如果您的代码已经使用其他日志记录库来生成 JSON 结构化日志，则无需进行任何更改。AWS Lambda 不会对任何已采用 JSON 编码的日志进行双重编码。即使您将函数配置为使用 JSON 日志格式，您的日志输出也会以您定义的 JSON 结构显示在 CloudWatch 中。

## 在 Lambda 控制台中查看日志
<a name="ruby-logging-console"></a>

调用 Lambda 函数后，您可以使用 Lambda 控制台查看日志输出。

如果可以在嵌入式**代码**编辑器中测试代码，则可以在**执行结果**中找到日志。使用控制台测试功能调用函数时，可以在**详细信息**部分找到**日志输出**。

## 在 CloudWatch 控制台中查看日志
<a name="ruby-logging-cwconsole"></a>

您可以使用 Amazon CloudWatch 控制台查看所有 Lambda 函数调用的日志。

**使用 CloudWatch 控制台查看日志**

1. 打开 CloudWatch 控制台的 [Log groups](https://console.aws.amazon.com/cloudwatch/home?#logs:)（日志组页面）。

1. 选择您的函数 (**/aws/lambda/{{your-function-name}}**) 的日志组。

1. 创建日志流。

每个日志流对应一个[函数实例](lambda-runtime-environment.md)。日志流会在您更新 Lambda 函数以及创建更多实例来处理并发调用时显示。要查找特定调用的日志，建议您使用 AWS X-Ray 检测函数。X-Ray 会在追踪中记录有关请求和日志流的详细信息。

## 使用 AWS Command Line Interface（AWS CLI）查看日志
<a name="ruby-logging-cli"></a>

AWS CLI 是一种开源工具，让您能够在命令行 Shell 中使用命令与 AWS 服务进行交互。要完成本节中的步骤，您必须拥有 [AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

您可以通过 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)，使用 `--log-type` 命令选项检索调用的日志。响应包含一个 `LogResult` 字段，其中包含多达 4KB 来自调用的 base64 编码日志。

**Example 检索日志 ID**  
以下示例说明如何从 `LogResult` 字段中检索名为 `my-function` 的函数的*日志 ID*。  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
您应看到以下输出：  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example 解码日志**  
在同一命令提示符下，使用 `base64` 实用程序解码日志。以下示例说明如何为 `my-function` 检索 base64 编码的日志。  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
如果使用 **cli-binary-format** 版本 2，则 AWS CLI 选项是必需的。要将其设为默认设置，请运行 `aws configure set cli-binary-format raw-in-base64-out`。有关更多信息，请参阅*版本 2 的 AWS Command Line Interface 用户指南*中的 [AWS CLI 支持的全局命令行选项](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。  
您应看到以下输出：  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
`base64` 实用程序在 Linux、macOS 和 [Ubuntu on Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) 上可用。macOS 用户可能需要使用 `base64 -D`。

**Example get-logs.sh 脚本**  
在同一命令提示符下，使用以下脚本下载最后五个日志事件。此脚本使用 `sed` 从输出文件中删除引号，并休眠 15 秒以等待日志可用。输出包括来自 Lambda 的响应，以及来自 `get-log-events` 命令的输出。  
复制以下代码示例的内容并将其作为 `get-logs.sh` 保存在 Lambda 项目目录中。  
如果使用 **cli-binary-format** 版本 2，则 AWS CLI 选项是必需的。要将其设为默认设置，请运行 `aws configure set cli-binary-format raw-in-base64-out`。有关更多信息，请参阅*版本 2 的 AWS Command Line Interface 用户指南*中的 [AWS CLI 支持的全局命令行选项](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/{{my-function}} --log-stream-name {{stream1}} --limit 5
```

**Example macOS 和 Linux（仅限）**  
在同一命令提示符下，macOS 和 Linux 用户可能需要运行以下命令以确保脚本可执行。  

```
chmod -R 755 get-logs.sh
```

**Example 检索最后五个日志事件**  
在同一命令提示符下，运行以下脚本以获取最后五个日志事件。  

```
./get-logs.sh
```
您应看到以下输出：  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## 删除日志
<a name="ruby-logging-delete"></a>

删除函数时，日志组不会自动删除。要避免无限期存储日志，请删除日志组，或[配置一个保留期](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)，在该保留期之后，日志将自动删除。

## 使用 Ruby 日志记录库
<a name="ruby-logging-lib"></a>

Ruby [日志记录库](https://ruby-doc.org/stdlib-2.7.0/libdoc/logger/rdoc/index.html)可返回易于读取的简化日志。使用日志记录实用程序输出与函数相关的详细信息、消息和错误代码。

```
# lambda_function.rb

require 'logger'

def handler(event:, context:) 
  logger = Logger.new($stdout)
  logger.info('## ENVIRONMENT VARIABLES')
  logger.info(ENV.to_a)
  logger.info('## EVENT')
  logger.info(event)
  event.to_a
end
```

`logger` 的输出包括日志级别、时间戳和请求 ID。

```
START RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125 Version: $LATEST
[INFO]  2020-01-31T22:12:58.534Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    ## ENVIRONMENT VARIABLES

[INFO]  2020-01-31T22:12:58.534Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    environ({'AWS_LAMBDA_LOG_GROUP_NAME': '/aws/lambda/my-function', 'AWS_LAMBDA_LOG_STREAM_NAME': '2020/01/31/[$LATEST]1bbe51xmplb34a2788dbaa7433b0aa4d', 'AWS_LAMBDA_FUNCTION_NAME': 'my-function', ...})

[INFO]  2020-01-31T22:12:58.535Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    ## EVENT

[INFO]  2020-01-31T22:12:58.535Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    {'key': 'value'}

END RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125
REPORT RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125  Duration: 2.75 ms   Billed Duration: 117 ms Memory Size: 128 MB Max Memory Used: 56 MB  Init Duration: 113.51 ms
XRAY TraceId: 1-5e34a66a-474xmpl7c2534a87870b4370   SegmentId: 073cxmpl3e442861 Sampled: true
```