亚马逊AWS官方博客

中国区CloudWatch Dashboard跨区域集成指标

背景介绍

Global与中国区CloudWatch跨区域集成指标的差异

Global region的CloudWatch于2019年发布了跨账号跨区域集成指标到同一个Dashboard的功能,但尚未于中国区落地,因此在中国区暂时无法通过服务本身的特性采集同一账号跨区域的指标至同一CloudWatch Dashboard之中。本文提供一种替代方案,调用API在中国区跨区域集成指标。

某些特定服务的指标特点

在亚马逊云科技提供的云原生服务中,某些服务并不区分区域,但启用的指标会被投递到某个区域。

以R53为例。如图所示,R53服务本身并不要求选择Region。

启用R53指标监控之后,在此账号的宁夏区与北京区分别检查CloudWatch Metrics,分别如下图所示,发现在宁夏区存在R53指标,而北京区不存在R53相关指标。

查阅R53文档可知,如下图描述,中国区使用CLI或SDK工具向R53 API提交请求时,默认区域或者指定区域为宁夏区。

进一步查阅R53的CloudWatch监控文档,如图所示,对于全球区,R53指标需要通过指定区域为弗吉尼亚北部来获取,相应地,在中国区,需要通过指定区域为宁夏区从而获取R53的相关指标。

构建跨区域集中指标的CloudWatch DashBoard

如背景介绍中提及,中国区CloudWatch服务本身暂不支持跨区域集成指标至同一DashBoard,而中国区存在某些服务如R53的指标,原生只发布到特定区域,或者存在跨区域的云用量,为了方便运维侧的监控管理,如果此时需要将对应指标集成到统一的CloudWatch DashBoard,该如何实现呢?这里提供一种使用Lambda调用SDK跨区域发布自定义指标的方案。

使用Lambda自定义发布跨区域指标的实现原理

为了在北京区域实现一个集中的CloudWatch Dashboard,需要将本账号宁夏区的指标发布到北京区。

对于跨区域的指标集成有两种思路,可以在宁夏区执行脚本,拿到本区域的Metrics,跨区域写到北京区的CloudWatch中;或者在北京区执行脚本,跨区域拿到宁夏区的Metrics,写入本区域的CloudWatch中。这两种方式实质上都要求做到跨区域的调用服务。

正如使用CLI调用API时我们通常会指定Region,使用SDK调用服务API时同样可以指定Region。以Python为例,导入包Boto3,我们通常实例化服务类client=boto3.client(Service),从而进一步调用服务API。然而往往在示例代码中都并不直接指定Region,这里我们对此用法进行解释。

首先我们检查boto3的源码。

我们可以发现client函数返回了一个对象,类型为boto3.session.Session.client(),于是我们检查后者源码,如下图所示。

从函数参数可知,实例化boto3.client时可以重写region_name参数从而指定具体区域,否则client将根据config使用当前会话的默认region。例如,前文提到的在宁夏区调用北京区的cloudwatch API,可以实现为client=boto3.client(‘cloudwatch’, region_name=’cn-north-1′)。

自定义跨区域发布指标的工作流程

将宁夏区的R53指标发布至北京区的CloudWatch Dashboard,首先需要从宁夏区获取指标统计数据,然后再发布指标至北京区。

查阅boto3 CloudWatch API文档可知,获取指标统计数据时调用API cloudwatch.get_metric_statistics(),发布自定义指标时调用API cloudwatch.put_metric_data()

发布指标时,CloudWatch 会将关于指标的数据储存为一系列数据点。每个数据点包含一个相关联的时间戳。根据需要甚至可以发布被统计数据集的聚合数据点集。

每个指标均为以下类型之一:

  • 标准精度,数据粒度为一分钟
  • 高精度,数据粒度为一秒

AWS 服务生成的指标在默认情况下为标准精度。在发布自定义指标时,您可以将其定义为标准精度或高精度。发布高精度指标时,CloudWatch 使用 1 秒的精度来存储指标,可以按照 1 秒、5 秒、10 秒、30 秒或 60 秒的任意倍数的时间段读取和检索。

自定义跨区域发布指标的实现示例

创建Lambda IAM Role

根据使用到的服务,首先需要为Lambda函数创建具备以下权限的角色

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "cloudwatch:PutMetricData",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:ListMetrics",
                "logs:CreateLogGroup",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

创建Lambda函数(以R53指标HealthCheckStatus为例)

import boto3
import random
from datetime import datetime
def lambda_handler(event, context):
    cloudwatch = boto3.client('cloudwatch', region_name='cn-northwest-1')
    response = cloudwatch.get_metric_statistics(
        Namespace='AWS/Route53',
        MetricName='HealthCheckStatus',
        Dimensions=[
            {
                'Name': 'HealthCheckId',
                'Value': '****************'
            },
        ],
        StartTime=datetime(2022, 5, 17),
        EndTime=datetime(2022, 5, 18),
        Period=120,
        Statistics=[
            'Average'
        ],
        Unit='None'
    )
    value = response['Datapoints'][0]['Average']
    cloudwatch = boto3.client('cloudwatch', region_name='cn-north-1')
    response = cloudwatch.put_metric_data(
        MetricData = [
            {
                'MetricName': 'R53HealthCheckStatus',
                'Unit': 'None',
                'Value': value
            },
        ],
        Namespace = 'CrossRegionMetrics'
    )

本篇作者

Yann Wang

AWS 专业服务团队云运维咨询顾问。对云上服务建设运维、 混沌工程等项目交付有丰富的经验。负责企业级客户的云架构设计、云上自动化运维、容器化平台设计实施等,对云原生技术有深入的研究和热情。