Skip to content

Add tracing of request events + mention LOG_LEVEL in README #315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Sources/AWSLambdaRuntimeCore/LambdaRunner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ internal final class LambdaRunner {
allocator: self.allocator,
invocation: invocation
)
logger.debug("sending invocation to lambda handler")
// when log level is trace or lower, print the first Kb of the payload
if logger.logLevel <= .trace, let buffer = bytes.getSlice(at: 0, length: max(bytes.readableBytes, 1024)) {
logger.trace("sending invocation to lambda handler",
metadata: ["1024 first bytes": .string(String(buffer: buffer))])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect String(buffer: buffer) may fail if buffer is not a string, please make sure it does not crash

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the AWS Lambda service API documentation, the payload is always a string
https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html

} else {
logger.debug("sending invocation to lambda handler")
}
return handler.handle(bytes, context: context)
// Hopping back to "our" EventLoop is important in case the handler returns a future that
// originated from a foreign EventLoop/EventLoopGroup.
Expand Down
44 changes: 44 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,50 @@ Next, create a `MyLambda.swift` and implement your Lambda. Note that the file ca

Beyond the small cognitive complexity of using the `EventLoopFuture` based APIs, note these APIs should be used with extra care. An `EventLoopLambdaHandler` will execute the user code on the same `EventLoop` (thread) as the library, making processing faster but requiring the user code to never call blocking APIs as it might prevent the underlying process from functioning.

## Testing Locally

Before deploying your code to AWS Lambda, you can test it locally by setting the `LOCAL_LAMBDA_SERVER_ENABLED` environment variable to true. It will look like this on CLI:

```sh
LOCAL_LAMBDA_SERVER_ENABLED=true swift run
```

This starts a local HTTP server listening on port 7000. You can invoke your local Lambda function by sending an HTTP POST request to `http://127.0.0.1:7000/invoke`.

The request must include the JSON payload expected as an `Event` by your function. You can create a text file with the JSON payload documented by AWS or captured from a trace. In this example, we used [the APIGatewayv2 JSON payload from the documentation](https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html#apigateway-example-event), saved as `events/create-session.json` text file.

Then we use curl to invoke the local endpoint with the test JSON payload.

```sh
curl -v --header "Content-Type:\ application/json" --data @events/create-session.json http://127.0.0.1:7000/invoke
* Trying 127.0.0.1:7000...
* Connected to 127.0.0.1 (127.0.0.1) port 7000
> POST /invoke HTTP/1.1
> Host: 127.0.0.1:7000
> User-Agent: curl/8.4.0
> Accept: */*
> Content-Type:\ application/json
> Content-Length: 1160
>
< HTTP/1.1 200 OK
< content-length: 247
<
* Connection #0 to host 127.0.0.1 left intact
{"statusCode":200,"isBase64Encoded":false,"body":"...","headers":{"Access-Control-Allow-Origin":"*","Content-Type":"application\/json; charset=utf-8","Access-Control-Allow-Headers":"*"}}
```

## Increase logging verbosity

You can increase the verbosity of the runtime using the `LOG_LEVEL` environment variable.

- `LOG_LEVEL=debug` displays information about the Swift AWS Lambda Runtime activity and lifecycle
- `LOG_LEVEL=trace` displays a string representation of the input event as received from the AWS Lambda service (before invoking your handler).

You can modify the verbosity of a Lambda function by passing the LOG_LEVEL environment variable both during your local testing (LOG_LEVEL=trace LOCAL_LAMBDA_SERVER_ENABLED=true swift run) or when you deploy your code on AWS Lambda.
You can [define environment variables for your Lambda functions](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html) in the AWS console or programmatically.

This repository follows [Swift's Log Level Guidelines](https://www.swift.org/server/guides/libraries/log-levels.html). At `LOG_LEVEL=trace`, the AWS Lambda runtime will display a string representation of the input event as received from the AWS Lambda service before invoking your handler, for maximum debuggability.

## Deploying to AWS Lambda

To deploy Lambda functions to AWS Lambda, you need to compile the code for Amazon Linux which is the OS used on AWS Lambda microVMs, package it as a Zip file, and upload to AWS.
Expand Down