为 Lambda 函数配置高级日志记录控件 - AWS Lambda

为 Lambda 函数配置高级日志记录控件

为了让您可以更好地控制如何捕获、处理和使用函数日志,Lambda 提供了以下日志配置选项:

  • 日志格式 - 为函数日志选择纯文本或结构化的 JSON 格式

  • 日志级别 - 对于 JSON 结构化日志,选择 Lambda 发送到 CloudWatch 的日志的详细信息级别,例如 ERROR、DEBUG 或 INFO

  • 日志组 - 选择您的函数发送日志的目标 CloudWatch 日志组

要了解有关配置高级日志记录控件的更多信息,请参阅以下各节:

配置 JSON 和纯文本日志格式

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

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

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

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

注意

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

支持的运行时系统和日志记录方法

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

运行时 支持的版本
Java Amazon Linux 1 上除 Java 8 之外的所有 Java 运行时系统
Node.js Node.js 16 及更高版本
Python Python 3.8 及更高版本

为了让 Lambda 以结构化的 JSON 格式将函数的应用程序日志发送到 CloudWatch,您的函数必须使用以下内置日志记录工具来输出日志:

  • Java - LambdaLogger 记录器或 Log4j2。

  • Node.js - 控制台方法 console.traceconsole.debugconsole.logconsole.infoconsole.errorconsole.warn

  • Python - 标准 Python logging

有关在支持的运行时系统中使用高级日志记录控件的更多信息,请参阅 Java Lambda 函数日志记录和监控Node.js Lambda 函数日志记录和监控Python Lambda 函数日志记录和监控

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

默认日志格式

目前,所有 Lambda 运行时系统的默认日志格式均为纯文本。

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

系统日志的 JSON 格式

当您将函数的日志格式配置为 JSON 时,每个系统日志项(平台事件)都将被捕获为一个 JSON 对象,并且包含带有以下键的键值对:

  • "time" - 生成日志消息的时间

  • "type" - 正在记录的事件类型

  • "record" - 日志输出的内容

"record" 值的格式因所记录的事件类型而异。有关更多信息,请参阅遥测 API Event 对象类型。有关分配给系统日志事件的日志级别的更多信息,请参阅 系统日志级别的事件映射

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

例 纯文本:
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
例 结构化的 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 访问扩展的实时遥测数据 始终以 JSON 格式发出平台事件,例如 STARTREPORT。配置 Lambda 发送到 CloudWatch 的系统日志的格式不会影响 Lambda 遥测 API 的行为。

应用程序日志的 JSON 格式

当您将函数的日志格式配置为 JSON 时,使用支持的日志记录库和方法编写的应用程序日志输出将被捕获为 JSON 对象,其中包含带有以下键的键值对。

  • "timestamp" - 生成日志消息的时间

  • "level" - 分配给消息的日志级别

  • "message" - 日志消息的内容

  • "requestId"(Python 和 Node.js)或 "AWSrequestId"(Java)- 函数调用的唯一请求 ID

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

注意

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

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

例 纯文本:
2024-10-27T19:17:45.586Z 79b4f56e-95b1-4643-9700-2807f4e68189 INFO some log message
例 结构化的 JSON:
{ "timestamp":"2024-10-27T19:17:45.586Z", "level":"INFO", "message":"some log message", "requestId":"79b4f56e-95b1-4643-9700-2807f4e68189" }

设置函数的日志格式

要配置函数的日志格式,您可以使用 Lambda 控制台或 AWS Command Line Interface(AWS CLI)。您还可以使用 CreateFunctionUpdateFunctionConfiguration Lambda API 命令、AWS Serverless Application Model(AWS SAM)AWS::Serverless::Function 资源以及 AWS CloudFormation AWS::Lambda::Function 资源来配置函数的日志格式。

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

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

注意

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

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

重要

如果您的函数使用 Powertools for AWS Lambda(TypeScript)或开源的 EMF 客户端库来发出 EMF 日志,请将 PowertoolsEMF 库更新到最新版本,以确保 CloudWatch 能够继续正确解析您的日志。如果您切换到 JSON 日志格式,我们还建议您进行测试以确保与函数的嵌入式指标兼容。有关发出 EMF 日志的 node.js 函数的更多建议,请参阅 使用带有结构化的 JSON 日志的嵌入式指标格式(EMF)客户端库

