【问题标题】:Show distinct number of users invoking API Gateway in CloudWatch dashboard在 CloudWatch 仪表板中显示不同数量的用户调用 API Gateway
【发布时间】:2022-10-04 22:14:46
【问题描述】:

如何获得在给定时间范围内使用我的服务的不同用户数量?用户数量必须显示在 CloudWatch 控制面板中。

我将 Cognito 与用于用户身份验证的托管 UI、HTTP API Gateway 以及用于授权的 Lambda 集成一起使用,并且 API Gateway 请求由另一个 Lambda 函数处理。

在 API Gateway 的 CloudWatch 访问日志中,我可以记录用户名。我知道我可以在 CloudWatch Insights 中使用 stats count(*) by username 来计算每个用户向 API Gateway 发送了多少请求,但我不知道如何获取不同用户的列表。 count_distinct 不起作用,因为它只会近似用户,因为该字段可以具有高基数。

最后,我希望在我的 CloudWatch 仪表板中有一个数字小部件,它将显示在所选时间范围内使用该服务的不同用户数量。

【问题讨论】:

    标签: amazon-web-services amazon-cloudwatch


    【解决方案1】:

    使用custom CloudWatch dashboard widgets,我决定构建一个执行日志洞察查询并将结果呈现为自定义小部件的 Lambda 函数。

    import os
    
    import boto3
    from aws_lambda_powertools import Logger
    from aws_lambda_powertools.utilities.data_classes import (
        CloudWatchDashboardCustomWidgetEvent,
        event_source,
    )
    from aws_lambda_powertools.utilities.typing import LambdaContext
    
    LOG_GROUP_NAME = os.environ["LOG_GROUP_NAME"]
    
    logger = Logger()
    cloud_watch_logs = boto3.client("logs")
    
    DOCS = """
    ## User Widget
    A script to get the number of unique users accessing the API in a given time range.
    """
    
    CSS = """
    <style>
    .container {
        align-content: center;
        align-items: center;
        display: flex;
        flex-direction: row;
        justify-content: center;
        width: 100%;
    }
    
    .value {
        font-size: 45px;
    }
    </style>"""
    
    
    def get_unique_api_users(start_time: int, end_time: int) -> int:
        start_query_response = cloud_watch_logs.start_query(
            logGroupName=LOG_GROUP_NAME,
            startTime=start_time,
            endTime=end_time,
            queryString='filter ispresent(user) and user != "-" | stats count(*) as userCount by user',
            limit=10000,
        )
    
        response = None
        while response == None or response["status"] != "Complete":
            response = cloud_watch_logs.get_query_results(
                queryId=start_query_response["queryId"]
            )
    
        return len(response["results"])
    
    
    @logger.inject_lambda_context(log_event=False)
    @event_source(data_class=CloudWatchDashboardCustomWidgetEvent)
    def lambda_handler(event: CloudWatchDashboardCustomWidgetEvent, context: LambdaContext):
        if event.describe:
            return DOCS
    
        start_time = event.widget_context.time_range.start
        end_time = event.widget_context.time_range.end
        if event.widget_context.time_range.zoom_start:
            start_time = event.widget_context.time_range.zoom_start
            end_time = event.widget_context.time_range.zoom_end
    
        return f"""
    {CSS}
    <div class="container">
        <div class="value">
            ? {get_unique_api_users(start_time=start_time, end_time=end_time)}
        </div>
    </div>"""
    
    

    通过这种方法,我们可以确保获得准确数量的 API 用户。不利的一面是,我们查询的日志越多,拥有的用户越多,获取用户数量所需的时间就越长。此外,每次我们刷新小部件时,都会调用一个 Lambda 函数,计入我们在该区域的并发执行限制,并且每次调用都要花钱,尽管可以说这只是很少的钱。

    【讨论】:

      猜你喜欢
      • 2020-02-14
      • 1970-01-01
      • 2017-01-01
      • 2019-03-30
      • 2019-12-08
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      相关资源
      最近更新 更多