|
1 |
| -# Example ElasticSearch Extension in Python |
2 |
| -The provided code sample demonstrates how to get a basic extension written in Python 3 up and running. |
| 1 | +# Example Logs API Extension in Python for Elasticsearch |
| 2 | +The provided code sample demonstrates how to get a basic Logs API extension for Elasticsearch written in Python 3 up and running. |
3 | 3 |
|
4 |
| -> Note: This extension requires the Python 3 runtime to be present in the Lambda execution environment of your function. |
| 4 | +> Note: This extension requires the Python 3 runtime to be present in the Lambda execution environment of your function. This example code is not production ready. Use it with your own discretion after testing thoroughly. |
5 | 5 |
|
6 |
| -There are two components to this sample: |
7 |
| -* `extensions/`: This sub-directory should be extracted to /opt/extensions where the Lambda platform will scan for executables to launch extensions |
8 |
| -* `python-example-elasticsearch-extension/`: This sub-directory should be extracted to /opt/python-example-extension which is referenced by the `extensions/python-example-elasticsearch-extension` executable and includes a Python executable along with all of its necessary dependencies. |
| 6 | +In this example, we start by developing a simple extension and then add the ability to read logs from the Logs API. For more details on building an extension, please read the Extension API Developer Guide. |
9 | 7 |
|
10 |
| -## Prep Python Dependencies |
11 |
| -Install the extension dependencies locally, which will be mounted along with the extension code. |
12 |
| - |
13 |
| -```bash |
14 |
| -$ cd python-example-elasticsearch-extension |
15 |
| -$ chmod +x extension.py |
16 |
| -$ pip3 install -r requirements.txt -t . |
17 |
| -$ cd .. |
18 |
| -``` |
| 8 | +When the Lambda service sets up the execution environment, it runs the extension (logs_api_elasticsearch_extension.py). This extension first registers as an extension and then subscribes to the Logs API to receive the logs via HTTP protocol. It starts an HTTP listener which receives the logs and processes them. |
19 | 9 |
|
20 | 10 | ## Layer Setup Process
|
21 |
| -The extensions .zip file should contain a root directory called `extensions/`, where the extension executables are located and another root directory called `python-example-elasticsearch-extension/`, where the core logic of the extension and its dependencies are located. |
| 11 | +The extensions .zip file should contain a root directory called `extensions/`, where the extension executables are located. The dependencies for the extension (logs_api_elasticsearch_extension.py) are found in the logs_api_elasticsearch_extension directory. |
22 | 12 |
|
23 | 13 | Creating zip package for the extension:
|
24 | 14 | ```bash
|
25 |
| -$ chmod +x extensions/python-example-elasticsearch-extension |
| 15 | +$ cd python-example-elasticsearch-extension |
| 16 | +$ chmod +x extensions/logs_api_elasticsearch_extension.py |
26 | 17 | $ zip -r extension.zip .
|
27 | 18 | ```
|
28 | 19 |
|
29 |
| -Ensure that you have aws-cli v2 for the commands below. |
30 |
| -Publish a new layer using the `extension.zip`. The output of the following command should provide you a layer arn. |
| 20 | +Publish a new layer using the `extension.zip`. The output of the following command should provides you a layer arn. |
31 | 21 | ```bash
|
32 | 22 | aws lambda publish-layer-version \
|
33 |
| - --layer-name "python-example-extension" \ |
| 23 | + --layer-name "python-example-elasticsearch-extension" \ |
34 | 24 | --region <use your region> \
|
35 | 25 | --zip-file "fileb://extension.zip"
|
36 | 26 | ```
|
37 | 27 | Note the LayerVersionArn that is produced in the output.
|
38 |
| -eg. `"LayerVersionArn": "arn:aws:lambda:<region>:123456789012:layer:<layerName>:1"` |
39 |
| - |
40 |
| -Add the newly created layer version to a Python 3.8 runtime Lambda function. Ensure to include environment variables like `ES_ENDPOINT`="ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com" and `ES_INDEX`="extensions" |
41 |
| - |
| 28 | +e.g. `"LayerVersionArn": "arn:aws:lambda:<region>:123456789012:layer:python-example-elasticsearch-extension:1"` |
42 | 29 |
|
43 |
| -## Function Invocation and Extension Execution |
44 |
| - |
45 |
| -When invoking the function, you should now see log messages from the example extension similar to the following: |
46 |
| -``` |
47 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX EXTENSION Name: python-example-elasticsearch-extension State: Ready Events: [INVOKE,SHUTDOWN] |
48 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX START RequestId: 9ca08945-de9b-46ec-adc6-3fe9ef0d2e8d Version: $LATEST |
49 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX python-example-elasticsearch-extension launching extension |
50 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Registering... |
51 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Registered with ID: 6ec8756c-4830-458b-9dda-156e5dda1cc1 |
52 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Waiting for event... |
53 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Received event: {"eventType": "INVOKE", "deadlineMs": 1596756305517, "requestId": "4b61d2be-3ba0-4e99-9121-30268b462c77", "invokedFunctionArn": "", "tracing": {"type": "X-Amzn-Trace-Id", "value": ""}} |
54 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Sending payload: {"functionName": "defaultFunctionName", "functionVersion": "$LATEST", "requestId": "4b61d2be-3ba0-4e99-9121-30268b462c77", "waitDuration": 3787.946044921875} |
55 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Attempting POST to: https://ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com/extensions/_doc |
56 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Response: {"_index":"extensions","_type":"_doc","_id":"eW8WxnMB4bYnBqSFvK5w","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1} |
57 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [python-example-elasticsearch-extension] Waiting for event... |
58 |
| - ... |
59 |
| - ... |
60 |
| - Function logs... |
61 |
| - ... |
62 |
| - ... |
63 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX END RequestId: 9ca08945-de9b-46ec-adc6-3fe9ef0d2e8d |
64 |
| - XXXX-XX-XXTXX:XX:XX.XXX-XX:XX REPORT RequestId: 9ca08945-de9b-46ec-adc6-3fe9ef0d2e8d Duration: 80.36 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 67 MB Init Duration: 297.83 ms |
| 30 | +Add the newly created layer version to a Python 3.8 runtime Lambda function. |
| 31 | +```bash |
| 32 | +aws lambda update-function-configuration --region <use your region> --function-name <your function name> --layers <LayerVersionArn from previous step> |
65 | 33 | ```
|
66 | 34 |
|
67 |
| - |
68 |
| - |
69 |
| - |
70 |
| - |
| 35 | +## Lambda Function Deployment |
| 36 | +When deploying the Lambda function, be sure to include configure two environment variables that the extension will leverage for communicating with the Elasticsearch cluster. |
| 37 | +ES_ENDPOINT: The endpoint for the Elasticsearch cluster, e.g. elasticsearch.example.com (don't need to include https:// or the trailing /). This endpoint must be reachable from the Lambda function. |
| 38 | +ES_INDEX: The index to which the extension should write log outputs. |
0 commit comments