配置函数的日志格式(控制台)
  1. 打开 Lamba 控制台的函数页面

  2. 选择函数

  3. 在函数配置页面上,选择监控和操作工具

  4. 日志记录配置窗格中,选择编辑

  5. 日志内容下,为日志格式选择文本JSON

  6. 选择保存

要更改现有函数的日志格式(AWS CLI)
  • 要更改现有函数的日志格式,请使用 update-function-configuration 命令。将 LoggingConfig 中的 LogFormat 选项设置为 JSONText

    aws lambda update-function-configuration \ --function-name myFunction \ --logging-config LogFormat=JSON
要在创建函数时设置日志格式(AWS CLI)
  • 要在创建新函数时配置日志格式,请使用 create-function 命令中的 --logging-config 选项。将 LogFormat 设置为 JSONText。以下示例命令创建 Node.js 函数,该函数以结构化 JSON 格式输出日志。

    如果您在创建函数时未指定日志格式,Lambda 将使用您选择的运行时系统版本的默认日志格式。有关默认日志记录格式的信息,请参阅 默认日志格式

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

日志级别筛选

Lambda 可以筛选函数的日志,以便仅将不超过特定详细信息级别的日志发送到 CloudWatch Logs。您可以分别为函数的系统日志(Lambda 生成的日志)和应用程序日志(您的函数代码生成的日志)单独配置日志级别筛选。

对于 支持的运行时系统和日志记录方法,要筛选函数的应用程序日志,无需对 Lambda 的函数代码进行任何更改。

对于所有其他运行时系统和日志记录方法,您的函数代码必须将日志事件作为 JSON 格式的对象输出到 stdoutstderr,并在其中包含键 "level" 的键值对。例如,Lambda 将以下到 stdout 的输出解释为调试级别的日志。

print('{"level": "debug", "msg": "my debug log", "timestamp": "2024-11-02T16:51:31.587199Z"}')

如果 "level" 值字段无效或缺失,Lambda 将为日志输出分配 INFO 级别。要让 Lambda 使用时间戳字段,您必须以有效的 RFC 3339 时间戳格式指定时间。如果您未提供有效的时间戳,Lambda 将为日志分配 INFO 级别并为您添加时间戳。

命名时间戳键时,请遵循所用运行时系统的惯例。Lambda 支持托管运行时系统使用的大多数常用命名惯例。例如,在使用.NET 运行时系统的函数中,Lambda 会识别键 "Timestamp"

注意

要使用日志级别筛选,必须将您的函数配置为使用 JSON 日志格式。目前,所有 Lambda 托管运行时系统的默认日志格式均为纯文本。要了解如何将函数的日志格式配置为 JSON,请参阅 设置函数的日志格式

对于应用程序日志(由函数代码生成的日志),您可以从以下日志级别中进行选择。

日志级别 标准使用情况
TRACE(最详细) 用于跟踪代码执行路径的最精细信息
调试 系统调试的详细信息
信息 记录函数正常运行情况的消息
警告 有关潜在错误的消息,如果不加以解决,这些错误可能会导致意外行为
错误 有关会阻碍代码按预期执行的问题的消息
FATAL(最简略) 有关导致应用程序停止运行的严重错误的消息

当您选择日志级别后,Lambda 会将该级别及更低级别的日志发送到 CloudWatch Logs。例如,如果您将函数的应用程序日志级别设置为 WARN,则 Lambda 不会发送 INFO 和 DEBUG 级别的日志输出。日志筛选的默认应用程序日志级别为 INFO。

当 Lambda 筛选函数的应用程序日志时,将为没有级别的日志消息分配日志级别 INFO。

对于系统日志(由 Lambda 服务生成的日志),您可以在以下日志级别之间进行选择。

日志级别 使用量
DEBUG(最详细) 系统调试的详细信息
信息 记录函数正常运行情况的消息
WARN(最简略) 有关潜在错误的消息,如果不加以解决,这些错误可能会导致意外行为

