

# 从警报中调用 Lambda 函数
<a name="alarms-and-actions-Lambda"></a>

CloudWatch 警报可保证在给定状态变化时异步调用 Lambda 函数，但以下情况除外：
+ 当该函数不存在时。
+ 当 CloudWatch 未被授权调用该 Lambda 函数时。

如果 CloudWatch 无法访问 Lambda 服务或消息因其他原因被拒绝，CloudWatch 会不断重试，直到调用成功。Lambda 将消息加入队列并处理执行重试。有关这种执行模式的更多信息，包括有关 Lambda 如何处理错误的信息，请参阅《AWS Lambda 开发人员指南》中的 [Asynchronous invocation](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html)。

可以调用同一账户中的 Lambda 函数，也可以调用其他 AWS 账户中的 Lambda 函数。

当您指定一个警报以调用 Lambda 函数作为警报操作时，您可以选择指定函数名称、函数别名或函数的特定版本。

当您将一个 Lambda 函数指定为警报操作时，必须为该函数创建一个资源策略，以允许 CloudWatch 服务主体调用该函数。

一种方法是使用 AWS CLI，如下例所示：

```
aws lambda add-permission \
--function-name my-function-name \
--statement-id AlarmAction \
--action 'lambda:InvokeFunction' \
--principal lambda.alarms.cloudwatch.amazonaws.com \
--source-account 111122223333 \
--source-arn arn:aws:cloudwatch:us-east-1:111122223333:alarm:alarm-name
```

或者，您可以创建一个类似于以下示例之一的策略，然后将其分配给该函数。

以下示例指定警报所在的账户，因此只有该账户（111122223333）中的警报才能调用该函数。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "default",
    "Statement": [{
        "Sid": "AlarmAction",
        "Effect": "Allow",
        "Principal": {
            "Service": "lambda.alarms.cloudwatch.amazonaws.com"
        },
        "Action": "lambda:InvokeFunction",
        "Resource": "arn:aws:lambda:us-east-1:444455556666:function:function-name",
        "Condition": {
            "StringEquals": {
                "AWS:SourceAccount": "111122223333"
            }
        }
    }]
}
```

------

以下示例的范围较窄，仅允许指定账户中的指定警报调用该函数。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "default",
  "Statement": [
    {
      "Sid": "AlarmAction",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.alarms.cloudwatch.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-1:444455556666:function:function-name",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "111122223333",
          "AWS:SourceArn": "arn:aws:cloudwatch:us-east-1:111122223333:alarm:alarm-name"
        }
      }
    }]
}
```

------

我们不建议创建未指定来源账户的策略，因为此类策略容易受到混淆代理问题的影响。

## 将 Lambda 指标添加到 CloudWatch 调查中
<a name="Lambda-metrics-investigation"></a>

您可以将 Lambda 指标添加到处于活动状态的 CloudWatch 调查中。在调查问题时，Lambda 指标可以提供有关函数性能和行为的宝贵洞察。例如，如果您正在调查应用程序性能问题，则持续时间、错误率或节流等 Lambda 指标可能有助于确定根本原因。

要将 Lambda 指标添加到 CloudWatch 调查中，请执行以下操作：

1. 通过 [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) 打开 AWS Lambda 控制台。

1. 在**监控**部分中，找到该指标。

1. 打开指标的上下文菜单，依次选择**调查**、**添加到调查中**。然后，在**调查**窗格中，选择调查名称。

## 从 CloudWatch 发送到 Lambda 的事件对象
<a name="Lambda-action-payload"></a>

当您将一个 Lambda 函数配置为警报操作时，CloudWatch 会在调用 Lambda 函数时向该函数传送一个 JSON 有效负载。此 JSON 有效负载用作函数的事件对象。您可以从此 JSON 对象中提取数据并将其用于您的函数。以下是指标警报中事件对象的示例。

```
{
  'source': 'aws.cloudwatch',
  'alarmArn': 'arn:aws:cloudwatch:us-east-1:444455556666:alarm:lambda-demo-metric-alarm',
  'accountId': '444455556666',
  'time': '2023-08-04T12:36:15.490+0000',
  'region': 'us-east-1',
  'alarmData': {
    'alarmName': 'lambda-demo-metric-alarm',
    'state': {
      'value': 'ALARM',
      'reason': 'test',
      'timestamp': '2023-08-04T12:36:15.490+0000'
    },
    'previousState': {
      'value': 'INSUFFICIENT_DATA',
      'reason': 'Insufficient Data: 5 datapoints were unknown.',
      'reasonData': '{"version":"1.0","queryDate":"2023-08-04T12:31:29.591+0000","statistic":"Average","period":60,"recentDatapoints":[],"threshold":5.0,"evaluatedDatapoints":[{"timestamp":"2023-08-04T12:30:00.000+0000"},{"timestamp":"2023-08-04T12:29:00.000+0000"},{"timestamp":"2023-08-04T12:28:00.000+0000"},{"timestamp":"2023-08-04T12:27:00.000+0000"},{"timestamp":"2023-08-04T12:26:00.000+0000"}]}',
      'timestamp': '2023-08-04T12:31:29.595+0000'
    },
    'configuration': {
      'description': 'Metric Alarm to test Lambda actions',
      'metrics': [
        {
          'id': '1234e046-06f0-a3da-9534-EXAMPLEe4c',
          'metricStat': {
            'metric': {
              'namespace': 'AWS/Logs',
              'name': 'CallCount',
              'dimensions': {
                'InstanceId': 'i-12345678'
              }
            },
            'period': 60,
            'stat': 'Average',
            'unit': 'Percent'
          },
          'returnData': True
        }
      ]
    }
  }
}
```

以下是复合警报中事件对象的示例。

```
{
  'source': 'aws.cloudwatch',
  'alarmArn': 'arn:aws:cloudwatch:us-east-1:111122223333:alarm:SuppressionDemo.Main',
  'accountId': '111122223333',
  'time': '2023-08-04T12:56:46.138+0000',
  'region': 'us-east-1',
  'alarmData': {
    'alarmName': 'CompositeDemo.Main',
    'state': {
      'value': 'ALARM',
      'reason': 'arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild transitioned to ALARM at Friday 04 August, 2023 12:54:46 UTC',
      'reasonData': '{"triggeringAlarms":[{"arn":"arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild","state":{"value":"ALARM","timestamp":"2023-08-04T12:54:46.138+0000"}}]}',
      'timestamp': '2023-08-04T12:56:46.138+0000'
    },
    'previousState': {
      'value': 'ALARM',
      'reason': 'arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild transitioned to ALARM at Friday 04 August, 2023 12:54:46 UTC',
      'reasonData': '{"triggeringAlarms":[{"arn":"arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild","state":{"value":"ALARM","timestamp":"2023-08-04T12:54:46.138+0000"}}]}',
      'timestamp': '2023-08-04T12:54:46.138+0000',
      'actionsSuppressedBy': 'WaitPeriod',
      'actionsSuppressedReason': 'Actions suppressed by WaitPeriod'
    },
    'configuration': {
      'alarmRule': 'ALARM(CompositeDemo.FirstChild) OR ALARM(CompositeDemo.SecondChild)',
      'actionsSuppressor': 'CompositeDemo.ActionsSuppressor',
      'actionsSuppressorWaitPeriod': 120,
      'actionsSuppressorExtensionPeriod': 180
    }
  }
}
```