# Knowledge sharing - Enable cloud watch logs for API Gateway using Serverless

**URL:** <https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287>\
**Category:** Serverless Framework\
**Created:** [December 10, 2017, 8:22am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287 "2017-12-10T08:22:23Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![bill](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/bill/32/1072_2.png) [@bill](https://forum.serverless.com/u/bill)\
**Post date:** [December 10, 2017, 8:22am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/1 "2017-12-10T08:22:23Z")

</div>

Serverless team are still working to add this feature in core service directly ([https://github.com/serverless/serverless/issues/4461](https://github.com/serverless/serverless/issues/4461)). If you need enable cloud watch logs for API Gateway using Serverless now, please follow this document.

Get most help from this ticket [How to enable cloud watch logs for API Gateway using Serverless](http://forum.serverless.com/t/how-to-enable-cloud-watch-logs-for-api-gateway-using-serverless/2067/3?u=bill)

But I still can’t make it work, if you follow its codes. So I need to understand how it works, how to enable cloudwatch logs in API Gateway.

1. Provide an iam role ARN that has write access to CloudWatch logs in API gateway.

Go through this documents

[https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/](https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/)

in general, you need to do:

- Create a new IAM role (for example, `apigateway-cloudwatch-logs-role`) with trust policy `apigateway.amazonaws.com`
- Attach aws exist policy `AmazonAPIGatewayPushToCloudWatchLogs` to this role
- Record this IAM role’s ARN
- Add this iam role’s arn to apigatewa-\> settings -\> CloudWatch log role ARN\*

**These are manual tasks.**

With this setup, all your api gateways are ready for generating access logs in Cloudwatch. This is a global setting for API Gateway, that’s the reason why it can’t be managed by serverless framework (in `serverless.yml`)

1. Enable access logs

Add below lines into `serverless.yml`, that’s all.

```
plugins:
  - serverless-plugin-stage-variables

resources:
  Resources:
     ApiGatewayStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        MethodSettings:
          - DataTraceEnabled: true
            HttpMethod: "*"
            LoggingLevel: INFO
            ResourcePath: "/*"
            MetricsEnabled: true

```

**Notes** : Don’t define `Provider -> role` with the new role you created above, because the `Provider:role` used in `serverless.yml` is for lambda function, not for api gateway. If you do that, you lost all permissions in lambda functions.

1. Install the plugin `serverless-plugin-stage-variables` and run `sls deploy`

2. Trigger several api gateway access, you should see the access logs in cloudwatch now.

The log group name is:

```
 API-Gateway-Execution-Logs_{rest-api-id}/{stage_name}

```

References:

[http://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html](http://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html)

---

<div class="post-metadata">

**Author:** ![stevenmwade](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/stevenmwade/32/1545_2.png) [@stevenmwade](https://forum.serverless.com/u/stevenmwade)\
**Post date:** [January 22, 2018, 6:32pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/2 "2018-01-22T18:32:54Z")

</div>

What is the point of `serverless-plugin-stage-variables` here?

---

<div class="post-metadata">

**Author:** ![bill](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/bill/32/1072_2.png) [@bill](https://forum.serverless.com/u/bill)\
**Post date:** [January 22, 2018, 8:11pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/3 "2018-01-22T20:11:09Z")

</div>

serverless framework does’t support stage ( api gateway stage) currently, so you need the plugin to help

---

<div class="post-metadata">

**Author:** ![stevenmwade](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/stevenmwade/32/1545_2.png) [@stevenmwade](https://forum.serverless.com/u/stevenmwade)\
**Post date:** [January 23, 2018, 6:36pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/4 "2018-01-23T18:36:42Z")

</div>

Using that just gives me this error:

`Cannot read property 'stageVariables' of undefined`

Does it just want you to put something empty if you don’t want to use it? Maybe I’m missing something from your post.

---

<div class="post-metadata">

**Author:** ![levz0r](https://avatars.discourse-cdn.com/v4/letter/l/eb9ed0/32.png) [@levz0r](https://forum.serverless.com/u/levz0r)\
**Post date:** [January 31, 2018, 11:20pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/5 "2018-01-31T23:20:10Z")

</div>

Add this to serverless.yml:

custom:  
stageVariables:  
env: ${self:provider.stage}

---

<div class="post-metadata">

**Author:** ![mbfisher](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/mbfisher/32/1841_2.png) [@mbfisher](https://forum.serverless.com/u/mbfisher)\
**Post date:** [April 12, 2018, 1:03am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/6 "2018-04-12T01:03:36Z")

</div>

Hi Bill,

Thanks for your docs!

I’m getting this error when I run `sls deploy`:

```
An error occurred: apiGatewayStage - Property RestApiId cannot be empty..

```

I’ve configured the API Gateway CloudWatch ARN, installed `serverless-plugin-stage-variables` and added this to `resources.Resources`:

```
ApiGatewayStage:
  Type: AWS::ApiGateway::Stage
  Properties:
    MethodSettings:
      - DataTraceEnabled: true
        HttpMethod: "*"
        LoggingLevel: INFO
        ResourcePath: "/*"
        MetricsEnabled: true

```

Any clues?

---

<div class="post-metadata">

**Author:** ![mbfisher](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/mbfisher/32/1841_2.png) [@mbfisher](https://forum.serverless.com/u/mbfisher)\
**Post date:** [April 12, 2018, 2:19am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/7 "2018-04-12T02:19:53Z")

</div>

Solve this by adding `RestApiId`:

```
ApiGatewayStage:
  Type: AWS::ApiGateway::Stage
  Properties:
    RestApiId:
      Ref: ApiGatewayRestApi
    MethodSettings:
      - DataTraceEnabled: true
        HttpMethod: "*"
        LoggingLevel: INFO
        ResourcePath: "/*"
        MetricsEnabled: true
```

---

<div class="post-metadata">

**Author:** ![bill](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/bill/32/1072_2.png) [@bill](https://forum.serverless.com/u/bill)\
**Post date:** [April 12, 2018, 2:52am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/8 "2018-04-12T02:52:46Z")

</div>

Nice to hear your problem is fixed.

I didn’t have to set `RestApiId` in my serverless.yml, but good to know this.

---

<div class="post-metadata">

**Author:** ![gauravve](https://avatars.discourse-cdn.com/v4/letter/g/aeb1de/32.png) [@gauravve](https://forum.serverless.com/u/gauravve)\
**Post date:** [August 4, 2018, 2:12pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/9 "2018-08-04T14:12:25Z")

</div>

Hi Bill,

I am getting the following error .

```
Serverless Error ---------------------------------------

  An error occurred: ApiGatewayStage - 1 validation error detected: Value null at 'createStageInput.deploymentId' failed to satisfy constraint: Member must not be null (Service: AmazonApiGateway; Status Code: 400; Error Code: ValidationException; Request ID: 270600b3-97f0-11e8-b138-2f94522f87b3).

```

Wondering where I can get this deployment ID from?

My serverless code looks like this

```
ApiGatewayStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        RestApiId:
          Ref: ApiGatewayRestApi
        StageName: ${self:provider.stage}
        MethodSettings:
          - DataTraceEnabled: true
            HttpMethod: "*"
            LoggingLevel: INFO
            ResourcePath: "/*"
            MetricsEnabled: true
```

---

<div class="post-metadata">

**Author:** ![timoteialbu](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/timoteialbu/32/2387_2.png) [@timoteialbu](https://forum.serverless.com/u/timoteialbu)\
**Post date:** [August 13, 2018, 5:21pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/10 "2018-08-13T17:21:34Z")

</div>

I am getting the same error ☹. I opened a issue on the plugins github ([https://github.com/svdgraaf/serverless-plugin-stage-variables/issues/15](https://github.com/svdgraaf/serverless-plugin-stage-variables/issues/15)) but I am starting to think its not necessarily related to that.

The deploymentId comes from here [https://github.com/awslabs/aws-apigateway-sdk-java/blob/master/src/main/java/com/amazonaws/services/apigateway/model/CreateStageInput.java](https://github.com/awslabs/aws-apigateway-sdk-java/blob/master/src/main/java/com/amazonaws/services/apigateway/model/CreateStageInput.java).

---

<div class="post-metadata">

**Author:** ![rbalhorn](https://avatars.discourse-cdn.com/v4/letter/r/d07c76/32.png) [@rbalhorn](https://forum.serverless.com/u/rbalhorn)\
**Post date:** [March 7, 2019, 6:40pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/11 "2019-03-07T18:40:35Z")

</div>

I am having issues getting this working. I am a bit new to SLS.

```
resources:
  - ${file(dynamodb.yml):resources} # DynamoDB
  - Resources: # API Gateway Logging
     ApiGatewayStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        RestApiId:
            Ref: ApiGatewayRestApi
        StageName: ${self:provider.stage}
        MethodSettings:
          - DataTraceEnabled: true
            HttpMethod: "*"
            LoggingLevel: INFO
            ResourcePath: "/*"
            MetricsEnabled: true

```

The error I am getting is:

> An error occurred: ApiGatewayStage - qa already exists.

I am adding logging to an existing deployment, so the environment/stage does already exist, but I am unsure how to let it add to that environment/stage.

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forum.serverless.com/u/Nil)\
**Post date:** [June 12, 2019, 3:24pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/12 "2019-06-12T15:24:57Z")

</div>

I can’t enable CloudWatch logs for API Gateway. It doesn’t give error but when I check serverless logs I can see somehow logLevel is OFF and tracingEnabled is false.

This is my serverless file:

```
        service: my-api-project
        package:
          individually: true
          exclude:
            - ./**
        provider:
          name: aws
          runtime: nodejs10.x
          region: eu-west-1
        plugins:
          - serverless-plugin-stage-variables
        custom: 
          stage: ${self:provider.stage, 'dev'}
          region: ${self:provider.region, 'eu-west-1'}
        functions:
          api:
            handler: dist/lambda.handler
            package:
              include:
                - dist/**
                - node_modules/**
                - ormconfig.js
            events:
              - http: ANY /
              - http: 'ANY {proxy+}'
        resources:
          Resources:
             ApiGatewayStage:
              Type: AWS::ApiGateway::Stage
              Properties:
                RestApiId:
                    Ref: ApiGatewayRestApi
                StageName: ${self:provider.stage}
                MethodSettings:
                  - DataTraceEnabled: true
                    HttpMethod: "*"
                    LoggingLevel: INFO
                    ResourcePath: "/*"
                    MetricsEnabled: true

```

These are the serverless logs:

```
Serverless: [AWS sts 200 0.341s 0 retries] getCallerIdentity({})
Serverless: [AWS apigateway 200 0.128s 0 retries] getRestApis({ position: undefined, limit: 500 })
Serverless: [AWS apigateway 200 0.113s 0 retries] getStage({ restApiId: 'xxx', stageName: 'dev' })
Serverless: [AWS apigateway 200 0.203s 0 retries] updateStage({ restApiId: 'xxx',
  stageName: 'dev',
  patchOperations:
   [ { op: 'replace', path: '/tracingEnabled', value: 'false' },
     { op: 'replace', path: '/*/*/logging/dataTrace', value: 'false' },
     { op: 'replace', path: '/*/*/logging/loglevel', value: 'OFF' },
     [length]: 3 ] })
Serverless: [AWS cloudwatchlogs 400 0.094s 0 retries] deleteLogGroup({ logGroupName: '/aws/api-gateway/my-api-project-dev' })
Serverless: Invoke aws:deploy:finalize
Serverless: [AWS s3 200 0.136s 0 retries] listObjectsV2({ Bucket:
   'my-api-project-dev-serverlessdeploymentbucket-xxx',
  Prefix: 'serverless/my-api-project/dev' })

```

Does anyone have an idea why I can’t enable CloudWatch logs? By the way I have already set a CloudWatch log role ARN in API Gateway settings. I just need to enable logging for API Gateway.

---

<div class="post-metadata">

**Author:** ![joonhwa](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@joonhwa](https://forum.serverless.com/u/joonhwa)\
**Post date:** [June 13, 2019, 9:08am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/13 "2019-06-13T09:08:03Z")

</div>

You need to put in the log key in your serverless file as follow:

```
provider:
  name: aws
  runtime: nodejs10.x
  stage: dev
  logs:
    restApi: true 

```

It works for me on sls version 1.44.1

However, this leads to another problem as the Access Log format seems to be hardcoded in as well. I was not able to use my own format so i had to revert back to 1.41.1 which allow me to enable logging and specify my own custom access log format. This can be seen at line 177 in the code [https://github.com/serverless/serverless/blob/0b53d71a8ff28e51f0080afbe8e0f513bfccb797/lib/plugins/aws/package/compile/events/apiGateway/lib/hack/updateStage.js](https://github.com/serverless/serverless/blob/0b53d71a8ff28e51f0080afbe8e0f513bfccb797/lib/plugins/aws/package/compile/events/apiGateway/lib/hack/updateStage.js)

Maybe the author can shed some lights as to why the access log format is hardcoded in the code?

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forum.serverless.com/u/Nil)\
**Post date:** [June 13, 2019, 9:40am UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/14 "2019-06-13T09:40:11Z")

</div>

My sls version is 1.44.1 as well. I have added the following key under provider:

```
  logs:
    restApi: true

```

However the result is still the same and logs have the following lines as well which I think that it means somehow logging settings are OFF although I say resAPI is true.

```
Serverless: [AWS apigateway 200 0.213s 0 retries] updateStage({ restApiId: 'XXX',
  stageName: 'dev', patchOperations:
   [ { op: 'replace', path: '/tracingEnabled', value: 'false' },
 { op: 'replace', path: '/*/*/logging/dataTrace', value: 'false' },
 { op: 'replace', path: '/*/*/logging/loglevel', value: 'OFF' },
 [length]: 3 ] })

```

Is there a way I can create API gateway resource with CloudFormation script rather than serverless creation? Because even if I manage to enable logs, I need to enable caching and access logging as well.

---

<div class="post-metadata">

**Author:** ![jonathandeclan](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/jonathandeclan/32/3402_2.png) [@jonathandeclan](https://forum.serverless.com/u/jonathandeclan)\
**Post date:** [June 13, 2019, 2:33pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/15 "2019-06-13T14:33:41Z")

</div>

Try downgrading to serverless 1.41.1 , able to configure cloud watch logs and access logs

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forum.serverless.com/u/Nil)\
**Post date:** [June 13, 2019, 3:48pm UTC](https://forum.serverless.com/t/knowledge-sharing-enable-cloud-watch-logs-for-api-gateway-using-serverless/3287/16 "2019-06-13T15:48:37Z")

</div>

I have tried with 1.41.1 and it didn’t work and then I have installed the latest version(1.45.1) and tried again. It didn’t work and it gave the following error message:

`Rest API could not be resolved. This might be casued by a custom API Gateway setup. With you current setup stage specific configurations such as tracing, logs and tags are not supportedPlease update your configuration or open up an issue if you feel that there's a way to support your setup.`

By the way there is a spelling mistake in the error message; `casued` should be replaced with `caused`.

I have deleted the whole stack and tried again and finally it worked with the following key:

```
  logs:
    restApi: true

```

Thanks for helping me out! 🙂