当您选择日志级别后,Lambda 会发送该级别及更低级别的日志。例如,如果您将函数的系统日志级别设置为 INFO,则 Lambda 不会发送 DEBUG 级别的日志输出。

默认情况下,Lambda 会将系统日志级别设置为 INFO。使用此设置,Lambda 会自动向 CloudWatch 发送 "start""report" 日志消息。要接收不同详细程度的系统日志,请将日志级别更改为 DEBUG 或 WARN。要查看 Lambda 将不同系统日志事件映射到的日志级别列表,请参阅 系统日志级别的事件映射

配置日志级别筛选

要为您的函数配置应用程序和系统日志级别的筛选,您可以使用 Lambda 控制台或 AWS Command Line Interface(AWS CLI)。您还可以使用 CreateFunctionUpdateFunctionConfiguration Lambda API 命令、AWS Serverless Application Model(AWS SAM)AWS::Serverless::Function 资源以及 AWS CloudFormation AWS::Lambda::Function 资源来配置函数的日志级别。

请注意,如果在代码中设置函数的日志级别,则此设置将优先于您配置的任何其他日志级别设置。例如,如果您通过 Python logging setLevel() 方法将函数的日志级别设置为 INFO,则此设置将优先于您通过 Lambda 控制台配置的 WARN 设置。

配置现有函数的应用程序或系统日志级别(控制台)
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. 在函数配置页面上,选择监控和操作工具

  4. 日志记录配置窗格中,选择编辑

  5. 日志内容下,确保为日志格式选择 JSON

  6. 使用单选按钮,为您的函数选择所需的应用程序日志级别系统日志级别

  7. 选择保存

配置现有函数的应用程序或系统日志级别(AWS CLI)
  • 要更改现有函数的应用程序或系统日志级别,请使用 update-function-configuration 命令。使用 --logging-configSystemLogLevel 设为 DEBUGINFOWARN。将 ApplicationLogLevel 设置为 DEBUGINFOWARNERRORFATAL 之一。

    aws lambda update-function-configuration \ --function-name myFunction \ --logging-config LogFormat=JSON,ApplicationLogLevel=ERROR,SystemLogLevel=WARN
在创建函数时配置日志级别筛选
  • 要在创建新函数时配置日志级别筛选,请在 create-function 命令中使用 --logging-config 来设置 SystemLogLevelApplicationLogLevel 键。将 SystemLogLevel 设置为 DEBUGINFOWARN 之一。将 ApplicationLogLevel 设置为 DEBUGINFOWARNERRORFATAL 之一。

    aws lambda create-function \ --function-name myFunction \ --runtime nodejs20.x \ --handler index.handler \ --zip-file fileb://function.zip \ --role arn:aws:iam::123456789012:role/LambdaRole \ --logging-config LogFormat=JSON,ApplicationLogLevel=ERROR,SystemLogLevel=WARN

系统日志级别的事件映射

对于 Lambda 生成的系统级日志事件,下表定义了分配给每个事件的日志级别。要了解有关表中所列事件的更多信息,请参阅 Lambda 遥测 API Event 架构参考

事件名称 状况 分配的日志级别
initStart 已设置 runtimeVersion 信息
initStart 未设置 runtimeVersion 调试
initRuntimeDone status=success 调试
initRuntimeDone status!=success 警告
initReport initializationType=snapstart 信息
initReport initializationType!=snapstart 调试
initReport status!=success 警告
restoreStart 已设置 runtimeVersion 信息
restoreStart 未设置 runtimeVersion 调试
restoreRuntimeDone status=success 调试
restoreRuntimeDone status!=success 警告
restoreReport status=success 信息
restoreReport status!=success 警告
开启 - 信息
runtimeDone status=success 调试
runtimeDone status!=success 警告
报告 status=success 信息
报告 status!=success 警告
extension state=success 信息
extension state!=success 警告
logSubscription - 信息
telemetrySubscription - 信息
logsDropped - 警告
注意

使用遥测 API 访问扩展的实时遥测数据 始终会发出一整套平台事件。配置 Lambda 发送到 CloudWatch 的系统日志的级别不会影响 Lambda 遥测 API 的行为。

