|
| 1 | +<p align="center"> |
| 2 | + <img src="docs/Arch_AWS-Lambda_64.svg" alt="AWS Lambda service icon"> |
| 3 | +</p> |
| 4 | + |
| 5 | +<h2 align="center">AWS Lambda Profiler Extension for Java</h2> |
| 6 | + |
| 7 | +The Lambda profiler extension allows you to profile your Java functions invoke by invoke, with high fidelity, and no |
| 8 | +code changes. It uses the [async-profiler](https://github.com/async-profiler/async-profiler) project to produce |
| 9 | +profiling data and automatically uploads the data as flame graphs to S3. |
| 10 | + |
| 11 | +<p align="center"> |
| 12 | + <img src="docs/example-cold-start-flame-graph.png" alt="A flame graph of a Java Lambda function"> |
| 13 | +</p> |
| 14 | + |
| 15 | +### Usage |
| 16 | + |
| 17 | +To use the profiler you need to |
| 18 | + |
| 19 | +1. Build the extension in this repo |
| 20 | +2. Deploy it as a Lambda Layer |
| 21 | +3. Create an S3 bucket for the results, or reuse an existing one |
| 22 | +4. Give your function permission to write to the bucket |
| 23 | +5. Configure the required environment variables. |
| 24 | + |
| 25 | +The following [Quick Start](#quick-start) will give you AWS CLI commands to run to get started. There are also [examples](examples) |
| 26 | +using infrastructure as code for you to refer to. |
| 27 | + |
| 28 | +### Quick Start |
| 29 | + |
| 30 | +- Clone the repo |
| 31 | + |
| 32 | +```bash |
| 33 | +git clone https://github.com/aws/aws-lambda-java-libs |
| 34 | +``` |
| 35 | + |
| 36 | +- Build the extension |
| 37 | + |
| 38 | +```bash |
| 39 | +cd aws-lambda-java-profiler/extension |
| 40 | +./build_layer.sh |
| 41 | +``` |
| 42 | + |
| 43 | +- Run the `update-function.sh` script which will create a new S3 bucket, Lambda layer and all the configuration required. |
| 44 | + |
| 45 | +```bash |
| 46 | +cd .. |
| 47 | +./update-function.sh YOUR_FUNCTION_NAME |
| 48 | +``` |
| 49 | + |
| 50 | +### Configuration |
| 51 | + |
| 52 | +#### Required Environment Variables |
| 53 | + |
| 54 | +| Name | Value | |
| 55 | +|------------------------------|-----------------------------------------------------------------------------------------------| |
| 56 | +| PROFILER_RESULTS_BUCKET_NAME | Your unique bucket name | |
| 57 | +| JAVA_TOOL_OPTIONS | -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -javaagent:/opt/profiler-extension.jar | |
| 58 | + |
| 59 | +#### Optional Environment Variables |
| 60 | + |
| 61 | +| Name | Default Value | Options | |
| 62 | +|-------------------------------|-----------------------------------------------------------|--------------------------------| |
| 63 | +| PROFILER_START_COMMAND | start,event=wall,interval=1us | | |
| 64 | +| PROFILER_STOP_COMMAND | stop,file=%s,include=*AWSLambda.main,include=start_thread | file=%s is required | |
| 65 | +| PROFILER_DEBUG | false | true - to enable debug logging | |
| 66 | +| PROFILER_COMMUNICATION_PORT | 1234 | a valid port number | |
| 67 | + |
| 68 | +### How does it work? |
| 69 | + |
| 70 | +In `/src` is the code for a Java agent. It's entry point `AgentEntry.premain()` is executed as the runtime starts up. |
| 71 | +The environment variable `JAVA_TOOL_OPTIONS` is used to specify which .jar file the agent is in. The `MANIFEST.MF` file |
| 72 | +is used to specify the pre-main class. |
| 73 | + |
| 74 | +When the agent is constructed, it starts the profiler and registers itself as a Lambda extension for `INVOKE` request. |
| 75 | + |
| 76 | +A new thread is created to handle calling `/next` and uploading the results of the profiler to S3. The bucket to upload |
| 77 | +the result to is configurable using an environment variable. |
| 78 | + |
| 79 | +### Project Structure |
| 80 | + |
| 81 | +- `Agent.java`: Main class that coordinates profiling and S3 uploads. |
| 82 | +- `AgentEntry.java`: Entry point for the Java agent. |
| 83 | +- `ExtensionClient.java`: Handles communication with the Lambda Extensions API. |
| 84 | + |
| 85 | +### Troubleshooting |
| 86 | + |
| 87 | +- Ensure the Lambda function has the necessary permissions to write to the S3 bucket. |
| 88 | +- Verify that the environment variables are correctly set in your Lambda function configuration. |
| 89 | +- Check CloudWatch logs for any error messages from the extension. |
| 90 | + |
| 91 | +### Contributing |
| 92 | + |
| 93 | +Contributions to improve the extension are welcome. Please submit pull requests with your proposed changes. |
0 commit comments