diff --git a/docs/shipping/AWS/aws-lambda-extensions.md b/docs/shipping/AWS/aws-lambda-extensions.md index e4e6b4de..c60a06de 100644 --- a/docs/shipping/AWS/aws-lambda-extensions.md +++ b/docs/shipping/AWS/aws-lambda-extensions.md @@ -14,303 +14,118 @@ metrics_alerts: [] drop_filter: [] --- -Lambda Extensions enable tools to integrate deeply into the Lambda execution environment to control and participate in Lambda’s lifecycle. -To read more about Lambda Extensions, [click here](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html). -The Logz.io Lambda extension for logs, uses the AWS Extensions API and [AWS Logs API](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported), and sends your Lambda Function Logs directly to your Logz.io account. +## Overview -This repo is based on the [AWS lambda extensions sample](https://github.com/aws-samples/aws-lambda-extensions). -This extension is written in Go, but can be run with runtimes that support [extensions](https://docs.aws.amazon.com/lambda/latest/dg/using-extensions.html). +This AWS Lambda Extension provides a streamlined way to collect telemetry data (logs, metrics, and traces) generated by your Lambda functions and the Lambda platform itself, sending it directly to your Logz.io account. It leverages the AWS Lambda Telemetry API for efficient, out-of-process data collection with minimal impact on function performance. -## Prerequisites +By using this extension, you can centralize your Lambda observability data in Logz.io without relying solely on CloudWatch Logs forwarding or complex trigger setups. -* Lambda function with [supported runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported) for extensions. -* AWS Lambda limitations: A function can use up to five layers at a time. The total unzipped size of the function and all layers cannot exceed the unzipped deployment package size limit of 250 MB. +## Features +* **Comprehensive Telemetry Collection:** Subscribes to the Lambda Telemetry API to receive platform events (lifecycle, reports, errors), function logs (`stdout`/`stderr`), and extension logs. +* **Direct Logz.io Shipping:** Securely sends Logs, Metrics (Prometheus Remote Write format), and Traces (OTLP/HTTP format) to your configured Logz.io account endpoints. +* **Standard Formats & Rich Context:** + * **Logs:** Events are processed into a structured JSON format. Log messages from your function code are automatically enriched with contextual information like `service_name`, `environment`, and the Lambda `requestId` (`faas.instance`) for easy correlation. + * **Metrics:** Platform metrics (e.g., duration, memory usage) are converted to the Prometheus time series format. Metrics are automatically decorated with standard AWS context labels, including `service_name`, `environment`, `faas.name`, `faas.version`, and the unique `faas.execution` request ID. + * **Traces:** The extension automatically processes X-Ray context from platform events to generate and export synthetic OpenTelemetry spans. This provides visibility into the Lambda platform's lifecycle and correlates logs with traces out-of-the-box. It also supports traces generated by instrumented function code. +* **Configurable:** Enable or disable Logs, Metrics, or Traces independently. All settings, including Logz.io region and tokens, are configured via environment variables. +* **Deployment Flexibility:** Deploy as a Lambda Layer for zip-archived functions or embed it directly into custom container images. +* **Minimal Function Impact:** Runs as a separate process within the Lambda execution environment, ensuring low overhead on your function's performance. -## Important notes +## Installation -* If an extension does not have enough time to receive logs from AWS Logs API, it may send the logs at the next invocation of the Lambda function. -If you want to send all the logs by the time your Lambda function stops running, you will need to add a sleep interval at the end of your Lambda function code. This will give the extension enough time to do the job. -* Due to [Lambda's execution environment lifecycle](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html), the extension is invoked at two events - `INVOKE` and `SHUTDOWN`. -This means that if your Lambda function goes into the `SHUTDOWN` phase, the extension will start running and send all logs that are in the queue. +There are two ways to install the extension, depending on how you deploy your Lambda function: +### **Method 1: Using Lambda Layers (Recommended for zip archives deployments)** -## Deploying Logz.io logs extension +1. **Find Layer ARN:** Go to the project's [**GitHub Releases Page**](https://github.com/logzio/opentelemetry-lambda-layer/releases) to find the latest `` number and the complete list of Layer ARNs for all supported regions. -You can deploy the extension via the AWS CLI or via the AWS Management Console. +2. **Use the ARN:** Copy the appropriate Layer ARN from the release page for your function's region and architecture. The ARNs follow this format: -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + * For **x86_64 / amd64** architecture: + ``` + arn:aws:lambda::486140753397:layer:logzio-otel-lambda-extension: + ``` - - + * For **arm64** (Graviton2) architecture: + ``` + arn:aws:lambda::486140753397:layer:logzio-otel-lambda-extension-arm64: + ``` -## Deploying via the AWS CLI +3. **Add Layer:** In your Lambda function's configuration (via AWS Console, CLI, SAM, Terraform, etc.), add the Layer ARN from the releases page. -### Deploy the extension and configuration +4. **Configure Environment Variables:** Set the necessary environment variables as described in the Configuration section below. -If you haven't done it already, [install](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) and [configure](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) the AWS CLI. +### **Method 2: Embedding in Container Image (Recommended for container-based deployments)** -Add the layer to your function and configure the environment variables using the following command: +If you deploy your Lambda function using a custom container image, embed the extension directly: -```shell -aws lambda update-function-configuration \ - --function-name <> \ - --layers <> \ - --environment "Variables={<>}" -``` +1. **Obtain Executable:** Download the pre-compiled Linux executable (`logzio-extension-amd64` or `logzio-extension-arm64`) for your function's architecture from the project's **Releases Page**. +2. **Modify Dockerfile:** Add the following instructions to your function's `Dockerfile`: -:::note -This command overwrites the existing function configuration. If you already have your own layers and environment variables for your function, include them in the list. -::: + ```dockerfile + # --- Add Logz.io Lambda Extension --- + # Create the standard extensions directory + RUN mkdir -p /opt/extensions/ + # Copy the downloaded extension executable into the directory + # Make sure 'logzio-extension-amd64' is in the same directory as your Dockerfile or adjust the path + COPY ./logzio-extension-amd64 /opt/extensions/logzio-extension -| Placeholder | Description | Required/Default| -|---|---|---| -| `<>` | Name of the Lambda Function you want to monitor. |Required| -| `<>` | A space-separated list of function layers to add to the function's execution environment. Specify each layer by its ARN, including the version. For the ARN, see the [**ARNs** table](https://docs.logz.io/docs/shipping/aws/lambda-extensions/#arns) | | -| `<>` | Key-value pairs containing environment variables that are accessible from function code during execution. Should appear in the following format: `KeyName1=string,KeyName2=string`. For a list of all the environment variables for the extension, see the [**Lambda environment variables** table](https://docs.logz.io/docs/shipping/Compute/Lambda-extensions#environment-variables) | | + # Make it executable + RUN chmod +x /opt/extensions/logzio-extension + # --- End Add Logz.io Lambda Extension --- -#### Command example -```shell -aws lambda update-function-configuration \ - --function-name exampleFunction \ - --layers arn:aws:lambda:us-east-1:486140753397:layer:LogzioLambdaExtensionLogs:14 \ - --environment "Variables={LOGZIO_LOGS_TOKEN=<>,LOGZIO_LISTENER=<>,ENABLE_PLATFORM_LOGS=true,GROK_PATTERNS='{}',LOGS_FORMAT='^\[%{NUMBER:logId}\] %{GREEDYDATA:message}',CUSTOM_FIELDS='fieldName1=fieldValue1,fieldName2=fieldValue2',JSON_FIELDS_UNDER_ROOT=true}" -``` + # Your original CMD or ENTRYPOINT for your Lambda function + # e.g., CMD [ "your_handler.handler" ] + ``` +3. **Configure Environment Variables:** Set the necessary environment variables in your Lambda function's configuration. +4. **Deploy:** Build and deploy your container image. -#### Deleting the extension +## Configuration -To delete the extension and its environment variables, use the following command: +Configure the extension using Lambda environment variables: -```shell -aws lambda update-function-configuration \ - --function-name <> \ - --layers \ - --environment "Variables={}" -``` +| Variable | Required | Default | Description | +| :------------------------------ | :------- | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `LOGZIO_APP_REGION` | **Yes** | `us` | Your two-letter [Logz.io account region code](https://docs.logz.io/docs/user-guide/admin/hosting-regions/account-region/#available-regions) (e.g., `eu`, `ca`, `au`). This determines all listener URLs. | +| `LOGZIO_LOGS_TOKEN` | If Logs | `""` | Your Logz.io Logs Shipping Token. | +| `LOGZIO_METRICS_TOKEN` | If Metrics| `""` | Your Logz.io Metrics Shipping Token (for Prometheus). | +| `LOGZIO_TRACES_TOKEN` | If Traces| `""` | Your Logz.io Tracing Shipping Token (for OTLP). | +| `LOGZIO_LOGS_ENABLED` | No | `true` | Set to `false` to disable sending logs. | +| `LOGZIO_METRICS_ENABLED` | No | `true` | Set to `false` to disable sending metrics. | +| `LOGZIO_TRACES_ENABLED` | No | `true` | Set to `false` to disable sending traces. | +| `LOG_LEVEL` | No | `info` | Log level for the extension itself (`trace`, `debug`, `info`, `warn`, `error`). | +| `ENVIRONMENT` | No | `""` | Deployment environment (e.g., `prod`, `dev`). Added as a `deployment.environment` attribute to all telemetry. | +| `OTEL_SERVICE_NAME` | No | (AWS Function Name) | Service name for all telemetry. Defaults to `AWS_LAMBDA_FUNCTION_NAME`. Setting this explicitly is recommended. | +| `LOGZIO_METRIC_LABELS` | No | `""` | Comma-separated `key=value` pairs for custom static metric labels (e.g., `team=backend,app=my-app`). | +| `LOGZIO_DRAIN_DURATION_SECONDS` | No | `2s` | How often the internal log buffer flushes to Logz.io. Must include a unit (e.g., `2s`, `500ms`). | +| `DISPATCH_MIN_BATCH_SIZE` | No | `1` | Minimum number of events the dispatcher processes before sending (unless forced). | +| `DISPATCH_MAX_BATCH_SIZE` | No | `1000` | Maximum number of events the dispatcher will pull from the queue in a single cycle. | +| `LISTENER_QUEUE_SIZE` | No | `2048` | Size of the internal buffer between the listener and dispatcher. Increase if seeing `platform.logsDropped` frequently. | -:::note -This command overwrites the existing function configuration. If you already have your own layers and environment variables for your function, include them in the list. -::: +**Note on CloudWatch Costs:** This extension sends data directly to Logz.io *in addition to* standard AWS mechanisms. To avoid duplicate data ingestion costs from CloudWatch, you can prevent your function from sending logs to CloudWatch Logs by removing the `logs:CreateLogStream` and `logs:PutLogEvents` permissions from its IAM execution role. -```shell -aws lambda update-function-configuration \ - --function-name <> \ - --layers [<>] \ - --environment "Variables={<>}" -``` -::: +## Supported Runtimes - - +This extension works with all AWS Lambda runtimes that support Lambda Extensions, including custom runtimes and container images. -## Deploying via the AWS Management Console +## Building from Source -### Add the extension to your Lambda Function +Ensure you have Go installed (version 1.21 or higher recommended). -1. In the Lambda Functions screen, choose the function you want to monitor. -![Pick lambda function](https://dytvr9ot2sszz.cloudfront.net/logz-docs/lambda_extensions/lambda-x_1-1.jpg) - -2. In the page for the function, scroll down to the `Layers` section and choose `Add Layer`. -![Add layer](https://dytvr9ot2sszz.cloudfront.net/logz-docs/lambda_extensions/lambda-x_1-2.jpg) - -3. Select the `Specify an ARN` option, then choose the ARN of the extension with the region code that matches your Lambda Function region from the [**ARNs** table](https://docs.logz.io/docs/shipping/aws/lambda-extensions/#arns), and click the `Add` button. - -![Add ARN extension](https://dytvr9ot2sszz.cloudfront.net/logz-docs/lambda_extensions/lambda-x_1-3.jpg) - -### Configure the extension parameters - -Add environment variables to the function, according to the [**Environment variables** table](https://docs.logz.io/docs/shipping/Compute/Lambda-extensions#environment-variables). - - -#### Deleting the extension - -- To delete the **extension layer**: In your function page, go to the **layers** panel. Click `edit`, select the extension layer, and click `save`. -- To delete the extension's **environment variables**: In your function page, select the `Configuration` tab, select `Environment variables`, click `edit`, and remove the variables that you added for the extension. - - - - - - -### Check Logz.io for your logs - -Give your logs some time to get from your system to ours. It may take more than one run of the function for the logs to start shipping to your Logz.io account. - -:::note -Your lambda logs will appear under the type `lambda-extension-logs`. -::: - -#### Pre-Built content - -Log in to your Logz.io account and navigate to the [current instructions page](https://app.logz.io/#/dashboard/integrations/Lambda-extensions) to install the pre-built dashboard to enhance the observability of your logs. - - - - -## Environment Variables - -| Name | Description |Required/Default| -| --- | --- | --- | -| `LOGZIO_LOGS_TOKEN` | Your Logz.io log shipping [token](https://app.logz.io/#/dashboard/settings/manage-tokens/data-shipping). | Required | -| `LOGZIO_LISTENER` | {@include: ../../_include/log-shipping/listener-var.md} For example: `https://listener.logz.io:8071`. | Required | -| `LOGS_EXT_LOG_LEVEL` | Log level of the extension. Can be set to one of the following: `debug`, `info`, `warn`, `error`, `fatal`, `panic`. |Default: `info` | -| `ENABLE_PLATFORM_LOGS` | The platform log captures runtime or execution environment errors. Set to `true` if you wish the platform logs will be shipped to your Logz.io account. | Default: `false` | -| `GROK_PATTERNS` | Must be set with `LOGS_FORMAT`. Use this if you want to parse your logs into fields. A minified JSON list that contains the field name and the regex that will match the field. To understand more see the [parsing logs](https://docs.logz.io/docs/shipping/aws/lambda-extensions/#parsing-logs) section. | - | -| `LOGS_FORMAT` | Must be set with `GROK_PATTERNS`. Use this if you want to parse your logs into fields. The format in which the logs will appear, in accordance to grok conventions. To understand more see the [parsing logs](https://docs.logz.io/docs/shipping/aws/lambda-extensions/#parsing-logs) section. | - | -| `CUSTOM_FIELDS` | Include additional fields with every message sent, formatted as `fieldName1=fieldValue1,fieldName2=fieldValue2` (**NO SPACES**). A custom key that clashes with a key from the log itself will be ignored. | - | -| `JSON_FIELDS_UNDER_ROOT` | If you log Json messages and would like the fields to be nested at the root of the log, instead of under `message_nested`. | Default: `False` | - -## ARNs -### AMD64 Architecture -| Region Name | Region Code | AWS ARN | -|---------------------------|------------------|--------------------------------------------------------------------------------| -| US East (N. Virginia) | `us-east-1` | `arn:aws:lambda:us-east-1:486140753397:layer:LogzioLambdaExtensionLogs:16` | -| US East (Ohio) | `us-east-2` | `arn:aws:lambda:us-east-2:486140753397:layer:LogzioLambdaExtensionLogs:16` | -| US West (N. California) | `us-west-1` | `arn:aws:lambda:us-west-1:486140753397:layer:LogzioLambdaExtensionLogs:16` | -| US West (Oregon) | `us-west-2` | `arn:aws:lambda:us-west-2:486140753397:layer:LogzioLambdaExtensionLogs:15` | -| Europe (Frankfurt) | `eu-central-1` | `arn:aws:lambda:eu-central-1:486140753397:layer:LogzioLambdaExtensionLogs:17` | -| Europe (Ireland) | `eu-west-1` | `arn:aws:lambda:eu-west-1:486140753397:layer:LogzioLambdaExtensionLogs:15` | -| Europe (Stockholm) | `eu-north-1` | `arn:aws:lambda:eu-north-1:486140753397:layer:LogzioLambdaExtensionLogs:16` | -| Asia Pacific (Sydney) | `ap-southeast-2` | `arn:aws:lambda:ap-southeast-2:486140753397:layer:LogzioLambdaExtensionLogs:16` | -| Canada (Central) | `ca-central-1` | `arn:aws:lambda:ca-central-1:486140753397:layer:LogzioLambdaExtensionLogs:17` | -| South America (São Paulo) | `sa-east-1` | `arn:aws:lambda:sa-east-1:486140753397:layer:LogzioLambdaExtensionLogs:18` | -| Asia Pacific (Tokyo) | `ap-northeast-1` | `arn:aws:lambda:ap-northeast-1:486140753397:layer:LogzioLambdaExtensionLogs:12` | -| Asia Pacific (Singapore) | `ap-southeast-1` | `arn:aws:lambda:ap-southeast-1:486140753397:layer:LogzioLambdaExtensionLogs:13` | -| Asia Pacific (Mumbai) | `ap-south-1` | `arn:aws:lambda:ap-south-1:486140753397:layer:LogzioLambdaExtensionLogs:12` | -| Asia Pacific (Osaka) | `ap-northeast-3` | `arn:aws:lambda:ap-northeast-3:486140753397:layer:LogzioLambdaExtensionLogs:13` | -| Asia Pacific (Seoul) | `ap-northeast-2` | `arn:aws:lambda:ap-northeast-2:486140753397:layer:LogzioLambdaExtensionLogs:13` | -| Europe (London) | `eu-west-2` | `arn:aws:lambda:eu-west-2:486140753397:layer:LogzioLambdaExtensionLogs:14` | -| Europe (Paris) | `eu-west-3` | `arn:aws:lambda:eu-west-3:486140753397:layer:LogzioLambdaExtensionLogs:13` | - -### ARM64 Architecture -| Region Name | Region Code | AWS ARN | -|---------------------------|------------------|-----------------------------------------------------------------------------------| -| US East (N. Virginia) | `us-east-1` | `arn:aws:lambda:us-east-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| US East (Ohio) | `us-east-2` | `arn:aws:lambda:us-east-2:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| US West (N. California) | `us-west-1` | `arn:aws:lambda:us-west-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| US West (Oregon) | `us-west-2` | `arn:aws:lambda:us-west-2:486140753397:layer:LogzioLambdaExtensionLogsArm:7` | -| Europe (Frankfurt) | `eu-central-1` | `arn:aws:lambda:eu-central-1:486140753397:layer:LogzioLambdaExtensionLogsArm:7` | -| Europe (Ireland) | `eu-west-1` | `arn:aws:lambda:eu-west-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Europe (Stockholm) | `eu-north-1` | `arn:aws:lambda:eu-north-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Asia Pacific (Sydney) | `ap-southeast-2` | `arn:aws:lambda:ap-southeast-2:486140753397:layer:LogzioLambdaExtensionLogsArm:7` | -| Canada (Central) | `ca-central-1` | `arn:aws:lambda:ca-central-1:486140753397:layer:LogzioLambdaExtensionLogsArm:7` | -| South America (São Paulo) | `sa-east-1` | `arn:aws:lambda:sa-east-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Asia Pacific (Tokyo) | `ap-northeast-1` | `arn:aws:lambda:ap-northeast-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Asia Pacific (Singapore) | `ap-southeast-1` | `arn:aws:lambda:ap-southeast-1:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Asia Pacific (Mumbai) | `ap-south-1` | `arn:aws:lambda:ap-south-1:486140753397:layer:LogzioLambdaExtensionLogsArm:7` | -| Asia Pacific (Osaka) | `ap-northeast-3` | `arn:aws:lambda:ap-northeast-3:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Asia Pacific (Seoul) | `ap-northeast-2` | `arn:aws:lambda:ap-northeast-2:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | -| Europe (London) | `eu-west-2` | `arn:aws:lambda:eu-west-2:486140753397:layer:LogzioLambdaExtensionLogsArm:7` | -| Europe (Paris) | `eu-west-3` | `arn:aws:lambda:eu-west-3:486140753397:layer:LogzioLambdaExtensionLogsArm:8` | - - -:::note -If your AWS region is not in the list, please reach out to Logz.io's support or open an issue in the [project's Github repo](https://github.com/logzio/logzio-lambda-extensions). -::: - -## Parsing logs - -By default, the extension sends the logs as strings. -If your logs are formatted, and you wish to parse them to separate fields, the extension will use the [grok library](https://github.com/vjeantet/grok) to parse grok patterns. -You can see all the pre-built grok patterns (for example `COMMONAPACHELOG` is already a known pattern in the library) [here](https://github.com/vjeantet/grok/tree/master/patterns). -If you need to use a custom pattern, you can use the environment variables `GROK_PATTERNS` and `LOGS_FORMAT`. - -### Example - -For logs that are formatted like this: - -```python -<> <>: <> -# Examples -May 04 2024 10:48:34.244 my_app: an awesome message -May 04 2024 10:50:46.532 logzio_sender: Successfully sent bulk to logz.io, size: 472 -``` - -In Logz.io we wish to have `timestamp`, `app_name` and `message` in their own fields. -To do so, we'll set the environment variables as follows: - -#### GROK_PATTERNS - -The `GROK_PATTERNS` variable contains definitions of custom grok patterns and should be in a JSON format. -- key - is the custom pattern name. -- value - the regex that captures the pattern. - -In our example: -- `timestamp` - matching the regex `\w+ \d{2} \d{4} \d{2}:\d{2}:\d{2}\.\d{3}`. -- `app_name` - always non-space character sequence, so matching `\S+`. -- `message` - have strings containing whitespaces, letters and numbers. So matching `.*`. - -For the regex that matches `app_name` and `message` there are built in grok patterns (we'll see in `LOGS_FORMAT` explanation), so we only need to define custom pattern for our `timestamp`. -Meaning we can set `GROK_PATTERNS` as: -``` json -{"MY_CUSTOM_TIMESTAMP":"\\w+ \\d{2} \\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}"} -``` - -#### LOGS_FORMAT - -The `LOGS_FORMAT` variable contains the full grok pattern that will match the format of the logs, using known patterns and the custom patterns that were defined in `GROK_PATTERNS` (if defined). -The variable should be in a grok format: -``` -%{GROK_PATTERN_NAME:WANTED_FIELD_NAME} -``` - -:::warning -The `WANTED_FIELD_NAME` cannot contain a dot (`.`). -::: - -In our example: -- `timestamp` - matching the custom pattern we defined previously `MY_CUSTOM_TIMESTAMP`. -- `app_name` - is matching the known grok pattern `NOTSPACE`. -- `message` - is matching the known grok pattern `GREEDYDATA`. - -So we will set `LOGS_FORMAT` as: -``` -^%{MY_CUSTOM_TIMESTAMP:timestamp} %{NOTSPACE:app_name}: %{GREEDYDATA:message} -``` - -The log example from above: -``` -May 04 2024 10:48:34.244 my_app: an awesome message -``` -Will be parsed to look like this: - -``` -timestamp: May 04 2024 10:48:34.244 -app_name: my_app -message: an awesome message -``` - -This project uses an external module for its grok parsing. To learn more about it, see the [grok library repo](https://github.com/vjeantet/grok). - -### Nested fields - -**As of v0.2.0** the extension can detect if a log is in a JSON format, and to parse the fields to appear as nested fields in the Logz.io app. -For example, the following log: - -```json -{ "foo": "bar", "field2": "val2" } -``` - -Will appear under the fields: -``` -message_nested.foo: bar -message_nested.field2: val2 -``` - -**As of v0.3.3**, to have the fields nested under the root (instead of under `message_nested`), set the `JSON_FIELDS_UNDER_ROOT` environment variable as `true`. -It is useful in cases where the passed object is in fact meant to be that of a message plus metadata fields. -For example, the following log: - -```json -{ "message": "hello", "foo": "bar" } -``` - -Will appear under the fields: -``` -message: hello -foo: bar -``` - -**Note:** The user must insert a valid JSON. Sending a dictionary or any key-value data structure that is not in a JSON format will cause the log to be sent as a string. +1. **Clone the repository:** + ```bash + git clone [https://github.com/logzio/opentelemetry-lambda-layer.git](https://github.com/logzio/opentelemetry-lambda-layer.git) + cd opentelemetry-lambda-layer + ``` +2. **Build:** Use the provided Makefile. + * For `x86_64` (Intel/AMD) Lambda functions: + ```bash + make build-linux-amd64 + ``` + * For `arm64` (Graviton2) Lambda functions: + ```bash + make build-linux-arm64 + ``` + The compiled executable will be in the `bin/` directory. \ No newline at end of file