Tri Q Tran
Tri Q Tran

Reputation: 5690

AWS API Gateway usage by API key

How do I get the usage metric from AWS API Gateway by API key, e.g. usage counter, usage logs, etc.?

I am currently sending the x-api-key to my integration endpoint for manual logging. I would prefer not to do this and let AWS API Gateway measure and report this metric for me.

Upvotes: 20

Views: 8499

Answers (3)

ThisGuyCantEven
ThisGuyCantEven

Reputation: 1267

I don't know how old some of these answers are, but if you set up a usage plan and associate your key with a usage plan, you can use the GetUsage endpoint of the ApiGateway API, which takes a UsagePlanId parameter. https://docs.aws.amazon.com/apigateway/latest/api/API_GetUsage.html

Here's a python (boto3) example:

response = client.get_usage(
    usagePlanId='string',
    keyId='string',
    startDate='string',
    endDate='string',
    position='string',
    limit=123
)

Also some example code I pulled from one of my repos to set up the usage plan and key:

from boto3 import session
from argparse import ArgumentParser

def parse_args():
    parser = ArgumentParser(
        prog="CreateNewUsagePlanWithKey",
        description="Creates a new usage plan with key for an AWS API gateway api"
    )
    parser.add_argument(
        "-p","--aws-profile",
        type=str,
        help="The AWS profile to use for the client session"
    )
    parser.add_argument(
        "-r","--aws-region",
        type=str,
        default="us-east-1",
        help="The AWS profile to use for the client session"
    )
    parser.add_argument(
        "-g","--gateway-id",
        type=str,
        help="The api gateway id to create the key and usage plan for"
    )
    parser.add_argument(
        "-s","--stage",
        type=str,
        help="The api gateway id to create the key and usage plan for"
    )
    parser.add_argument(
        "-n","--usage-plan-name",
        type=str,
        help="The name to give the usage plan (will be propagated to the key with a \"_key\" suffix)"
    )
    return parser.parse_args().__dict__

def create_or_update_usage_plan(client,usage_plan_name,api_id,stage) -> str:
    res = client.create_usage_plan(
        name=usage_plan_name,
        description=f"Usage plan {usage_plan_name} for API {api_id}",
        apiStages=[
            {
                "apiId": api_id,
                "stage": stage
            }
        ]
    )
    return res["id"]

def create_api_key(client,usage_plan_id) -> (str,str):
    res = client.create_api_key(
        name=f"{usage_plan_id}_key",
        description=f"API key for usage plan {usage_plan_id}",
        enabled=True,
    )
    return res["id"],res["value"]

def create_usage_plan_key(client,usage_plan_id,key_id) -> None:
    client.create_usage_plan_key(
        usagePlanId=usage_plan_id,
        keyId=key_id,
        keyType="API_KEY"
    )

def main(aws_profile,aws_region,gateway_id,stage,usage_plan_name) -> None:
    sess = session.Session(profile_name=aws_profile,region_name=aws_region)
    client = sess.client('apigateway')
    usage_plan_id = create_or_update_usage_plan(client,usage_plan_name,gateway_id)
    key_id,key_value = create_api_key(client,usage_plan_id)
    create_usage_plan_key(client,usage_plan_id,key_id)
    print(f"Successfully created usage plan, new key: {key_value}")

if __name__ == "__main__":
    args = parse_args()
    main(**args)

Upvotes: 1

Hexie
Hexie

Reputation: 4221

I found that all the logging was insufficient for what I needed - especially as it didn't log per API Key as yet (holding out that this will still one).

So I created my own custom logs -

This way, I can search my CloudWatch logs and get back the exact data that I'm wanting, even per API Key if required;

Under my stages, I enabled the "Custom Access Logging" and used the following format:

enter image description here

NOTE: These custom logs, currently only support context variables.

  • I'm waiting for the support of input variables:

Documentation can be found here:

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variable-reference

With this custom logging in place, I can open CloudWatch, filter per date and use a search string to search for anything I want (that fits my custom logging);

  • For example: All GET requests made for any API Key ending in BcxvY1 on Endpoint /fees

[RequestId,APIKeyText,APIKeyValue="*BcxvY1*",HTTPText,MethodText,HTTPMethodType="*GET*",PathText,PathValue="*/fees,",StatusText,StatusCode,ErrorsText,ErrorsValue,DescriptionText,DescriptionValue=custom_log]

The great thing with this, is that is completely customisable. I can change my search query however I want, depending on the results I want. Making it more / less complex as needed.

Hope this helps.

Upvotes: 19

jens walter
jens walter

Reputation: 14029

So far, there are no metrics in Cloudwatch for key usage. But the gateway itself keeps some usage statistics, although not very detailed.

Usage plan overview: usage plan stats

Invocation statistic of one API Key: api key usage

Upvotes: 16

Related Questions