Custom error metrics in Lambda function - aws-lambda

I have a (Python) Lambda function that I'm calling via AWS API Gateway (not using "Lambda Proxy integration").
The Lambda accepts a JSON payload, and if all goes well returns a JSON response.
In terms of monitoring the Lambda, I can see the following in CloudWatch:
invocations
duration
throttles
errors
The Lambda can fail in a number of ways, and in each of these cases a JSON error object is returned as the response.
I would like to add the ability to view metrics of these error conditions in CloudWatch, but reading the documentation on Cloudwatch alerts and alarms, it is not clear to me how to do this. Any ideas?

Related

Tracing HTTP Request to Lambda Function Invocation

The frontend developers at my company want to be able to see the lambda function logs of their requests.
Is there a way to pass something like a user created unique id in a header in an http request that will be passed from api gateway to the lambda function so that it easy to find the logs for that particular request?
It is an environment where there could be many requests happening simultaneously.
API Gateway will attach a unique ID to each request and this will filter through into Lambda. Each request should return a header with its response x-amzn-RequestId containing the request ID. In Lambda, you can access this request ID through the context object.
You're also free to create your own headers, x-correlation-id for example. In Lambda, you can access this header via the event.
Once you have you're value, you can attach that to your logs, directly as part of the log message or as metadata — depending on what logger you're using. If you're using CloudWatch, you might want to construct an object:
{ "requestId": "abc", "message": "This is a log entry." }
However you choose to do it, you should end up with a correlation ID which you can use to query your log entries.

Invoking AWS Lambda Authorizer using Function URL

I have implemented an AWS Lambda Authorizer in Java (type=REQUEST). I would like to invoke the lambda using a Function URL. I need to pass the following fields to my Lambda AuthorizerEvent:
headers
type (REQUEST)
methodArn
I am sending the HTTP GET message using Postman. The headers get mapped correctly to the event object. However, type and methodARN are shown as null in the CloudWatch logs and the Function URL returns a 502 Bad Gateway error:
Received AuthorizerEvent(type=null, authorizationToken=null, headers={...}, methodArn=null)
I've tried putting type and methodArn in query parameters, headers and body (even though REQUEST authorizers don't use the body, see here). I also can't find complete documentation outlining how HTTP parameters are mapped to the lambda request event parameters for Authorizer Function URLs.
Any help would be greatly appreciated!

How get AWS API Gateway & Lambda REST API to correctly handle a POST as application/x-www-form-urlencoded

I'm setting up a Lambda as a webhook handler that receive data POSTed from a remote API.
As per usual, the external webhook is POSTing the data in the form:
payload='SOME_JSON' for example payload='{"foo":"bar"}'
How can AWS API Gateway be configured to correctly handle application/x-www-form-urlencoded data POSTed from an external webhook, e.g., to correctly map the raw content string into a "form style" parameter name/value pair and pass the value (which is JSON) to the Lambda?
The problem is that AWS API Gateway, by default, tries to relay the entire raw string payload=JSONSTRING to the Lambda, but of course the payload= is not JSON, it's the form parameter name, so that generates a 400 error (body not in JSON format).
To test, I posted the same data to both the AWS API Gateway, and, so that I can see exactly what is POSTed from the webhook, also to webhook.site for debugging.
As shown below the in webhook.site screengrab, the raw data POSTed is in the usual webhook format, "parameter=value" eg payload=JSONSTRING, specifically: payload='{\"arg1\":\"val1\"}'
And as shown in the webhook.site screengrab, their site completely understood how to map that to a "parameter name" (payload) and the parameter value.
webhook.site screengrab:
The closest I've come is to get the API Gateway & Lambda to stop throwing 400 errors, by using API Gateway's "Body Mapping Template" to at least force the raw content "param=value" into JSON format using this body mapping:
{"body": "$input.body"}
as described in this helpful blog post: https://blog.summercat.com/using-aws-lambda-and-api-gateway-as-html-form-endpoint.html
(edit: that blog post was old, Body Mapping Template is not required, API Gateway now supports enabling "Use Lambda Proxy integration" on the Integration Request for the POST method which passed to the Lambda the full input object (headers, payload, etc) as JSON to get rid of the 400 errors. But the "body" key/value in the JSON is still not parse-able JSON, it is prefixed with the payload=")
But the problem is the the Lambda event hash still isn't in a usable format it still includes the "payload=...(escaped string)" e.g.
`{"body"=>"payload=%7B%22arg1%22%3A%22val1%22%7D"
So I hope there is some way to configure API Gateway to do what the rest of the world can do, and map the POSTed raw content "payload=JSONSTRING" to a JSON object that is passed to the Lambda, such as {"payload" : "JSONSTRING"} or perhaps just JSONSTRING?

API GW V2 HTTP API and legacy lambda authorizer

I'm trying to integrate API GW v2 HTTP API with legacy (payload version 1.0) custom lambda authorizer. It's able to invoke the custom lambda authorizer but getting below response ($context.authorizer.error) in gateway logs with 500 status ($context.authorizer.status https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-logging-variables.html)-
The response from the Lambda Authorizer function doesn't match the format that API Gateway expects. Invalid value for 'context'
Which indicates that it's not abiding to the response format as mentioned here-
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html#http-api-lambda-authorizer.payload-format-response
But same legacy lambda is working fine with API GW v1 REST APIs. Also cannot enable the execution logs like REST API so not able to see the actual response returned by lambda if by any chance it's not returning the correct response but i doubt that.
So problem seems to be API GW HTTP API doesn't like null values in context variable from Lambda authorizer. For now going to suppress the null values but ideally API GW should handle the null values gracefully. Another problem is it seems to be timing out in case time taken is more than 10 secs by Lambda authorizer but there's no way timeout can be configured for lambda authorizer.

AWS AppSync - GraphQL: Lambda error not resulting in errors object in AppSync response

I used to get the errors object in AppSync response and a 5xx status code - if there was an error thrown from Lambda resolver (either a timeout error or a handled error I send as the first parameter in the lambda callback)
Eg.
`callback(errorMessage, …)
I can no longer see the errors object in AppSync – even though the Lambda resolver is throwing errors.
Is this a change in implementation or a bug?
I'm having to work around this by changing the response mapping template in AppSync resolver – to use $util.error based on a flag in the Lambda response.
While doing this – I'm able to get the errors object in AppSync response – but it’s still a 200 OK response.
Any way we can override this status code in AppSync?
Have you changed the version of mapping template that you are using from 2017-02-28 to 2018-05-29? The behavior on how invocation errors are handled changes between the two versions.
A snippet from the AppSync Developer Docs:
Previously, with 2017-02-28, in case of an invocation error, the response mapping template was evaluated and the result was placed automatically in the errors block of the GraphQL response.
With 2018-05-29, we can now choose what to do with the error, re-raise it, raise a different error, or append the error while return data.
You can find the AppSync Developer Docs that I am referencing here.
Currently you cannot customize the error status code in AWS AppSync.
The suggested approach is to use errorType in the error response. You can use $util.appendError or $util.error methods in your velocity mapping template to define the error type.

Resources