Loading
BLOG 開発者ブログ

2025年2月21日

【Amazon API Gateway】メソッドの呼び出し回数を記録・集計する

システムを安定稼働させるためには、利用状況をモニタリングし、得られたデータを基に適切な改善や対策を講じることが重要です。

例えば、API を運用しているシステムにおいては、API の利用状況やトラフィックの傾向を把握することで、リソースやコストの最適化、耐障害性の向上に繋げることができます。

本記事では、Amazon API Gateway で API メソッドの呼び出し回数を記録・集計する方法をご紹介します。

目次

はじめに

こんにちは。クラウドソリューション第1グループの namiki.t です。

Amazon API Gateway は、API を簡単に作成、デプロイ、管理できるサービスです。
サーバーレスで動作するため、インフラの管理を気にせず、開発に集中できる点が大きな魅力です。
また、スケーラブルな設計により、少ないトラフィックから高負荷なリクエストまで柔軟に対応できるため、
スタートアップからエンタープライズまで幅広く利用されています。
例えば、モバイルアプリとバックエンドを繋ぐ REST API の構築や、IoT デバイスからのデータ送信を処理するエンドポイントの提供、
さらには既存のオンプレミスシステムを API 化して外部連携を実現するケースなど、その活用範囲は多岐に渡ります。

そんな便利な Amazon API Gateway ですが、その運用を効率化するには、API の利用状況を正確に把握することが欠かせません。
次のセクションでは、この API Gateway を使ってメソッドの呼び出し回数を記録・集計する具体的な手順について解説します。

手順

下記の流れで手順を説明します。

  1. リソース準備
  2. 呼び出しログ出力設定
  3. ログ出力確認
  4. 呼び出し回数集計

1. リソース準備

はじめに、実際に動作確認を行うために API Gateway のメソッドと、API Gateway から CloudWatch Logs にログを書き込むための IAM ロールを準備します。
※既に作成済の方は読み飛ばしていただいて問題ありません

今回は、下記の CloudFormation テンプレートを使用します。
なお、本筋から逸れるため、テンプレートそのものやスタック作成に関する説明は割愛させていただきます。

---
Parameters:
  SystemName:
    Type: String
  Env:
    Type: String
    Default: develop

Resources:
  ApiGatewayLoggingRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
            Action:
              - sts:AssumeRole
      RoleName: api-gateway-logging-role
      Policies:
        - PolicyName: api-gateway-logging-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                  - logs:PutLogEvents
                  - logs:GetLogEvents
                  - logs:FilterLogEvents
                Effect: Allow
                Resource: "*"
  ApiGatewayAccount:
    Type: AWS::ApiGateway::Account
    Properties:
      CloudWatchRoleArn: !GetAtt ApiGatewayLoggingRole.Arn
  RestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: !Sub ${SystemName}-${Env}-rest-api
      EndpointConfiguration:
        Types:
          - REGIONAL
  Deployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - GetMethod
      - PostMethod
    Properties:
      RestApiId: !Ref RestApi
      StageName: !Ref Env
  GetResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt RestApi.RootResourceId
      RestApiId: !Ref RestApi
      PathPart: get
  GetMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      ResourceId: !GetAtt GetResource.ResourceId
      RestApiId: !Ref RestApi
      RequestParameters:
        method.request.header.Content-Type: true
      Integration:
        IntegrationHttpMethod: GET
        Type: MOCK
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestTemplates:
          application/json: '{ "statusCode": 200 }'
        IntegrationResponses:
          - StatusCode: "200"
            ResponseTemplates:
              application/json: '{ "message": "Hello from GetMethod!" }'
      MethodResponses:
        - StatusCode: "200"
          ResponseModels:
            application/json: Empty
  PostResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt RestApi.RootResourceId
      RestApiId: !Ref RestApi
      PathPart: post
  PostMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: POST
      ResourceId: !GetAtt PostResource.ResourceId
      RestApiId: !Ref RestApi
      RequestParameters:
        method.request.header.Content-Type: true
      Integration:
        IntegrationHttpMethod: POST
        Type: MOCK
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestTemplates:
          application/json: '{ "statusCode": 200 }'
        IntegrationResponses:
          - StatusCode: "200"
            ResponseTemplates:
              application/json: '{ "message": "Hello from PostMethod!" }'
      MethodResponses:
        - StatusCode: "200"
          ResponseModels:
            application/json: Empty
Outputs:
  BaseUrl:
    Value: !Sub https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/${Env}/

2. 呼び出しログ出力設定

次に、メソッドが呼び出された際にログ出力するよう設定を行います。

API Gateway のコンソールから対象 API の [ステージ] を開きます

[ログとトレース] 内の [編集] を開きます

[CloudWatch ログ] で [エラーと情報ログ] を選択し、[詳細なメトリクス] にチェックを入れて [保存] を押下します

これで、呼び出し回数を記録するためのログ出力が設定されました。

3. ログ出力確認

HTTP クライアントツールを使用して、API を呼び出します。
今回は、各メソッド (パス) を下記の時刻で呼び出しました。

------------------
[00:01] /post
[00:02] /get
[00:03] /get
[00:04] /post
[00:05] /get
------------------

CloudWatch Logs コンソールを開き、[API-Gateway-Execution-Logs_${API_ID}/${ステージ名}] ロググループを開くと、ログストリームが作成されているはずです。

ログは、下図のような形式になっています。

4. 呼び出し回数集計

最後に、各メソッド (パス) が呼び出された回数を集計します。
集計には、CloudWatch の [ログのインサイト] を使用します。

ログ出力しているロググループを選択して、下記のクエリを入力します。

fields @message
| filter @message like /Resource Path: /
| parse @message /(?<resourcePath>(\/.*))/
| stats count(*) by resourcePath

[クエリの実行] を押下すると、下図の通りメソッドが呼ばれた回数が出力できました。

また、stats 句の後に bin() 関数を呼び出すと、単位時間あたり (1時間、1日、1週など) の呼び出し回数を出力することもできます。
下図は、前段にクエリの末尾に bin(1m) を追記してクエリを実行した際の実行結果です。

詳しくは下記公式ドキュメントを参照してください。
stats – Amazon CloudWatch Logs

終わりに

今回は、Amazon API Gateway で API メソッドの呼び出し回数を記録・集計する方法をご紹介しました。

実は、CloudWatch メトリクスでも呼び出し回数を視覚的に確認することができるのですが、
デフォルトのダッシュボードではそのアカウントのすべてのステージやメソッドが一度に表示されてしまうため、使い勝手が悪いです。
そのため、特定の API やステージ、メソッドなど、対象を絞って利用状況を確認したい場合は、今回ご紹介した方法がおすすめです。

ぜひ、利用状況のモニタリングやリソース・コストの最適化にお役立てください!

namiki.tのブログ