使用自定义运行时系统进行应用程序日志级别筛选

当您为函数配置应用程序日志级别筛选时,Lambda 会在后台使用 AWS_LAMBDA_LOG_LEVEL 环境变量在运行时系统中设置应用程序日志级别。Lambda 还会使用 AWS_LAMBDA_LOG_FORMAT 环境变量设置函数的日志格式。您可以使用这些变量将 Lambda 高级日志记录控件集成到自定义运行时系统中。

要使用自定义运行时系统通过 Lambda 控制台、AWS CLI 和 Lambda API 为函数配置日志记录设置,请配置您的自定义运行时系统以检查这些环境变量的值。然后,您可以根据所选的日志格式和日志级别配置运行时系统的记录器。

配置 CloudWatch 日志组

默认情况下,CloudWatch 会在首次调用您的函数时为其自动创建一个名为 /aws/lambda/<function name> 的日志组。要将您的函数配置为向现有日志组发送日志,或者为函数创建新的日志组,可以使用 Lambda 控制台或 AWS CLI。您还可以使用 CreateFunctionUpdateFunctionConfiguration Lambda API 命令以及 AWS Serverless Application Model(AWS SAM)AWS::Serverless::Function 资源配置自定义日志组。

您可以配置多个 Lambda 函数向同一 CloudWatch 日志组发送日志。例如,您可以使用单个日志组来存储构成特定应用程序的所有 Lambda 函数的日志。当您为 Lambda 函数使用自定义日志组时,Lambda 创建的日志流包括函数名称和函数版本。这可以确保即使将同一个日志组用于多个函数,也能保留日志消息与函数之间的映射。

自定义日志组的日志流命名格式遵循以下惯例:

YYYY/MM/DD/<function_name>[<function_version>][<execution_environment_GUID>]

请注意,配置自定义日志组时,您为日志组选择的名称必须遵守 CloudWatch Logs 命名规则。此外,自定义日志组名称不得以字符串 aws/ 开头。如果以 aws/ 为开头创建自定义日志组,则 Lambda 将无法创建该日志组。这将导致函数的日志不会发送到 CloudWatch。

更改函数的日志组(控制台)
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. 在函数配置页面上,选择监控和操作工具

  4. 日志记录配置窗格中,选择编辑

  5. 日志记录组窗格中,为 CloudWatch 日志组选择自定义

  6. 自定义日志组下,输入您希望函数发送日志的目标 CloudWatch 日志组的名称。如果您输入现有日志组的名称,则函数将使用该组。如果不存在具有所输入名称的日志组,则 Lambda 将使用该名称为您的函数创建一个新的日志组。

更改函数的日志组(AWS CLI)
  • 要更改现有函数的日志组,请使用 update-function-configuration 命令。

    aws lambda update-function-configuration \ --function-name myFunction \ --logging-config LogGroup=myLogGroup
在创建函数时指定自定义日志组(AWS CLI)
  • 要在使用 AWS CLI 创建新 Lambda 函数时指定自定义日志组,请使用 --logging-config 选项。以下示例命令可创建 Node.js Lambda 函数,用于将日志发送到名为 myLogGroup 的日志组。

    aws lambda create-function \ --function-name myFunction \ --runtime nodejs20.x \ --handler index.handler \ --zip-file fileb://function.zip \ --role arn:aws:iam::123456789012:role/LambdaRole \ --logging-config LogGroup=myLogGroup

执行角色权限

您的函数必须拥有 logs:PutLogEvents 权限,才能向 CloudWatch Logs 发送日志。当您使用 Lambda 控制台配置函数的日志组时,如果您的函数没有此权限,Lambda 会默认将其添加到函数的执行角色。当 Lambda 添加此权限时,它会向该函数授予向任何 CloudWatch Logs 日志组发送日志的权限。

要防止 Lambda 自动更新函数的执行角色并改为手动对其进行编辑,请展开权限并取消选中添加所需权限

当您使用 AWS CLI 配置函数的日志组时,Lambda 不会自动添加 logs:PutLogEvents 权限。如果函数的执行角色还没有该权限,请添加。此权限包含在 AWSLambdaBasicExecutionRole 托管策略中。