|
| 1 | +## CloudWatch Logs Reader with GraalVM Native Image |
| 2 | + |
| 3 | +### Overview |
| 4 | + |
| 5 | +This project is a Kotlin-based application that reads log events from AWS CloudWatch Logs. It uses the AWS SDK for |
| 6 | +Kotlin and is configured to run as a native image using GraalVM. More information about GraalVM native images can be found in the [official documentation](https://www.graalvm.org/latest/reference-manual/native-image/). |
| 7 | + |
| 8 | +### How to Use |
| 9 | + |
| 10 | +#### Prerequisites |
| 11 | + |
| 12 | +<ul> |
| 13 | +<li> JDK 17</li> |
| 14 | +<li> GraalVM</li> |
| 15 | +<li> Gradle</li> |
| 16 | +<li> AWS credentials configured (e.g, using AWS CLI)</li> |
| 17 | +</ul> |
| 18 | + |
| 19 | +### What is GraalVM? |
| 20 | + |
| 21 | +GraalVM is a high-performance runtime that provides significant improvements in application performance and efficiency. |
| 22 | +It supports multiple languages and execution modes, including: |
| 23 | + |
| 24 | +- **JVM-based languages**: Java, Kotlin, Scala, etc. |
| 25 | +- **LLVM-based languages**: C, C++, Rust, etc. |
| 26 | +- **Dynamic languages**: JavaScript, Python, Ruby, etc. |
| 27 | + |
| 28 | +GraalVM can compile Kotlin applications into native executables, which improves startup time and reduces memory usage. |
| 29 | + |
| 30 | +### Running the Application with Configured Gradle Task |
| 31 | + |
| 32 | +The `nativeRun` Gradle task is configured to run the application as a native image. Here is a brief explanation of the |
| 33 | +configuration: |
| 34 | + |
| 35 | +- **Region**: The AWS region where your CloudWatch Logs are located. |
| 36 | +- **Log Group**: The name of the log group you want to read logs from. |
| 37 | +- **Log Stream**: The name of the log stream you want to read logs from. |
| 38 | +- **The task**: is defined in the `build.gradle.kts` file. |
| 39 | + |
| 40 | +This task uses the GraalVM native image plugin to build and run the application with the specified arguments. |
| 41 | + |
| 42 | +```kotlin |
| 43 | +tasks.named<org.graalvm.buildtools.gradle.tasks.NativeRunTask>("nativeRun") { |
| 44 | + this.runtimeArgs = listOf("ap-southeast-1", "my-log-group", "my-log-stream") |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +### Reflection Configuration for GraalVM |
| 49 | + |
| 50 | +GraalVM doesn’t support reflection automatically. If your code or any library you use relies on reflection, you’ll need to set it up manually when building native images. This is done by creating a reflection configuration file. The configuration file should be placed in the `src/main/resources/META-INF/native-image` directory. |
| 51 | + |
| 52 | +Here is an example of a reflection configuration file [src/main/resources/META-INF/native-image/reflect-config.json](src/main/resources/META-INF/native-image/aws/sdk/kotlin/example/reflect-config.json): |
| 53 | + |
| 54 | +```json |
| 55 | +[ |
| 56 | + { |
| 57 | + "name": "com.example.YourClass", |
| 58 | + "allDeclaredConstructors": true, |
| 59 | + "allDeclaredMethods": true, |
| 60 | + "allDeclaredFields": true |
| 61 | + } |
| 62 | +] |
| 63 | +``` |
| 64 | + |
| 65 | +In the `build.gradle.kts` file, ensure that the `META-INF/native-image` directory is added to the classpath for reflection configuration: |
| 66 | +```kotlin |
| 67 | +graalvmNative { |
| 68 | + binaries.all { |
| 69 | + resources.autodetect() |
| 70 | + // Add the META-INF/native-image directory to the classpath for reflection configuration |
| 71 | + configurationFileDirectories.from(file("src/main/resources/META-INF/native-image")) |
| 72 | + } |
| 73 | +} |
| 74 | +``` |
| 75 | +This configuration ensures that the necessary reflection metadata is available at runtime for the native image. |
| 76 | +For more details, you can refer to the [official GraalVM documentation on reflection configuration](https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/Reflection/). |
| 77 | + |
0 commit comments