20

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.

3 Answers 3

19

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.

Sign up to request clarification or add additional context in comments.

Comments

16

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

5 Comments

does anyone know how to programmatically query this information? I'd love to report this data to Stripe billing API for metered billing
This data can be retrieved through a 'get-usage' call, docs.aws.amazon.com/cli/latest/reference/apigateway/…
Unfortunately, in the updated Console this usage UI is no longer available. One can only download the CSV/JSON file with usage data.
@esengineer actually, it is reported. Choose the usage plans, click on the "Associated API keys" tab, and there you have it: remaining calls per API key. The problem is how lagging this information is. It seems to only be updated once usage is exhausted, or maybe after a long delay (> 30 minutes), so not representative for near real-time.
@FGM, it reports only the remaining quota, however, it does not show the metrics graph as it used to do in the old Console.
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.