

# Augment Lambda functions using Lambda extensions
<a name="lambda-extensions"></a>

You can use Lambda extensions to augment your Lambda functions. For example, use Lambda extensions to integrate functions with your preferred monitoring, observability, security, and governance tools. You can choose from a broad set of tools that [AWS Lambda Partners](https://aws.amazon.com/lambda/partners/) provides, or you can [create your own Lambda extensions](runtimes-extensions-api.md).

Lambda supports external and internal extensions. An external extension runs as an independent process in the execution environment and continues to run after the function invocation is fully processed. Because extensions run as separate processes, you can write them in a different language than the function. All [Lambda runtimes](lambda-runtimes.md) support extensions.

An internal extension runs as part of the runtime process. Your function accesses internal extensions by using wrapper scripts or in-process mechanisms such as `JAVA_TOOL_OPTIONS`. For more information, see [Modifying the runtime environment](runtimes-modify.md).

You can add extensions to a function using the Lambda console, the AWS Command Line Interface (AWS CLI), or infrastructure as code (IaC) services and tools such as CloudFormation, AWS Serverless Application Model (AWS SAM), and Terraform.

You are charged for the execution time that the extension consumes (in 1 ms increments). There is no cost to install your own extensions. For more pricing information for extensions, see [AWS Lambda Pricing](https://aws.amazon.com/lambda/pricing/). For pricing information for partner extensions, see those partners' websites. See [AWS Lambda extensions partners](extensions-api-partners.md) for a list of official partner extensions.

**Topics**
+ [Execution environment](#using-extensions-env)
+ [Impact on performance and resources](#using-extensions-reg)
+ [Permissions](#using-extensions-permissions)
+ [Configuring Lambda extensions](extensions-configuration.md)
+ [AWS Lambda extensions partners](extensions-api-partners.md)
+ [Using the Lambda Extensions API to create extensions](runtimes-extensions-api.md)
+ [Accessing real-time telemetry data for extensions using the Telemetry API](telemetry-api.md)

## Execution environment
<a name="using-extensions-env"></a>

Lambda invokes your function in an [execution environment](lambda-runtime-environment.md), which provides a secure and isolated runtime environment. The execution environment manages the resources required to run your function and provides lifecycle support for the function's runtime and extensions.

The lifecycle of the execution environment includes the following phases:
+ `Init`: In this phase, Lambda creates or unfreezes an execution environment with the configured resources, downloads the code for the function and all layers, initializes any extensions, initializes the runtime, and then runs the function’s initialization code (the code outside the main handler). The `Init` phase happens either during the first invocation, or in advance of function invocations if you have enabled [provisioned concurrency](provisioned-concurrency.md).

  The `Init` phase is split into three sub-phases: `Extension init`, `Runtime init`, and `Function init`. These sub-phases ensure that all extensions and the runtime complete their setup tasks before the function code runs.

  When [Lambda SnapStart](snapstart.md) is activated, the `Init` phase happens when you publish a function version. Lambda saves a snapshot of the memory and disk state of the initialized execution environment, persists the encrypted snapshot, and caches it for low-latency access. If you have a before-checkpoint [runtime hook](snapstart-runtime-hooks.md), then the code runs at the end of `Init` phase.
+ `Restore` (SnapStart only): When you first invoke a [SnapStart](snapstart.md) function and as the function scales up, Lambda resumes new execution environments from the persisted snapshot instead of initializing the function from scratch. If you have an after-restore [runtime hook](snapstart-runtime-hooks.md), the code runs at the end of the `Restore` phase. You are charged for the duration of after-restore runtime hooks. The runtime must load and after-restore runtime hooks must complete within the timeout limit (10 seconds). Otherwise, you'll get a SnapStartTimeoutException. When the `Restore` phase completes, Lambda invokes the function handler (the [Invoke phase](lambda-runtime-environment.md#runtimes-lifecycle-invoke)).
+ `Invoke`: In this phase, Lambda invokes the function handler. After the function runs to completion, Lambda prepares to handle another function invocation.
+ `Shutdown`: This phase is triggered if the Lambda function does not receive any invocations for a period of time. In the `Shutdown` phase, Lambda shuts down the runtime, alerts the extensions to let them stop cleanly, and then removes the environment. Lambda sends a `Shutdown` event to each extension, which tells the extension that the environment is about to be shut down.

During the `Init` phase, Lambda extracts layers containing extensions into the `/opt` directory in the execution environment. Lambda looks for extensions in the `/opt/extensions/` directory, interprets each file as an executable bootstrap for launching the extension, and starts all extensions in parallel.

## Impact on performance and resources
<a name="using-extensions-reg"></a>

The size of your function's extensions counts towards the deployment package size limit. For a .zip file archive, the total unzipped size of the function and all extensions cannot exceed the unzipped deployment package size limit of 250 MB.

Extensions can impact the performance of your function because they share function resources such as CPU, memory, and storage. For example, if an extension performs compute-intensive operations, you may see your function's execution duration increase.

Each extension must complete its initialization before Lambda invokes the function. Therefore, an extension that consumes significant initialization time can increase the latency of the function invocation.

To measure the extra time that the extension takes after the function execution, you can use the `PostRuntimeExtensionsDuration` [function metric](monitoring-metrics.md). To measure the increase in memory used, you can use the `MaxMemoryUsed` metric. To understand the impact of a specific extension, you can run different versions of your functions side by side.

**Note**  
`MaxMemoryUsed` metric is one of the [Metrics collected by Lambda Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-metrics.html) and not a Lambda native metric.

## Permissions
<a name="using-extensions-permissions"></a>

Extensions have access to the same resources as functions. Because extensions are executed within the same environment as the function, permissions are shared between the function and the extension.

For a .zip file archive, you can create an CloudFormation template to simplify the task of attaching the same extension configuration—including AWS Identity and Access Management (IAM) permissions—to multiple functions.

# Configuring Lambda extensions
<a name="extensions-configuration"></a>

## Configuring extensions (.zip file archive)
<a name="using-extensions-config"></a>

You can add an extension to your function as a [Lambda layer](chapter-layers.md). Using layers enables you to share extensions across your organization or to the entire community of Lambda developers. You can add one or more extensions to a layer. You can register up to 10 extensions for a function.

You add the extension to your function using the same method as you would for any layer. For more information, see [Managing Lambda dependencies with layers](chapter-layers.md).

**Add an extension to your function (console)**

1. Open the [Functions page](https://console.aws.amazon.com/lambda/home#/functions) of the Lambda console.

1. Choose a function.

1. Choose the **Code** tab if it is not already selected.

1. Under **Layers**, choose **Edit**.

1. For **Choose a layer**, choose **Specify an ARN**.

1. For **Specify an ARN**, enter the Amazon Resource Name (ARN) of an extension layer.

1. Choose **Add**.

## Using extensions in container images
<a name="invocation-extensions-images"></a>

You can add extensions to your [container image](images-create.md). The ENTRYPOINT container image setting specifies the main process for the function. Configure the ENTRYPOINT setting in the Dockerfile, or as an override in the function configuration. 

You can run multiple processes within a container. Lambda manages the lifecycle of the main process and any additional processes. Lambda uses the [Extensions API](runtimes-extensions-api.md) to manage the extension lifecycle. 

### Example: Adding an external extension
<a name="extensions-images-ex1"></a>

An external extension runs in a separate process from the Lambda function. Lambda starts a process for each extension in the `/opt/extensions/` directory. Lambda uses the Extensions API to manage the extension lifecycle. After the function has run to completion, Lambda sends a `Shutdown` event to each external extension.

**Example of adding an external extension to a Python base image**  

```
FROM public.ecr.aws/lambda/python:3.11

# Copy and install the app
COPY /app /app
WORKDIR /app
RUN pip install -r requirements.txt

# Add an extension from the local directory into /opt/extensions
ADD my-extension.zip /opt/extensions
CMD python ./my-function.py
```

## Next steps
<a name="using-extensions-next"></a>

To learn more about extensions, we recommend the following resources:
+ For a basic working example, see [Building Extensions for AWS Lambda](https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/) on the AWS Compute Blog.
+ For information about extensions that AWS Lambda Partners provides, see [Introducing AWS Lambda Extensions](https://aws.amazon.com/blogs/compute/introducing-aws-lambda-extensions-in-preview/) on the AWS Compute Blog.
+ To view available example extensions and wrapper scripts, see [AWS Lambda Extensions](https://github.com/aws-samples/aws-lambda-extensions) on the AWS Samples GitHub repository.

# AWS Lambda extensions partners
<a name="extensions-api-partners"></a>

AWS Lambda has partnered with several third party entities to provide extensions to integrate with your Lambda functions. The following list details third party extensions that are ready for you to use at any time.
+ [https://docs.appdynamics.com/display/PRO20X/Use+the+AppDynamics+AWS+Lambda+Extension+to+Instrument+Serverless+APM+at+Runtime](https://docs.appdynamics.com/display/PRO20X/Use+the+AppDynamics+AWS+Lambda+Extension+to+Instrument+Serverless+APM+at+Runtime) – Provides automatic instrumentation of Node.js or Python Lambda functions, providing visibility and alerting on function performance.
+ [https://axiom.co/docs/apps/lambda](https://axiom.co/docs/apps/lambda) – Provides dashboards for monitoring Lambda function performance and aggregate system-level metrics.
+ [https://docs.datadoghq.com/serverless/datadog_lambda_library/extension/](https://docs.datadoghq.com/serverless/datadog_lambda_library/extension/) – Provides comprehensive, real-time visibility to your serverless applications through the use of metrics, traces, and logs.
+ [https://www.dynatrace.com/support/help/technology-support/cloud-platforms/amazon-web-services/integrations/deploy-oneagent-as-lambda-extension/](https://www.dynatrace.com/support/help/technology-support/cloud-platforms/amazon-web-services/integrations/deploy-oneagent-as-lambda-extension/) – Provides visibility into traces and metrics, and leverages AI for automated error detection and root cause analysis across the entire application stack.
+ [https://www.elastic.co/guide/en/apm/agent/nodejs/current/lambda.html](https://www.elastic.co/guide/en/apm/agent/nodejs/current/lambda.html) – Provides Application Performance Monitoring (APM) to identify and resolve root cause issues using correlated traces, metrics, and logs.
+ [https://docs.epsagon.com/docs/environment-monitoring/lambda/intro](https://docs.epsagon.com/docs/environment-monitoring/lambda/intro) – Listens to invocation events, stores traces, and sends them in parallel to Lambda function executions.
+ [https://docs.fastly.com/signalsciences/install-guides/paas/aws-lambda/](https://docs.fastly.com/signalsciences/install-guides/paas/aws-lambda/)– Protects your Lambda functions from suspicious activity, such as injection-style attacks, account takeover via credential stuffing, malicious bots, and API abuse.
+ [https://learn.hashicorp.com/tutorials/vault/aws-lambda](https://learn.hashicorp.com/tutorials/vault/aws-lambda) – Manages secrets and makes them available for developers to use within function code, without making functions Vault aware.
+ [https://docs.honeycomb.io/getting-data-in/integrations/aws/aws-lambda/](https://docs.honeycomb.io/getting-data-in/integrations/aws/aws-lambda/) – Observability tool for debugging your app stack.
+ [https://docs.lumigo.io/docs/lambda-extensions](https://docs.lumigo.io/docs/lambda-extensions) – Profiles Lambda function invocations and collects metrics for troubleshooting issues in serverless and microservice environments.
+ [https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/monitoring-aws-lambda-serverless-monitoring](https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/monitoring-aws-lambda-serverless-monitoring) – Runs alongside Lambda functions, automatically collecting, enhancing, and transporting telemetry to New Relic's unified observability platform.
+ [https://docs.sedai.io/get-started/platform/optimization/aws/lambda](https://docs.sedai.io/get-started/platform/optimization/aws/lambda) – An autonomous cloud management platform, powered by AI/ML, that delivers continuous optimization for cloud operations teams to maximize cloud cost savings, performance, and availability at scale.
+ [https://docs.sentry.io/platforms/javascript/guides/aws-lambda/](https://docs.sentry.io/platforms/javascript/guides/aws-lambda/) – Diagnose, fix, and optimize performance of Lambda functions.
+ [https://www.site24x7.com/help/aws/lambda-execution-logs.html](https://www.site24x7.com/help/aws/lambda-execution-logs.html) – Achieve real-time observability into your Lambda environments
+ [https://github.com/signalfx/splunk-otel-lambda](https://github.com/signalfx/splunk-otel-lambda) – Collects high-resolution, low-latency metrics for efficient and effective monitoring of Lambda functions.
+ [https://help.sumologic.com/03Send-Data/Collect-from-Other-Data-Sources/Collect_AWS_Lambda_Logs_using_an_Extension](https://help.sumologic.com/03Send-Data/Collect-from-Other-Data-Sources/Collect_AWS_Lambda_Logs_using_an_Extension) – Provides visibility into the health and performance of serverless applications.
+ [Salt Security](https://salt.security/press-releases/salt-security-becomes-the-first-and-only-api-security-vendor-to-join-aws-lambda-ready-program?) – Simplifies API posture governance and API security for Lambda functions through automated setup and support for diverse runtimes.

## AWS managed extensions
<a name="aws-managed-extensions"></a>

AWS provides its own managed extensions, including:
+ [AWS AppConfig](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions.html#appconfig-integration-lambda-extensions-enabling) – Use feature flags and dynamic data to update your Lambda functions. You can also use this extension to update other dynamic configuration, such as ops throttling and tuning. 
+ [Amazon CodeGuru Profiler](https://docs.aws.amazon.com/codeguru/latest/profiler-ug/python-lambda-layers.html) – Improves application performance and reduces cost by pinpointing an application's most expensive line of code and providing recommendations for improving code.
+ [CloudWatch Lambda Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights.html) – Monitor, troubleshoot, and optimize the performance of your Lambda functions through automated dashboards.
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – Enables functions to send trace data to AWS monitoring services such as AWS X-Ray, and to destinations that support OpenTelemetry such as Honeycomb and Lightstep.
+ [AWS Parameters and Secrets](with-secrets-manager.md) – Securely retrieve parameters from AWS Systems Manager Parameter Store and secrets from AWS Secrets Manager in Lambda functions.

For additional extensions samples and demo projects, see [AWS Lambda Extensions](https://github.com/aws-samples/aws-lambda-extensions).

# Using the Lambda Extensions API to create extensions
<a name="runtimes-extensions-api"></a>

Lambda function authors use extensions to integrate Lambda with their preferred tools for monitoring, observability, security, and governance. Function authors can use extensions from AWS, [AWS Partners](extensions-api-partners.md), and open-source projects. For more information on using extensions, see [Introducing AWS Lambda Extensions](https://aws.amazon.com/blogs/aws/getting-started-with-using-your-favorite-operational-tools-on-aws-lambda-extensions-are-now-generally-available/) on the AWS Compute Blog. This section describes how to use the Lambda Extensions API, the Lambda execution environment lifecycle, and the Lambda Extensions API reference. 

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/telemetry-api-concept-diagram.png)


As an extension author, you can use the Lambda Extensions API to integrate deeply into the Lambda [execution environment](lambda-runtime-environment.md). Your extension can register for function and execution environment lifecycle events. In response to these events, you can start new processes, run logic, and control and participate in all phases of the Lambda lifecycle: initialization, invocation, and shutdown. In addition, you can use the [Runtime Logs API](runtimes-logs-api.md) to receive a stream of logs.

An extension runs as an independent process in the execution environment and can continue to run after the function invocation is fully processed. Because extensions run as processes, you can write them in a different language than the function. We recommend that you implement extensions using a compiled language. In this case, the extension is a self-contained binary that is compatible with supported runtimes. All [Lambda runtimes](lambda-runtimes.md) support extensions. If you use a non-compiled language, ensure that you include a compatible runtime in the extension. 

Lambda also supports *internal extensions*. An internal extension runs as a separate thread in the runtime process. The runtime starts and stops the internal extension. An alternative way to integrate with the Lambda environment is to use language-specific [environment variables and wrapper scripts](runtimes-modify.md). You can use these to configure the runtime environment and modify the startup behavior of the runtime process.

You can add extensions to a function in two ways. For a function deployed as a [.zip file archive](configuration-function-zip.md), you deploy your extension as a [layer](chapter-layers.md). For a function defined as a container image, you add [the extensions](extensions-configuration.md#invocation-extensions-images) to your container image.

**Note**  
For example extensions and wrapper scripts, see [AWS Lambda Extensions](https://github.com/aws-samples/aws-lambda-extensions) on the AWS Samples GitHub repository.

**Topics**
+ [Lambda execution environment lifecycle](#runtimes-extensions-api-lifecycle)
+ [Extensions API reference](#runtimes-extensions-registration-api)

## Lambda execution environment lifecycle
<a name="runtimes-extensions-api-lifecycle"></a>

The lifecycle of the execution environment includes the following phases:
+ `Init`: In this phase, Lambda creates or unfreezes an execution environment with the configured resources, downloads the code for the function and all layers, initializes any extensions, initializes the runtime, and then runs the function’s initialization code (the code outside the main handler). The `Init` phase happens either during the first invocation, or in advance of function invocations if you have enabled [provisioned concurrency](provisioned-concurrency.md).

  The `Init` phase is split into three sub-phases: `Extension init`, `Runtime init`, and `Function init`. These sub-phases ensure that all extensions and the runtime complete their setup tasks before the function code runs.
+ `Invoke`: In this phase, Lambda invokes the function handler. After the function runs to completion, Lambda prepares to handle another function invocation.
+ `Shutdown`: This phase is triggered if the Lambda function does not receive any invocations for a period of time. In the `Shutdown` phase, Lambda shuts down the runtime, alerts the extensions to let them stop cleanly, and then removes the environment. Lambda sends a `Shutdown` event to each extension, which tells the extension that the environment is about to be shut down.

Each phase starts with an event from Lambda to the runtime and to all registered extensions. The runtime and each extension signal completion by sending a `Next` API request. Lambda freezes the execution environment when each process has completed and there are no pending events.

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/Overview-Full-Sequence.png)


 

**Topics**
+ [Init phase](#runtimes-extensions-api-reg)
+ [Invoke phase](#runtimes-lifecycle-extensions-invoke)
+ [Shutdown phase](#runtimes-lifecycle-extensions-shutdown)
+ [Permissions and configuration](#runtimes-extensions-registration-api-e)
+ [Failure handling](#runtimes-extensions-api-failure)
+ [Troubleshooting extensions](#runtimes-extensions-api-trbl)

### Init phase
<a name="runtimes-extensions-api-reg"></a>

During the `Extension init` phase, each extension needs to register with Lambda to receive events. Lambda uses the full file name of the extension to validate that the extension has completed the bootstrap sequence. Therefore, each `Register` API call must include the `Lambda-Extension-Name` header with the full file name of the extension.

You can register up to 10 extensions for a function. This limit is enforced through the `Register` API call.

After each extension registers, Lambda starts the `Runtime init` phase. The runtime process calls `functionInit` to start the `Function init` phase.

The `Init` phase completes after the runtime and each registered extension indicate completion by sending a `Next` API request.

**Note**  
Extensions can complete their initialization at any point in the `Init` phase.

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/Init-Phase.png)


### Invoke phase
<a name="runtimes-lifecycle-extensions-invoke"></a>

When a Lambda function is invoked in response to a `Next` API request, Lambda sends an `Invoke` event to the runtime and to each extension that is registered for the `Invoke` event.

**Note**  
**Lambda Managed Instances:** Extensions for Lambda Managed Instances functions cannot register for the `Invoke` event. Because Lambda Managed Instances supports concurrent invocations within a single execution environment, the `Invoke` event is not supported. Extensions can only register for the `Shutdown` event. If you need to track when invocations start and finish, use the `platform.report` platform event through the [Telemetry API](telemetry-api.md).

During the invocation, external extensions run in parallel with the function. They also continue running after the function has completed. This enables you to capture diagnostic information or to send logs, metrics, and traces to a location of your choice.

After receiving the function response from the runtime, Lambda returns the response to the client, even if extensions are still running.

The `Invoke` phase ends after the runtime and all extensions signal that they are done by sending a `Next` API request. 

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/Invoke-Phase.png)


**Event payload**: The event sent to the runtime (and the Lambda function) carries the entire request, headers (such as `RequestId`), and payload. The event sent to each extension contains metadata that describes the event content. This lifecycle event includes the type of the event, the time that the function times out (`deadlineMs`), the `requestId`, the invoked function's Amazon Resource Name (ARN), and tracing headers.

Extensions that want to access the function event body can use an in-runtime SDK that communicates with the extension. Function developers use the in-runtime SDK to send the payload to the extension when the function is invoked.

Here is an example payload:

```
{
    "eventType": "INVOKE",
    "deadlineMs": 676051,
    "requestId": "3da1f2dc-3222-475e-9205-e2e6c6318895",
    "invokedFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:ExtensionTest",
    "tracing": {
        "type": "X-Amzn-Trace-Id",
        "value": "Root=1-5f35ae12-0c0fec141ab77a00bc047aa2;Parent=2be948a625588e32;Sampled=1"
    }
 }
```

**Duration limit**: The function's timeout setting limits the duration of the entire `Invoke` phase. For example, if you set the function timeout as 360 seconds, the function and all extensions need to complete within 360 seconds. Note that there is no independent post-invoke phase. The duration is the total time it takes for your runtime and all your extensions' invocations to complete and is not calculated until the function and all extensions have finished running.

**Performance impact and extension overhead**: Extensions can impact function performance. As an extension author, you have control over the performance impact of your extension. For example, if your extension performs compute-intensive operations, the function's duration increases because the extension and the function code share the same CPU resources. In addition, if your extension performs extensive operations after the function invocation completes, the function duration increases because the `Invoke` phase continues until all extensions signal that they are completed.

**Note**  
Lambda allocates CPU power in proportion to the function's memory setting. You might see increased execution and initialization duration at lower memory settings because the function and extension processes are competing for the same CPU resources. To reduce the execution and initialization duration, try increasing the memory setting.

To help identify the performance impact introduced by extensions on the `Invoke` phase, Lambda outputs the `PostRuntimeExtensionsDuration` metric. This metric measures the cumulative time spent between the runtime `Next` API request and the last extension `Next` API request. To measure the increase in memory used, use the `MaxMemoryUsed` metric. For more information about function metrics, see [Using CloudWatch metrics with Lambda](monitoring-metrics.md).

Function developers can run different versions of their functions side by side to understand the impact of a specific extension. We recommend that extension authors publish expected resource consumption to make it easier for function developers to choose a suitable extension.

### Shutdown phase
<a name="runtimes-lifecycle-extensions-shutdown"></a>

When Lambda is about to shut down the runtime, it sends a `Shutdown` to each registered external extension. Extensions can use this time for final cleanup tasks. The `Shutdown` event is sent in response to a `Next` API request.

**Duration limit**: The maximum duration of the `Shutdown` phase depends on the configuration of registered extensions:
+ 0 ms – A function with no registered extensions
+ 500 ms – A function with a registered internal extension
+ 2,000 ms – A function with one or more registered external extensions

If the runtime or an extension does not respond to the `Shutdown` event within the limit, Lambda ends the process using a `SIGKILL` signal.

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/Shutdown-Phase.png)


**Event payload**: The `Shutdown` event contains the reason for the shutdown and the time remaining in milliseconds.

 The `shutdownReason` includes the following values:
+ SPINDOWN – Normal shutdown
+ TIMEOUT – Duration limit timed out
+ FAILURE – Error condition, such as an `out-of-memory` event

```
{ 
  "eventType": "SHUTDOWN", 
  "shutdownReason": "reason for shutdown", 
  "deadlineMs": "the time and date that the function times out in Unix time milliseconds" 
}
```

### Permissions and configuration
<a name="runtimes-extensions-registration-api-e"></a>

Extensions run in the same execution environment as the Lambda function. Extensions also share resources with the function, such as CPU, memory, and `/tmp` disk storage. In addition, extensions use the same AWS Identity and Access Management (IAM) role and security context as the function.

**File system and network access permissions**: Extensions run in the same file system and network name namespace as the function runtime. This means that extensions need to be compatible with the associated operating system. If an extension requires any additional outbound network traffic rules, you must apply these rules to the function configuration.

**Note**  
Because the function code directory is read-only, extensions cannot modify the function code.

**Environment variables**: Extensions can access the function's [environment variables](configuration-envvars.md), except for the following variables that are specific to the runtime process:
+ `AWS_EXECUTION_ENV`
+ `AWS_LAMBDA_LOG_GROUP_NAME`
+ `AWS_LAMBDA_LOG_STREAM_NAME`
+ `AWS_XRAY_CONTEXT_MISSING`
+ `AWS_XRAY_DAEMON_ADDRESS`
+ `LAMBDA_RUNTIME_DIR`
+ `LAMBDA_TASK_ROOT`
+ `_AWS_XRAY_DAEMON_ADDRESS`
+ `_AWS_XRAY_DAEMON_PORT`
+ `_HANDLER`

**Note**  
**Detecting Lambda Managed Instances:** Extensions can check the `AWS_LAMBDA_INITIALIZATION_TYPE` environment variable to determine if they are running on Lambda Managed Instances versus Lambda (default) functions. This is the recommended method for extensions to adapt their behavior based on the execution environment type.

### Failure handling
<a name="runtimes-extensions-api-failure"></a>

**Initialization failures**: If an extension fails, Lambda restarts the execution environment to enforce consistent behavior and to encourage fail fast for extensions. Also, for some customers, the extensions must meet mission-critical needs such as logging, security, governance, and telemetry collection.

**Invoke failures** (such as out of memory, function timeout): Because extensions share resources with the runtime, memory exhaustion affects them. When the runtime fails, all extensions and the runtime itself participate in the `Shutdown` phase. In addition, the runtime is restarted—either automatically as part of the current invocation, or via a deferred re-initialization mechanism.

If there is a failure (such as a function timeout or runtime error) during `Invoke`, the Lambda service performs a reset. The reset behaves like a `Shutdown` event. First, Lambda shuts down the runtime, then it sends a `Shutdown` event to each registered external extension. The event includes the reason for the shutdown. If this environment is used for a new invocation, the extension and runtime are re-initialized as part of the next invocation.

![\[Execution environment example: Init, Invoke, Invoke with Error, Invoke, Shutdown\]](http://docs.aws.amazon.com/lambda/latest/dg/images/Overview-Invoke-with-Error.png)


For a more detailed explanation of the previous diagram, see [Failures during the invoke phase](lambda-runtime-environment.md#runtimes-lifecycle-invoke-with-errors).

**Extension logs**: Lambda sends the log output of extensions to CloudWatch Logs. Lambda also generates an additional log event for each extension during `Init`. The log event records the name and registration preference (event, config) on success, or the failure reason on failure.

### Troubleshooting extensions
<a name="runtimes-extensions-api-trbl"></a>
+ If a `Register` request fails, make sure that the `Lambda-Extension-Name` header in the `Register` API call contains the full file name of the extension.
+ If the `Register` request fails for an internal extension, make sure that the request does not register for the `Shutdown` event.

## Extensions API reference
<a name="runtimes-extensions-registration-api"></a>

The OpenAPI specification for the extensions API version **2020-01-01** is available here: [extensions-api.zip](samples/extensions-api.zip)

You can retrieve the value of the API endpoint from the `AWS_LAMBDA_RUNTIME_API` environment variable. To send a `Register` request, use the prefix `2020-01-01/` before each API path. For example:

```
http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register 
```

**Topics**
+ [Register](#extensions-registration-api-a)
+ [Next](#extensions-api-next)
+ [Init error](#runtimes-extensions-init-error)
+ [Exit error](#runtimes-extensions-exit-error)

### Register
<a name="extensions-registration-api-a"></a>

During `Extension init`, all extensions need to register with Lambda to receive events. Lambda uses the full file name of the extension to validate that the extension has completed the bootstrap sequence. Therefore, each `Register` API call must include the `Lambda-Extension-Name` header with the full file name of the extension.

Internal extensions are started and stopped by the runtime process, so they are not permitted to register for the `Shutdown` event.

**Path** – `/extension/register`

**Method** – **POST**

**Request headers**
+ `Lambda-Extension-Name` – The full file name of the extension. Required: yes. Type: string.
+ `Lambda-Extension-Accept-Feature` – Use this to specify optional Extensions features during registration. Required: no. Type: comma separated string. Features available to specify using this setting:
  + `accountId` – If specified, the Extension registration response will contain the account ID associated with the Lambda function that you're registering the Extension for.

**Request body parameters**
+ `events` – Array of the events to register for. Required: no. Type: array of strings. Valid strings: `INVOKE`, `SHUTDOWN`.
**Note**  
**Lambda Managed Instances:** Extensions for Lambda Managed Instances functions can only register for the `SHUTDOWN` event. Attempting to register for the `INVOKE` event will result in an error. This is because Lambda Managed Instances supports concurrent invocations within a single execution environment.

**Response headers**
+ `Lambda-Extension-Identifier` – Generated unique agent identifier (UUID string) that is required for all subsequent requests.

**Response codes**
+ 200 – Response body contains the function name, function version, and handler name.
+ 400 – Bad Request
+ 403 – Forbidden
+ 500 – Container error. Non-recoverable state. Extension should exit promptly.

**Example request body**  

```
{
    'events': [ 'INVOKE', 'SHUTDOWN']
}
```

**Example response body**  

```
{
    "functionName": "helloWorld",
    "functionVersion": "$LATEST",
    "handler": "lambda_function.lambda_handler"
}
```

**Example response body with optional accountId feature**  

```
{
    "functionName": "helloWorld",
    "functionVersion": "$LATEST",
    "handler": "lambda_function.lambda_handler",
    "accountId": "123456789012"
}
```

### Next
<a name="extensions-api-next"></a>

Extensions send a `Next` API request to receive the next event, which can be an `Invoke` event or a `Shutdown` event. The response body contains the payload, which is a JSON document that contains event data.

The extension sends a `Next` API request to signal that it is ready to receive new events. This is a blocking call.

Do not set a timeout on the GET call, as the extension can be suspended for a period of time until there is an event to return.

**Path** – `/extension/event/next`

**Method** – **GET**

**Request headers**
+ `Lambda-Extension-Identifier` – Unique identifier for extension (UUID string). Required: yes. Type: UUID string.

**Response headers**
+ `Lambda-Extension-Event-Identifier` – Unique identifier for the event (UUID string).

**Response codes**
+ 200 – Response contains information about the next event (`EventInvoke` or `EventShutdown`).
+ 403 – Forbidden
+ 500 – Container error. Non-recoverable state. Extension should exit promptly.

### Init error
<a name="runtimes-extensions-init-error"></a>

The extension uses this method to report an initialization error to Lambda. Call it when the extension fails to initialize after it has registered. After Lambda receives the error, no further API calls succeed. The extension should exit after it receives the response from Lambda.

**Path** – `/extension/init/error`

**Method** – **POST**

**Request headers**
+ `Lambda-Extension-Identifier` – Unique identifier for extension. Required: yes. Type: UUID string.
+ `Lambda-Extension-Function-Error-Type` – Error type that the extension encountered. Required: yes. This header consists of a string value. Lambda accepts any string, but we recommend a format of <category.reason>. For example:
  + Extension.NoSuchHandler
  + Extension.APIKeyNotFound
  + Extension.ConfigInvalid
  + Extension.UnknownReason

**Request body parameters**
+ `ErrorRequest` – Information about the error. Required: no. 

This field is a JSON object with the following structure:

```
{
      errorMessage: string (text description of the error),
      errorType: string,
      stackTrace: array of strings
}
```

Note that Lambda accepts any value for `errorType`.

The following example shows a Lambda function error message in which the function could not parse the event data provided in the invocation.

**Example Function error**  

```
{
      "errorMessage" : "Error parsing event data.",
      "errorType" : "InvalidEventDataException",
      "stackTrace": [ ]
}
```

**Response codes**
+ 202 – Accepted
+ 400 – Bad Request
+ 403 – Forbidden
+ 500 – Container error. Non-recoverable state. Extension should exit promptly.

### Exit error
<a name="runtimes-extensions-exit-error"></a>

The extension uses this method to report an error to Lambda before exiting. Call it when you encounter an unexpected failure. After Lambda receives the error, no further API calls succeed. The extension should exit after it receives the response from Lambda.

**Path** – `/extension/exit/error`

**Method** – **POST**

**Request headers**
+ `Lambda-Extension-Identifier` – Unique identifier for extension. Required: yes. Type: UUID string.
+ `Lambda-Extension-Function-Error-Type` – Error type that the extension encountered. Required: yes. This header consists of a string value. Lambda accepts any string, but we recommend a format of <category.reason>. For example:
  + Extension.NoSuchHandler
  + Extension.APIKeyNotFound
  + Extension.ConfigInvalid
  + Extension.UnknownReason

**Request body parameters**
+ `ErrorRequest` – Information about the error. Required: no.

This field is a JSON object with the following structure:

```
{
      errorMessage: string (text description of the error),
      errorType: string,
      stackTrace: array of strings
}
```

Note that Lambda accepts any value for `errorType`.

The following example shows a Lambda function error message in which the function could not parse the event data provided in the invocation.

**Example Function error**  

```
{
      "errorMessage" : "Error parsing event data.",
      "errorType" : "InvalidEventDataException",
      "stackTrace": [ ]
}
```

**Response codes**
+ 202 – Accepted
+ 400 – Bad Request
+ 403 – Forbidden
+ 500 – Container error. Non-recoverable state. Extension should exit promptly.

 

# Accessing real-time telemetry data for extensions using the Telemetry API
<a name="telemetry-api"></a>

The Telemetry API enables your extensions to receive telemetry data directly from Lambda. During function initialization and invocation, Lambda automatically captures telemetry, including logs, platform metrics, and platform traces. The Telemetry API enables extensions to access this telemetry data directly from Lambda in near real time.

Within the Lambda execution environment, you can subscribe your Lambda extensions to telemetry streams. After subscribing, Lambda automatically sends all telemetry data to your extensions. You then have the flexibility to process, filter, and dispatch the data to your preferred destination, such as an Amazon Simple Storage Service (Amazon S3) bucket or a third-party observability tools provider.

The following diagram shows how the Extensions API and Telemetry API link extensions to Lambda from within the execution environment. Additionally, the Runtime API connects your runtime and function to Lambda.

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/telemetry-api-concept-diagram.png)


**Important**  
The Lambda Telemetry API supersedes the Lambda Logs API. **While the Logs API remains fully functional, we recommend using only the Telemetry API going forward.** You can subscribe your extension to a telemetry stream using either the Telemetry API or the Logs API. After subscribing using one of these APIs, any attempt to subscribe using the other API returns an error.

**Lambda Managed Instances schema version requirement**  
Lambda Managed Instances support only the `2025-01-29` schema version of the Telemetry API. When subscribing to telemetry streams for Managed Instance functions, you **must** use `"schemaVersion": "2025-01-29"` in your subscription request. Using previous schema versions will result in events being rejected by Lambda.  
The `2025-01-29` schema version is backward compatible and can be used with both Lambda Managed Instances and Lambda (default) functions. We recommend using this version for all new extensions to ensure compatibility across both deployment models.

Extensions can use the Telemetry API to subscribe to three different telemetry streams:
+ **Platform telemetry** – Logs, metrics, and traces, which describe events and errors related to the execution environment runtime lifecycle, extension lifecycle, and function invocations.
+ **Function logs** – Custom logs that the Lambda function code generates.
+ **Extension logs** – Custom logs that the Lambda extension code generates.

**Note**  
Lambda sends logs and metrics to CloudWatch, and traces to X-Ray (if you've activated tracing), even if an extension subscribes to telemetry streams.

**Topics**
+ [Creating extensions using the Telemetry API](#telemetry-api-creating-extensions)
+ [Registering your extension](#telemetry-api-registration)
+ [Creating a telemetry listener](#telemetry-api-listener)
+ [Specifying a destination protocol](#telemetry-api-destination)
+ [Configuring memory usage and buffering](#telemetry-api-buffering)
+ [Sending a subscription request to the Telemetry API](#telemetry-api-subscription)
+ [Inbound Telemetry API messages](#telemetry-api-messages)
+ [Lambda Telemetry API reference](telemetry-api-reference.md)
+ [Lambda Telemetry API `Event` schema reference](telemetry-schema-reference.md)
+ [Converting Lambda Telemetry API `Event` objects to OpenTelemetry Spans](telemetry-otel-spans.md)
+ [Using the Lambda Logs API](runtimes-logs-api.md)

## Creating extensions using the Telemetry API
<a name="telemetry-api-creating-extensions"></a>

Lambda extensions run as independent processes in the execution environment. Extensions can continue to run after function invocation completes. Because extensions are separate processes, you can write them in a language different from the function code. We recommend writing extensions using a compiled language such as Golang or Rust. This way, the extension is a self-contained binary that can be compatible with any supported runtime.

The following diagram illustrates a four-step process to create an extension that receives and processes telemetry data using the Telemetry API.

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/telemetry-api-creation-steps.png)


Here is each step in more detail:

1. Register your extension using the [Using the Lambda Extensions API to create extensions](runtimes-extensions-api.md). This provides you with a `Lambda-Extension-Identifier`, which you'll need in the following steps. For more information about how to register your extension, see [Registering your extension](#telemetry-api-registration).

1. Create a telemetry listener. This can be a basic HTTP or TCP server. Lambda uses the URI of the telemetry listener to send telemetry data to your extension. For more information, see [Creating a telemetry listener](#telemetry-api-listener).

1. Using the Subscribe API in the Telemetry API, subscribe your extension to the desired telemetry streams. You'll need the URI of your telemetry listener for this step. For more information, see [Sending a subscription request to the Telemetry API](#telemetry-api-subscription).

1. Get telemetry data from Lambda via the telemetry listener. You can do any custom processing of this data, such as dispatching the data to Amazon S3 or to an external observability service.

**Note**  
A Lambda function's execution environment can start and stop multiple times as part of its [lifecycle](runtimes-extensions-api.md#runtimes-extensions-api-lifecycle). In general, your extension code runs during function invocations, and also up to 2 seconds during the shutdown phase. We recommend batching the telemetry as it arrives to your listener. Then, use the `Invoke` and `Shutdown` lifecycle events to send each batch to their desired destinations.

## Registering your extension
<a name="telemetry-api-registration"></a>

Before you can subscribe to telemetry data, you must register your Lambda extension. Registration occurs during the [extension initialization phase](runtimes-extensions-api.md#runtimes-extensions-api-reg). The following example shows an HTTP request to register an extension.

```
POST http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register
 Lambda-Extension-Name: lambda_extension_name
{
    'events': [ 'INVOKE', 'SHUTDOWN']
}
```

If the request succeeds, the subscriber receives an HTTP 200 success response. The response header contains the `Lambda-Extension-Identifier`. The response body contains other properties of the function.

```
HTTP/1.1 200 OK
Lambda-Extension-Identifier: a1b2c3d4-5678-90ab-cdef-EXAMPLE11111
{
    "functionName": "lambda_function",
    "functionVersion": "$LATEST",
    "handler": "lambda_handler",
    "accountId": "123456789012"
}
```

For more information, see the [Extensions API reference](runtimes-extensions-api.md#runtimes-extensions-registration-api).

## Creating a telemetry listener
<a name="telemetry-api-listener"></a>

Your Lambda extension must have a listener that handles incoming requests from the Telemetry API. The following code shows an example telemetry listener implementation in Golang:

```
// Starts the server in a goroutine where the log events will be sent
func (s *TelemetryApiListener) Start() (string, error) {
	address := listenOnAddress()
	l.Info("[listener:Start] Starting on address", address)
	s.httpServer = &http.Server{Addr: address}
	http.HandleFunc("/", s.http_handler)
	go func() {
		err := s.httpServer.ListenAndServe()
		if err != http.ErrServerClosed {
			l.Error("[listener:goroutine] Unexpected stop on Http Server:", err)
			s.Shutdown()
		} else {
			l.Info("[listener:goroutine] Http Server closed:", err)
		}
	}()
	return fmt.Sprintf("http://%s/", address), nil
}

// http_handler handles the requests coming from the Telemetry API.
// Everytime Telemetry API sends log events, this function will read them from the response body
// and put into a synchronous queue to be dispatched later.
// Logging or printing besides the error cases below is not recommended if you have subscribed to
// receive extension logs. Otherwise, logging here will cause Telemetry API to send new logs for
// the printed lines which may create an infinite loop.
func (s *TelemetryApiListener) http_handler(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		l.Error("[listener:http_handler] Error reading body:", err)
		return
	}

	// Parse and put the log messages into the queue
	var slice []interface{}
	_ = json.Unmarshal(body, &slice)

	for _, el := range slice {
		s.LogEventsQueue.Put(el)
	}

	l.Info("[listener:http_handler] logEvents received:", len(slice), " LogEventsQueue length:", s.LogEventsQueue.Len())
	slice = nil
}
```

## Specifying a destination protocol
<a name="telemetry-api-destination"></a>

When you subscribe to receive telemetry using the Telemetry API, you can specify a destination protocol in addition to the destination URI:

```
{
    "destination": {
        "protocol": "HTTP",
        "URI": "http://sandbox.localdomain:8080"
    }
}
```

Lambda accepts two protocols for receiving telemetry:
+ **HTTP (recommended)** – Lambda delivers telemetry to a local HTTP endpoint (`http://sandbox.localdomain:${PORT}/${PATH}`) as an array of records in JSON format. The `$PATH` parameter is optional. Lambda supports only HTTP, not HTTPS. Lambda delivers telemetry through POST requests.
+ **TCP** – Lambda delivers telemetry to a TCP port in [Newline delimited JSON (NDJSON) format](https://github.com/ndjson/ndjson-spec).

**Note**  
We strongly recommend using HTTP rather than TCP. With TCP, the Lambda platform cannot acknowledge when it delivers telemetry to the application layer. Therefore, if your extension crashes, you might lose telemetry. HTTP does not have this limitation.

Before subscribing to receive telemetry, establish the local HTTP listener or TCP port. During setup, note the following:
+ Lambda sends telemetry only to destinations that are inside the execution environment.
+ Lambda retries to send telemetry (with backoff) in the absence of a listener, or if the POST request encounters an error. If the telemetry listener crashes, it resumes receiving telemetry after Lambda restarts the execution environment.
+ Lambda reserves port 9001. There are no other port number restrictions or recommendations.

## Configuring memory usage and buffering
<a name="telemetry-api-buffering"></a>

Memory usage in an execution environment grows linearly with the number of subscribers. Subscriptions consume memory resources because each one opens a new memory buffer to store telemetry data. Buffer memory usage contributes to the overall memory consumption in the execution environment.

When subscribing to receive telemetry through the Telemetry API, you have the option to buffer telemetry data and deliver it to subscribers in batches. To optimize memory usage, you can specify a buffering configuration:

```
{
    "buffering": {
        "maxBytes": 256*1024,
        "maxItems": 1000,
        "timeoutMs": 100
    }
}
```


| Parameter | Description | Defaults and limits | 
| --- | --- | --- | 
|  `maxBytes`  |  The maximum volume of telemetry (in bytes) to buffer in memory.  |  Default: 262,144 Minimum: 262,144 Maximum: 1,048,576  | 
|  `maxItems`  |  The maximum number of events to buffer in memory.  |  Default: 10,000 Minimum: 1,000 Maximum: 10,000  | 
|  `timeoutMs`  |  The maximum time (in milliseconds) to buffer a batch.  |  Default: 1,000 Minimum: 25 Maximum: 30,000  | 

When setting up buffering, keep these points in mind:
+ If any of the input streams are closed, Lambda flushes the logs. For example, this can occur if the runtime crashes.
+ Each subscriber can customize their buffering configuration in their subscription request.
+ When determining the buffer size for reading the data, anticipate receiving payloads as large as `2 * maxBytes + metadataBytes`, where `maxBytes` is a component of your buffering setup. To gauge the amount of `metadataBytes` to consider, review the following metadata. Lambda appends metadata similar to this to each record:

  ```
  {
     "time": "2022-08-20T12:31:32.123Z",
     "type": "function",
     "record": "Hello World"
  }
  ```
+ If the subscriber cannot process incoming telemetry fast enough, or if your function code generates very high log volume, Lambda might drop records to keep memory utilization bounded. When this occurs, Lambda sends a `platform.logsDropped` event.

## Sending a subscription request to the Telemetry API
<a name="telemetry-api-subscription"></a>

Lambda extensions can subscribe to receive telemetry data by sending a subscription request to the Telemetry API. The subscription request should contain information about the types of events that you want the extension to subscribe to. In addition, the request can contain [delivery destination information](#telemetry-api-destination) and a [buffering configuration](#telemetry-api-buffering).

Before sending a subscription request, you must have an extension ID (`Lambda-Extension-Identifier`). When you [register your extension with the Extensions API](#telemetry-api-registration), you obtain an extension ID from the API response.

Subscription occurs during the [extension initialization phase](runtimes-extensions-api.md#runtimes-extensions-api-reg). The following example shows an HTTP request to subscribe to all three telemetry streams: platform telemetry, function logs, and extension logs.

```
PUT http://${AWS_LAMBDA_RUNTIME_API}/2022-07-01/telemetry HTTP/1.1
{
   "schemaVersion": "2025-01-29",
   "types": [
        "platform",
        "function",
        "extension"
   ],
   "buffering": {
        "maxItems": 1000,
        "maxBytes": 256*1024,
        "timeoutMs": 100
   },
   "destination": {
        "protocol": "HTTP",
        "URI": "http://sandbox.localdomain:8080"
   }
}
```

If the request succeeds, then the subscriber receives an HTTP 200 success response.

```
HTTP/1.1 200 OK
"OK"
```

## Inbound Telemetry API messages
<a name="telemetry-api-messages"></a>

After subscribing using the Telemetry API, an extension automatically starts to receive telemetry from Lambda via POST requests. Each POST request body contains an array of `Event` objects. Each `Event` has the following schema:

```
{
   time: String,
   type: String,
   record: Object
}
```
+ The `time` property defines when the Lambda platform generated the event. This is different from when the event actually occurred. The string value of `time` is a timestamp in ISO 8601 format.
+ The `type` property defines the event type. The following table describes all possible values.
+ The `record` property defines a JSON object that contains the telemetry data. The schema of this JSON object depends on the `type`.

**Event ordering with concurrent invocations**  
For [Lambda Managed Instances](lambda-managed-instances.md), multiple function invocations can execute concurrently within the same execution environment. In this case, the order of `platform.start` and `platform.report` events is not guaranteed between different concurrent invocations. Extensions must handle events from multiple invocations running in parallel and should not assume sequential ordering.  
To properly attribute events to specific invocations, extensions should use the `requestId` field present in these platform events. Each invocation has a unique request ID that remains consistent across all events for that invocation, allowing extensions to correlate events correctly even when they arrive out of order.

The following table summarizes all types of `Event` objects, and links to the [Telemetry API `Event` schema reference](telemetry-schema-reference.md) for each event type.


| Category | Event type | Description | Event record schema | 
| --- | --- | --- | --- | 
|  Platform event  |  `platform.initStart`  |  Function initialization started.  |  [`platform.initStart`](telemetry-schema-reference.md#platform-initStart) schema  | 
|  Platform event  |  `platform.initRuntimeDone`  |  Function initialization completed.  |  [`platform.initRuntimeDone`](telemetry-schema-reference.md#platform-initRuntimeDone) schema  | 
|  Platform event  |  `platform.initReport`  |  A report of function initialization.  |  [`platform.initReport`](telemetry-schema-reference.md#platform-initReport) schema  | 
|  Platform event  |  `platform.start`  |  Function invocation started.  |  [`platform.start`](telemetry-schema-reference.md#platform-start) schema  | 
|  Platform event  |  `platform.runtimeDone`  |  The runtime finished processing an event with either success or failure.  |  [`platform.runtimeDone`](telemetry-schema-reference.md#platform-runtimeDone) schema  | 
|  Platform event  |  `platform.report`  |  A report of function invocation.  |  [`platform.report`](telemetry-schema-reference.md#platform-report) schema  | 
|  Platform event  |  `platform.restoreStart`  |  Runtime restore started.  |  [`platform.restoreStart`](telemetry-schema-reference.md#platform-restoreStart) schema  | 
|  Platform event  |  `platform.restoreRuntimeDone`  |  Runtime restore completed.  |  [`platform.restoreRuntimeDone`](telemetry-schema-reference.md#platform-restoreRuntimeDone) schema  | 
|  Platform event  |  `platform.restoreReport`  |  Report of runtime restore.  |  [`platform.restoreReport`](telemetry-schema-reference.md#platform-restoreReport) schema  | 
|  Platform event  |  `platform.telemetrySubscription`  |  The extension subscribed to the Telemetry API.  |  [`platform.telemetrySubscription`](telemetry-schema-reference.md#platform-telemetrySubscription) schema  | 
|  Platform event  |  `platform.logsDropped`  |  Lambda dropped log entries.  |  [`platform.logsDropped`](telemetry-schema-reference.md#platform-logsDropped) schema  | 
|  Function logs  |  `function`  |  A log line from function code.  |  [`function`](telemetry-schema-reference.md#telemetry-api-function) schema  | 
|  Extension logs  |  `extension`  |  A log line from extension code.  |  [`extension`](telemetry-schema-reference.md#telemetry-api-extension) schema  | 

# Lambda Telemetry API reference
<a name="telemetry-api-reference"></a>

Use the Lambda Telemetry API endpoint to subscribe extensions to telemetry streams. You can retrieve the Telemetry API endpoint from the `AWS_LAMBDA_RUNTIME_API` environment variable. To send an API request, append the API version (`2022-07-01/`) and `telemetry/`. For example:

```
http://${AWS_LAMBDA_RUNTIME_API}/2022-07-01/telemetry/
```

For the OpenAPI Specification (OAS) definition of the subscription responses version `2025-01-29`, see the following:
+ **HTTP** – [telemetry-api-http-schema.zip](samples/events_http_schema_v2025_01_29.zip)
+ **TCP** – [telemetry-api-tcp-schema.zip](samples/events_tcp_schema_v2025_01_29.zip)

**Topics**
+ [Subscribe](#telemetry-subscribe-api)

## Subscribe
<a name="telemetry-subscribe-api"></a>

To subscribe to a telemetry stream, a Lambda extension can send a Subscribe API request.
+ **Path** – `/telemetry`
+ **Method** – `PUT`
+ **Headers**
  + `Content-Type`: `application/json`
+ **Request body parameters**
  + **schemaVersion**
    + Required: Yes
    + Type: String
    + Valid values: `"2025-01-29"`, `"2022-12-13"`, or `"2022-07-01"`
    + **Note:** Lambda Managed Instances require `"2025-01-29"`. This version is backward compatible with Lambda (default) functions.
  + **destination** – The configuration settings that define the telemetry event destination and the protocol for event delivery.
    + Required: Yes
    + Type: Object

      ```
      {
          "protocol": "HTTP",
          "URI": "http://sandbox.localdomain:8080"
      }
      ```
    + **protocol** – The protocol that Lambda uses to send telemetry data.
      + Required: Yes
      + Type: String
      + Valid values: `"HTTP"`\$1`"TCP"`
    + **URI** – The URI to send telemetry data to.
      + Required: Yes
      + Type: String
    + For more information, see [Specifying a destination protocol](telemetry-api.md#telemetry-api-destination).
  + **types** – The types of telemetry that you want the extension to subscribe to.
    + Required: Yes
    + Type: Array of strings
    + Valid values: `"platform"`\$1`"function"`\$1`"extension"`
  + **buffering** – The configuration settings for event buffering.
    + Required: No
    + Type: Object

      ```
      {
         "buffering": {
              "maxItems": 1000,
              "maxBytes": 256*1024,
              "timeoutMs": 100
         }
      }
      ```
    + **maxItems** – The maximum number of events to buffer in memory.
      + Required: No
      + Type: Integer
      + Default: 1,000
      + Minimum: 1,000
      + Maximum: 10,000
    + **maxBytes** – The maximum volume of telemetry (in bytes) to buffer in memory.
      + Required: No
      + Type: Integer
      + Default: 262,144
      + Minimum: 262,144
      + Maximum: 1,048,576
    + **timeoutMs** – The maximum time (in milliseconds) to buffer a batch.
      + Required: No
      + Type: Integer
      + Default: 1,000
      + Minimum: 25
      + Maximum: 30,000
    + For more information, see [Configuring memory usage and buffering](telemetry-api.md#telemetry-api-buffering).

### Example Subscribe API request
<a name="telemetry-subscribe-api-example"></a>

```
PUT http://${AWS_LAMBDA_RUNTIME_API}/2022-07-01/telemetry HTTP/1.1
{
   "schemaVersion": "2025-01-29",
   "types": [
        "platform",
        "function",
        "extension"
   ],
   "buffering": {
        "maxItems": 1000,
        "maxBytes": 256*1024,
        "timeoutMs": 100
   },
   "destination": {
        "protocol": "HTTP",
        "URI": "http://sandbox.localdomain:8080"
   }
}
```

If the Subscribe request succeeds, the extension receives an HTTP 200 success response:

```
HTTP/1.1 200 OK
"OK"
```

If the Subscribe request fails, the extension receives an error response. For example:

```
HTTP/1.1 400 OK
{
    "errorType": "ValidationError",
    "errorMessage": "URI port is not provided; types should not be empty"
}
```

Here are some additional response codes that the extension can receive:
+ 200 – Request completed successfully
+ 202 – Request accepted. Subscription request response in local testing environment
+ 400 – Bad request
+ 500 – Service error

# Lambda Telemetry API `Event` schema reference
<a name="telemetry-schema-reference"></a>

Use the Lambda Telemetry API endpoint to subscribe extensions to telemetry streams. You can retrieve the Telemetry API endpoint from the `AWS_LAMBDA_RUNTIME_API` environment variable. To send an API request, append the API version (`2022-07-01/`) and `telemetry/`. For example:

```
http://${AWS_LAMBDA_RUNTIME_API}/2022-07-01/telemetry/
```

For the OpenAPI Specification (OAS) definition of the subscription responses version `2025-01-29`, see the following:
+ **HTTP** – [telemetry-api-http-schema.zip](samples/events_http_schema_v2025_01_29.zip)
+ **TCP** – [telemetry-api-tcp-schema.zip](samples/events_tcp_schema_v2025_01_29.zip)

The following table is a summary of all the types of `Event` objects that the Telemetry API supports.


| Category | Event type | Description | Event record schema | 
| --- | --- | --- | --- | 
|  Platform event  |  `platform.initStart`  |  Function initialization started.  |  [`platform.initStart`](#platform-initStart) schema  | 
|  Platform event  |  `platform.initRuntimeDone`  |  Function initialization completed.  |  [`platform.initRuntimeDone`](#platform-initRuntimeDone) schema  | 
|  Platform event  |  `platform.initReport`  |  A report of function initialization.  |  [`platform.initReport`](#platform-initReport) schema  | 
|  Platform event  |  `platform.start`  |  Function invocation started.  |  [`platform.start`](#platform-start) schema  | 
|  Platform event  |  `platform.runtimeDone`  |  The runtime finished processing an event with either success or failure.  |  [`platform.runtimeDone`](#platform-runtimeDone) schema  | 
|  Platform event  |  `platform.report`  |  A report of function invocation.  |  [`platform.report`](#platform-report) schema  | 
|  Platform event  |  `platform.restoreStart`  |  Runtime restore started.  |  [`platform.restoreStart`](#platform-restoreStart) schema  | 
|  Platform event  |  `platform.restoreRuntimeDone`  |  Runtime restore completed.  |  [`platform.restoreRuntimeDone`](#platform-restoreRuntimeDone) schema  | 
|  Platform event  |  `platform.restoreReport`  |  Report of runtime restore.  |  [`platform.restoreReport`](#platform-restoreReport) schema  | 
|  Platform event  |  `platform.telemetrySubscription`  |  The extension subscribed to the Telemetry API.  |  [`platform.telemetrySubscription`](#platform-telemetrySubscription) schema  | 
|  Platform event  |  `platform.logsDropped`  |  Lambda dropped log entries.  |  [`platform.logsDropped`](#platform-logsDropped) schema  | 
|  Function logs  |  `function`  |  A log line from function code.  |  [`function`](#telemetry-api-function) schema  | 
|  Extension logs  |  `extension`  |  A log line from extension code.  |  [`extension`](#telemetry-api-extension) schema  | 

**Contents**
+ [Telemetry API `Event` object types](#telemetry-api-events)
  + [`platform.initStart`](#platform-initStart)
  + [`platform.initRuntimeDone`](#platform-initRuntimeDone)
  + [`platform.initReport`](#platform-initReport)
  + [`platform.start`](#platform-start)
  + [`platform.runtimeDone`](#platform-runtimeDone)
  + [`platform.report`](#platform-report)
  + [`platform.restoreStart`](#platform-restoreStart)
  + [`platform.restoreRuntimeDone`](#platform-restoreRuntimeDone)
  + [`platform.restoreReport`](#platform-restoreReport)
  + [`platform.extension`](#platform-extension)
  + [`platform.telemetrySubscription`](#platform-telemetrySubscription)
  + [`platform.logsDropped`](#platform-logsDropped)
  + [`function`](#telemetry-api-function)
  + [`extension`](#telemetry-api-extension)
+ [Shared object types](#telemetry-api-objects)
  + [`InitPhase`](#InitPhase)
  + [`InitReportMetrics`](#InitReportMetrics)
  + [`InitType`](#InitType)
  + [`ReportMetrics`](#ReportMetrics)
  + [`RestoreReportMetrics`](#RestoreReportMetrics)
  + [`RuntimeDoneMetrics`](#RuntimeDoneMetrics)
  + [`Span`](#Span)
  + [`Status`](#Status)
  + [`TraceContext`](#TraceContext)
  + [`TracingType`](#TracingType)

## Telemetry API `Event` object types
<a name="telemetry-api-events"></a>

This section details the types of `Event` objects that the Lambda Telemetry API supports. In the event descriptions, a question mark (`?`) indicates that the attribute may not be present in the object.

### `platform.initStart`
<a name="platform-initStart"></a>

A `platform.initStart` event indicates that the function initialization phase has started. A `platform.initStart` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.initStart
- record: PlatformInitStart
```

The `PlatformInitStart` object has the following attributes:
+ **functionName** – `String`
+ **functionVersion** – `String`
+ **initializationType** – ``InitType`` object
+ **instanceId?** – `String`
+ **instanceMaxMemory?** – `Integer`
+ **phase** – ``InitPhase`` object
+ **runtimeVersion?** – `String`
+ **runtimeVersionArn?** – `String`

The following is an example `Event` of type `platform.initStart`:

```
{
    "time": "2022-10-12T00:00:15.064Z",
    "type": "platform.initStart",
    "record": {
        "initializationType": "on-demand",
        "phase": "init",
        "runtimeVersion": "nodejs-14.v3",
        "runtimeVersionArn": "arn",
        "functionName": "myFunction",
        "functionVersion": "$LATEST",
        "instanceId": "82561ce0-53dd-47d1-90e0-c8f5e063e62e",
        "instanceMaxMemory": 256
    }
}
```

### `platform.initRuntimeDone`
<a name="platform-initRuntimeDone"></a>

A `platform.initRuntimeDone` event indicates that the function initialization phase has completed. A `platform.initRuntimeDone` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.initRuntimeDone
- record: PlatformInitRuntimeDone
```

The `PlatformInitRuntimeDone` object has the following attributes:
+ **initializationType** – ``InitType`` object
+ **phase** – ``InitPhase`` object
+ **status** – ``Status`` object
+ **spans?** – List of ``Span`` objects

The following is an example `Event` of type `platform.initRuntimeDone`:

```
{
    "time": "2022-10-12T00:01:15.000Z",
    "type": "platform.initRuntimeDone",
    "record": {
        "initializationType": "on-demand"
        "status": "success",
        "spans": [
            {
                "name": "someTimeSpan",
                "start": "2022-06-02T12:02:33.913Z",
                "durationMs": 70.5
            }
        ]
    }
}
```

### `platform.initReport`
<a name="platform-initReport"></a>

A `platform.initReport` event contains an overall report of the function initialization phase. A `platform.initReport` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.initReport
- record: PlatformInitReport
```

The `PlatformInitReport` object has the following attributes:
+ **errorType?** – string
+ **initializationType** – ``InitType`` object
+ **phase** – ``InitPhase`` object
+ **metrics** – ``InitReportMetrics`` object
+ **spans?** – List of ``Span`` objects
+ **status** – ``Status`` object

The following is an example `Event` of type `platform.initReport`:

```
{
    "time": "2022-10-12T00:01:15.000Z",
    "type": "platform.initReport",
    "record": {
        "initializationType": "on-demand",
        "status": "success",
        "phase": "init",
        "metrics": {
            "durationMs": 125.33
        },
        "spans": [
            {
                "name": "someTimeSpan",
                "start": "2022-06-02T12:02:33.913Z",
                "durationMs": 90.1
            }
        ]
    }
}
```

### `platform.start`
<a name="platform-start"></a>

A `platform.start` event indicates that the function invocation phase has started. A `platform.start` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.start
- record: PlatformStart
```

The `PlatformStart` object has the following attributes:
+ **requestId** – `String`
+ **version?** – `String`
+ **tracing?** – ``TraceContext``

The following is an example `Event` of type `platform.start`:

```
{
    "time": "2022-10-12T00:00:15.064Z",
    "type": "platform.start",
    "record": {
        "requestId": "6d68ca91-49c9-448d-89b8-7ca3e6dc66aa",
        "version": "$LATEST",
        "tracing": {
            "spanId": "54565fb41ac79632",
            "type": "X-Amzn-Trace-Id",
            "value": "Root=1-62e900b2-710d76f009d6e7785905449a;Parent=0efbd19962d95b05;Sampled=1"
        }
    }
}
```

### `platform.runtimeDone`
<a name="platform-runtimeDone"></a>

A `platform.runtimeDone` event indicates that the function invocation phase has completed. A `platform.runtimeDone` `Event` object has the following shape:

**Lambda Managed Instances**  
The `platform.runtimeDone` event is not supported for Lambda Managed Instances. Extensions running on Managed Instances will not receive this event because extensions cannot subscribe to the `INVOKE` event on Managed Instances. Due to the concurrent execution model where multiple invocations can be processed simultaneously, extensions cannot perform post-invoke processing for individual invocations as they traditionally do on Lambda (default) functions.  
For Managed Instances, the `responseLatency` and `responseDuration` spans that are normally included in `platform.runtimeDone` are instead available in the `platform.report` event. See [`platform.report`](#platform-report) for details.

```
Event: Object
- time: String
- type: String = platform.runtimeDone
- record: PlatformRuntimeDone
```

The `PlatformRuntimeDone` object has the following attributes:
+ **errorType?** – `String`
+ **metrics?** – ``RuntimeDoneMetrics`` object
+ **requestId** – `String`
+ **status** – ``Status`` object
+ **spans?** – List of ``Span`` objects
+ **tracing?** – ``TraceContext`` object

The following is an example `Event` of type `platform.runtimeDone`:

```
{
    "time": "2022-10-12T00:01:15.000Z",
    "type": "platform.runtimeDone",
    "record": {
        "requestId": "6d68ca91-49c9-448d-89b8-7ca3e6dc66aa",
        "status": "success",
        "tracing": {
            "spanId": "54565fb41ac79632",
            "type": "X-Amzn-Trace-Id",
            "value": "Root=1-62e900b2-710d76f009d6e7785905449a;Parent=0efbd19962d95b05;Sampled=1"
        },
        "spans": [
            {
                "name": "someTimeSpan",
                "start": "2022-08-02T12:01:23:521Z",
                "durationMs": 80.0
            }
        ],
        "metrics": {
            "durationMs": 140.0,
            "producedBytes": 16
        }
    }
}
```

### `platform.report`
<a name="platform-report"></a>

A `platform.report` event contains an overall report of the function invoke phase. A `platform.report` `Event` object has the following shape:

**Lambda Managed Instances**  
The `platform.report` event for Lambda Managed Instances has different metrics and spans compared to Lambda (default) functions. For Managed Instances:  
**Spans**: Contains `responseLatency` and `responseDuration` instead of `extensionOverhead`. The `extensionOverhead` span is not available because extensions cannot subscribe to the `INVOKE` event on Managed Instances due to the concurrent execution model.
**Metrics**: Only includes `durationMs`. The following metrics are not included: `billedDurationMs`, `initDurationMs`, `maxMemoryUsedMB`, and `memorySizeMB`. These per-invoke metrics are not applicable in the concurrent execution environment. For resource utilization metrics, use [Monitoring Lambda Managed Instances](lambda-managed-instances-monitoring.md) or [Lambda Insights](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-insights.html).

```
Event: Object
- time: String
- type: String = platform.report
- record: PlatformReport
```

The `PlatformReport` object has the following attributes:
+ **metrics** – ``ReportMetrics`` object
+ **requestId** – `String`
+ **spans?** – List of ``Span`` objects
+ **status** – ``Status`` object
+ **tracing?** – ``TraceContext`` object

The following is an example `Event` of type `platform.report`:

```
{
    "time": "2022-10-12T00:01:15.000Z",
    "type": "platform.report",
    "record": {
        "metrics": {
            "billedDurationMs": 694,
            "durationMs": 693.92,
            "initDurationMs": 397.68,
            "maxMemoryUsedMB": 84,
            "memorySizeMB": 128
        },
        "requestId": "6d68ca91-49c9-448d-89b8-7ca3e6dc66aa",
    }
}
```

### `platform.restoreStart`
<a name="platform-restoreStart"></a>

A `platform.restoreStart` event indicates that a function environment restoration event started. In an environment restoration event, Lambda creates the environment from a cached snapshot rather than initializing it from scratch. For more information, see [Lambda SnapStart](snapstart.md). A `platform.restoreStart` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.restoreStart
- record: PlatformRestoreStart
```

The `PlatformRestoreStart` object has the following attributes:
+ **functionName** – `String`
+ **functionVersion** – `String`
+ **instanceId?** – `String`
+ **instanceMaxMemory?** – `String`
+ **runtimeVersion?** – `String`
+ **runtimeVersionArn?** – `String`

The following is an example `Event` of type `platform.restoreStart`:

```
{
    "time": "2022-10-12T00:00:15.064Z",
    "type": "platform.restoreStart",
    "record": {
        "runtimeVersion": "nodejs-14.v3",
        "runtimeVersionArn": "arn",
        "functionName": "myFunction",
        "functionVersion": "$LATEST",
        "instanceId": "82561ce0-53dd-47d1-90e0-c8f5e063e62e",
        "instanceMaxMemory": 256
    }
}
```

### `platform.restoreRuntimeDone`
<a name="platform-restoreRuntimeDone"></a>

A `platform.restoreRuntimeDone` event indicates that a function environment restoration event completed. In an environment restoration event, Lambda creates the environment from a cached snapshot rather than initializing it from scratch. For more information, see [Lambda SnapStart](snapstart.md). A `platform.restoreRuntimeDone` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.restoreRuntimeDone
- record: PlatformRestoreRuntimeDone
```

The `PlatformRestoreRuntimeDone` object has the following attributes:
+ **errorType?** – `String`
+ **spans?** – List of ``Span`` objects
+ **status** – ``Status`` object

The following is an example `Event` of type `platform.restoreRuntimeDone`:

```
{
    "time": "2022-10-12T00:00:15.064Z",
    "type": "platform.restoreRuntimeDone",
    "record": {
        "status": "success",
        "spans": [
            {
                "name": "someTimeSpan",
                "start": "2022-08-02T12:01:23:521Z",
                "durationMs": 80.0
            }
        ]
    }
}
```

### `platform.restoreReport`
<a name="platform-restoreReport"></a>

A `platform.restoreReport` event contains an overall report of a function restoration event. A `platform.restoreReport` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.restoreReport
- record: PlatformRestoreReport
```

The `PlatformRestoreReport` object has the following attributes:
+ **errorType?** – string
+ **metrics?** – ``RestoreReportMetrics`` object
+ **spans?** – List of ``Span`` objects
+ **status** – ``Status`` object

The following is an example `Event` of type `platform.restoreReport`:

```
{
    "time": "2022-10-12T00:00:15.064Z",
    "type": "platform.restoreReport",
    "record": {
        "status": "success",
        "metrics": {
            "durationMs": 15.19
        },
        "spans": [
            {
                "name": "someTimeSpan",
                "start": "2022-08-02T12:01:23:521Z",
                "durationMs": 30.0
            }
        ]
    }
}
```

### `platform.extension`
<a name="platform-extension"></a>

An `extension` event contains logs from the extension code. An `extension` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = extension
- record: {}
```

The `PlatformExtension` object has the following attributes:
+ **events** – List of `String`
+ **name** – `String`
+ **state** – `String`

The following is an example `Event` of type `platform.extension`:

```
{
    "time": "2022-10-12T00:02:15.000Z",
    "type": "platform.extension",
    "record": {
        "events": [ "INVOKE", "SHUTDOWN" ],
        "name": "my-telemetry-extension",
        "state": "Ready"
    }
}
```

### `platform.telemetrySubscription`
<a name="platform-telemetrySubscription"></a>

A `platform.telemetrySubscription` event contains information about an extension subscription. A `platform.telemetrySubscription` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.telemetrySubscription
- record: PlatformTelemetrySubscription
```

The `PlatformTelemetrySubscription` object has the following attributes:
+ **name** – `String`
+ **state** – `String`
+ **types** – List of `String`

The following is an example `Event` of type `platform.telemetrySubscription`:

```
{
    "time": "2022-10-12T00:02:35.000Z",
    "type": "platform.telemetrySubscription",
    "record": {
        "name": "my-telemetry-extension",
        "state": "Subscribed",
        "types": [ "platform", "function" ]
    }
}
```

### `platform.logsDropped`
<a name="platform-logsDropped"></a>

A `platform.logsDropped` event contains information about dropped events. Lambda emits the `platform.logsDropped` event when a function outputs logs at too high a rate for Lambda to process them. When Lambda can't send logs to CloudWatch or to the extension subscribed to Telemetry API at the rate the function produces them, it drops logs to prevent the function's execution from slowing down. A `platform.logsDropped` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = platform.logsDropped
- record: PlatformLogsDropped
```

The `PlatformLogsDropped` object has the following attributes:
+ **droppedBytes** – `Integer`
+ **droppedRecords** – `Integer`
+ **reason** – `String`

The following is an example `Event` of type `platform.logsDropped`:

```
{
    "time": "2022-10-12T00:02:35.000Z",
    "type": "platform.logsDropped",
    "record": {
        "droppedBytes": 12345,
        "droppedRecords": 123,
        "reason": "Some logs were dropped because the downstream consumer is slower than the logs production rate"
    }
}
```

### `function`
<a name="telemetry-api-function"></a>

A `function` event contains logs from the function code. A `function` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = function
- record: {}
```

The format of the `record` field depends on whether your function's logs are formatted in plain text or JSON format. to learn more about log format configuration options, see [Configuring JSON and plain text log formats](monitoring-cloudwatchlogs-logformat.md)

The following is an example `Event` of type `function` where the log format is plain text:

```
{
    "time": "2022-10-12T00:03:50.000Z",
    "type": "function",
    "record": "[INFO] Hello world, I am a function!"
}
```

The following is an example `Event` of type `function` where the log format is JSON:

```
{
    "time": "2022-10-12T00:03:50.000Z",
    "type": "function",
    "record": {
        "timestamp": "2022-10-12T00:03:50.000Z",
        "level": "INFO",
        "requestId": "79b4f56e-95b1-4643-9700-2807f4e68189",
        "message": "Hello world, I am a function!"
    }
}
```

**Note**  
If the schema version you're using is older than the `2022-12-13` version, then the `"record"` is always rendered as a string even when your function's logging format is configured as JSON. For Lambda Managed Instances, you must use schema version `2025-01-29`.

### `extension`
<a name="telemetry-api-extension"></a>

A `extension` event contains logs from the extension code. A `extension` `Event` object has the following shape:

```
Event: Object
- time: String
- type: String = extension
- record: {}
```

The format of the `record` field depends on whether your function's logs are formatted in plain text or JSON format. to learn more about log format configuration options, see [Configuring JSON and plain text log formats](monitoring-cloudwatchlogs-logformat.md)

The following is an example `Event` of type `extension` where the log format is plain text:

```
{
    "time": "2022-10-12T00:03:50.000Z",
    "type": "extension",
    "record": "[INFO] Hello world, I am an extension!"
}
```

The following is an example `Event` of type `extension` where the log format is JSON:

```
{
    "time": "2022-10-12T00:03:50.000Z",
    "type": "extension",
    "record": {
       "timestamp": "2022-10-12T00:03:50.000Z",
       "level": "INFO",
       "requestId": "79b4f56e-95b1-4643-9700-2807f4e68189",
       "message": "Hello world, I am an extension!"
    }    
}
```

**Note**  
If the schema version you're using is older than the `2022-12-13` version, then the `"record"` is always rendered as a string even when your function's logging format is configured as JSON. For Lambda Managed Instances, you must use schema version `2025-01-29`.

## Shared object types
<a name="telemetry-api-objects"></a>

This section details the types of shared objects that the Lambda Telemetry API supports.

### `InitPhase`
<a name="InitPhase"></a>

A string enum that describes the phase when the initialization step occurs. In most cases, Lambda runs the function initialization code during the `init` phase. However, in some error cases, Lambda may re-run the function initialization code during the `invoke` phase. (This is called a *suppressed init*.)
+ **Type** – `String`
+ **Valid values** – `init`\$1`invoke`\$1`snap-start`

### `InitReportMetrics`
<a name="InitReportMetrics"></a>

An object that contains metrics about an initialization phase.
+ **Type** – `Object`

An `InitReportMetrics` object has the following shape:

```
InitReportMetrics: Object
- durationMs: Double
```

The following is an example `InitReportMetrics` object:

```
{
    "durationMs": 247.88
}
```

### `InitType`
<a name="InitType"></a>

A string enum that describes how Lambda initialized the environment.
+ **Type** – `String`
+ **Valid values** – `on-demand`\$1`provisioned-concurrency`

### `ReportMetrics`
<a name="ReportMetrics"></a>

An object that contains metrics about a completed phase.
+ **Type** – `Object`

A `ReportMetrics` object has the following shape:

```
ReportMetrics: Object
- billedDurationMs: Integer
- durationMs: Double
- initDurationMs?: Double
- maxMemoryUsedMB: Integer
- memorySizeMB: Integer
- restoreDurationMs?: Double
```

The following is an example `ReportMetrics` object:

```
{
    "billedDurationMs": 694,
    "durationMs": 693.92,
    "initDurationMs": 397.68,
    "maxMemoryUsedMB": 84,
    "memorySizeMB": 128
}
```

### `RestoreReportMetrics`
<a name="RestoreReportMetrics"></a>

An object that contains metrics about a completed restoration phase.
+ **Type** – `Object`

A `RestoreReportMetrics` object has the following shape:

```
RestoreReportMetrics: Object
- durationMs: Double
```

The following is an example `RestoreReportMetrics` object:

```
{
    "durationMs": 15.19
}
```

### `RuntimeDoneMetrics`
<a name="RuntimeDoneMetrics"></a>

An object that contains metrics about an invocation phase.
+ **Type** – `Object`

A `RuntimeDoneMetrics` object has the following shape:

```
RuntimeDoneMetrics: Object
- durationMs: Double
- producedBytes?: Integer
```

The following is an example `RuntimeDoneMetrics` object:

```
{
    "durationMs": 200.0,
    "producedBytes": 15
}
```

### `Span`
<a name="Span"></a>

An object that contains details about a span. A span represents a unit of work or operation in a trace. For more information about spans, see [Span](https://opentelemetry.io/docs/reference/specification/trace/api/#span) on the **Tracing API** page of the OpenTelemetry Docs website.

Lambda supports the following spans for the `platform.RuntimeDone` event:
+ The `responseLatency` span describes how long it took your Lambda function to start sending the response.
+ The `responseDuration` span describes how long it took your Lambda function to finish sending the entire response.
+ The `runtimeOverhead` span describes how long it took the Lambda runtime to signal that it is ready to process the next function invoke. This is how long the runtime took to call the [next invocation](runtimes-api.md#runtimes-api-next) API to get the next event after returning your function response.

The following is an example `responseLatency` span object:

```
{
        "name": "responseLatency", 
        "start": "2022-08-02T12:01:23.521Z",
        "durationMs": 23.02
      }
```

### `Status`
<a name="Status"></a>

An object that describes the status of an initialization or invocation phase. If the status is either `failure` or `error`, then the `Status` object also contains an `errorType` field describing the error.
+ **Type** – `Object`
+ **Valid status values** – `success`\$1`failure`\$1`error`\$1`timeout`

### `TraceContext`
<a name="TraceContext"></a>

An object that describes the properties of a trace.
+ **Type** – `Object`

A `TraceContext` object has the following shape:

```
TraceContext: Object
- spanId?: String
- type: TracingType enum
- value: String
```

The following is an example `TraceContext` object:

```
{
    "spanId": "073a49012f3c312e",
    "type": "X-Amzn-Trace-Id",
    "value": "Root=1-62e900b2-710d76f009d6e7785905449a;Parent=0efbd19962d95b05;Sampled=1"
}
```

### `TracingType`
<a name="TracingType"></a>

A string enum that describes the type of tracing in a ``TraceContext`` object.
+ **Type** – `String`
+ **Valid values** – `X-Amzn-Trace-Id`

# Converting Lambda Telemetry API `Event` objects to OpenTelemetry Spans
<a name="telemetry-otel-spans"></a>

The AWS Lambda Telemetry API schema is semantically compatible with OpenTelemetry (OTel). This means that you can convert your AWS Lambda Telemetry API `Event` objects to OpenTelemetry (OTel) Spans. When converting, you shouldn't map a single `Event` object to a single OTel Span. Instead, you should present all three events related to a lifecycle phase in a single OTel Span. For example, the `start`, `runtimeDone`, and `runtimeReport` events represent a single function invocation. Present all three of these events as a single OTel Span.

You can convert your events using Span Events or Child (nested) Spans. The tables on this page describe the mappings between Telemetry API schema properties and OTel Span properties for both approaches. For more information about OTel Spans, see [Span](https://opentelemetry.io/docs/reference/specification/trace/api/#span) on the **Tracing API** page of the OpenTelemetry Docs website.

**Topics**
+ [Map to OTel Spans with Span Events](#telemetry-otel-span-events)
+ [Map to OTel Spans with Child Spans](#telemetry-otel-child-spans)

## Map to OTel Spans with Span Events
<a name="telemetry-otel-span-events"></a>

In the following tables, `e` represents the event coming from the telemetry source.

**Mapping the \$1Start events**


| OpenTelemetry | Lambda Telemetry API schema | 
| --- | --- | 
|  `Span.Name`  |  Your extension generates this value based on the `type` field.  | 
|  `Span.StartTime`  |  Use `e.time`.  | 
|  `Span.EndTime`  |  N/A, because the event hasn't completed yet.  | 
|  `Span.Kind`  |  Set to `Server`.  | 
|  `Span.Status`  |  Set to `Unset`.  | 
|  `Span.TraceId`  |  Parse the AWS X-Ray header found in `e.tracing.value`, then use the `TraceId` value.  | 
|  `Span.ParentId`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Parent` value.  | 
|  `Span.SpanId`  |  Use `e.tracing.spanId` if available. Otherwise, generate a new `SpanId`.  | 
|  `Span.SpanContext.TraceState`  |  N/A for an X-Ray trace context.  | 
|  `Span.SpanContext.TraceFlags`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Sampled` value.  | 
|  `Span.Attributes`  |  Your extension can add any custom values here.  | 

**Mapping the \$1RuntimeDone events**


| OpenTelemetry | Lambda Telemetry API schema | 
| --- | --- | 
|  `Span.Name`  |  Your extension generates the value based on the `type` field.  | 
|  `Span.StartTime`  |  Use `e.time` from the matching `*Start` event. Alternatively, use `e.time - e.metrics.durationMs`.  | 
|  `Span.EndTime`  |  N/A, because the event hasn't completed yet.  | 
|  `Span.Kind`  |  Set to `Server`.  | 
|  `Span.Status`  |  If `e.status` doesn't equal `success`, then set to `Error`. Otherwise, set to `Ok`.  | 
|  `Span.Events[]`  |  Use `e.spans[]`.  | 
|  `Span.Events[i].Name`  |  Use `e.spans[i].name`.  | 
|  `Span.Events[i].Time`  |  Use `e.spans[i].start`.  | 
|  `Span.TraceId`  |  Parse the AWS X-Ray header found in `e.tracing.value`, then use the `TraceId` value.  | 
|  `Span.ParentId`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Parent` value.  | 
|  `Span.SpanId`  |  Use the same `SpanId` from the `*Start` event. If unavailable, then use `e.tracing.spanId`, or generate a new `SpanId`.  | 
|  `Span.SpanContext.TraceState`  |  N/A for an X-Ray trace context.  | 
|  `Span.SpanContext.TraceFlags`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Sampled` value.  | 
|  `Span.Attributes`  |  Your extension can add any custom values here.  | 

**Mapping the \$1Report events**


| OpenTelemetry | Lambda Telemetry API schema | 
| --- | --- | 
|  `Span.Name`  |  Your extension generates the value based on the `type` field.  | 
|  `Span.StartTime`  |  Use `e.time` from the matching `*Start` event. Alternatively, use `e.time - e.metrics.durationMs`.  | 
|  `Span.EndTime`  |  Use `e.time`.  | 
|  `Span.Kind`  |  Set to `Server`.  | 
|  `Span.Status`  |  Use the same value as the `*RuntimeDone` event.  | 
|  `Span.TraceId`  |  Parse the AWS X-Ray header found in `e.tracing.value`, then use the `TraceId` value.  | 
|  `Span.ParentId`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Parent` value.  | 
|  `Span.SpanId`  |  Use the same `SpanId` from the `*Start` event. If unavailable, then use `e.tracing.spanId`, or generate a new `SpanId`.  | 
|  `Span.SpanContext.TraceState`  |  N/A for an X-Ray trace context.  | 
|  `Span.SpanContext.TraceFlags`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Sampled` value.  | 
|  `Span.Attributes`  |  Your extension can add any custom values here.  | 

## Map to OTel Spans with Child Spans
<a name="telemetry-otel-child-spans"></a>

The following table describes how to convert Lambda Telemetry API events into OTel Spans with Child (nested) Spans for `*RuntimeDone` Spans. For `*Start` and `*Report` mappings, refer to the tables in [Map to OTel Spans with Span Events](#telemetry-otel-span-events), as they're the same for Child Spans. In this table, `e` represents the event coming from the telemetry source.

**Mapping the \$1RuntimeDone events**


| OpenTelemetry | Lambda Telemetry API schema | 
| --- | --- | 
|  `Span.Name`  |  Your extension generates the value based on the `type` field.  | 
|  `Span.StartTime`  |  Use `e.time` from the matching `*Start` event. Alternatively, use `e.time - e.metrics.durationMs`.  | 
|  `Span.EndTime`  |  N/A, because the event hasn't completed yet.  | 
|  `Span.Kind`  |  Set to `Server`.  | 
|  `Span.Status`  |  If `e.status` doesn't equal `success`, then set to `Error`. Otherwise, set to `Ok`.  | 
|  `Span.TraceId`  |  Parse the AWS X-Ray header found in `e.tracing.value`, then use the `TraceId` value.  | 
|  `Span.ParentId`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Parent` value.  | 
|  `Span.SpanId`  |  Use the same `SpanId` from the `*Start` event. If unavailable, then use `e.tracing.spanId`, or generate a new `SpanId`.  | 
|  `Span.SpanContext.TraceState`  |  N/A for an X-Ray trace context.  | 
|  `Span.SpanContext.TraceFlags`  |  Parse the X-Ray header found in `e.tracing.value`, then use the `Sampled` value.  | 
|  `Span.Attributes`  |  Your extension can add any custom values here.  | 
|  `ChildSpan[i].Name`  |  Use `e.spans[i].name`.  | 
|  `ChildSpan[i].StartTime`  |  Use `e.spans[i].start`.  | 
|  `ChildSpan[i].EndTime`  |  Use `e.spans[i].start + e.spans[i].durations`.  | 
|  `ChildSpan[i].Kind`  |  Same as parent `Span.Kind`.  | 
|  `ChildSpan[i].Status`  |  Same as parent `Span.Status`.  | 
|  `ChildSpan[i].TraceId`  |  Same as parent `Span.TraceId`.  | 
|  `ChildSpan[i].ParentId`  |  Use parent `Span.SpanId`.  | 
|  `ChildSpan[i].SpanId`  |  Generate a new `SpanId`.  | 
|  `ChildSpan[i].SpanContext.TraceState`  |  N/A for an X-Ray trace context.  | 
|  `ChildSpan[i].SpanContext.TraceFlags`  |  Same as parent `Span.SpanContext.TraceFlags`.  | 

# Using the Lambda Logs API
<a name="runtimes-logs-api"></a>

**Important**  
The Lambda Telemetry API supersedes the Lambda Logs API. **While the Logs API remains fully functional, we recommend using only the Telemetry API going forward.** You can subscribe your extension to a telemetry stream using either the Telemetry API or the Logs API. After subscribing using one of these APIs, any attempt to subscribe using the other API returns an error.

**Lambda Managed Instances do not support Logs API**  
Lambda Managed Instances do not support the Logs API. If you are using Managed Instance functions, use the [Telemetry API](telemetry-api.md) instead. The Telemetry API provides enhanced capabilities for collecting and processing telemetry data from your Lambda functions.

Lambda automatically captures runtime logs and streams them to Amazon CloudWatch. This log stream contains the logs that your function code and extensions generate, and also the logs that Lambda generates as part of the function invocation.

[Lambda extensions](runtimes-extensions-api.md) can use the Lambda Runtime Logs API to subscribe to log streams directly from within the Lambda [execution environment](lambda-runtime-environment.md). Lambda streams the logs to the extension, and the extension can then process, filter, and send the logs to any preferred destination.

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/logs-api-concept-diagram.png)


The Logs API allows extensions to subscribe to three different logs streams:
+ Function logs that the Lambda function generates and writes to `stdout` or `stderr`.
+ Extension logs that extension code generates.
+ Lambda platform logs, which record events and errors related to invocations and extensions.

**Note**  
Lambda sends all logs to CloudWatch, even when an extension subscribes to one or more of the log streams.

**Topics**
+ [Subscribing to receive logs](#runtimes-logs-api-subscribing)
+ [Memory usage](#runtimes-logs-api-memory)
+ [Destination protocols](#runtimes-logs-api-dest)
+ [Buffering configuration](#runtimes-logs-api-buffering)
+ [Example subscription](#runtimes-logs-api-subs-example)
+ [Sample code for Logs API](#runtimes-logs-api-samples)
+ [Logs API reference](#runtimes-logs-api-ref)
+ [Log messages](#runtimes-logs-api-msg)

## Subscribing to receive logs
<a name="runtimes-logs-api-subscribing"></a>

A Lambda extension can subscribe to receive logs by sending a subscription request to the Logs API.

To subscribe to receive logs, you need the extension identifier (`Lambda-Extension-Identifier`). First [register the extension](runtimes-extensions-api.md#extensions-registration-api-a) to receive the extension identifier. Then subscribe to the Logs API during [initialization](lambda-runtime-environment.md#runtimes-lifecycle-ib). After the initialization phase completes, Lambda does not process subscription requests.

**Note**  
Logs API subscription is idempotent. Duplicate subscribe requests do not result in duplicate subscriptions.

## Memory usage
<a name="runtimes-logs-api-memory"></a>

Memory usage increases linearly as the number of subscribers increases. Subscriptions consume memory resources because each subscription opens a new memory buffer to store the logs. To help optimize memory usage, you can adjust the [buffering configuration](#runtimes-logs-api-buffering). Buffer memory usage counts towards overall memory consumption in the execution environment.

## Destination protocols
<a name="runtimes-logs-api-dest"></a>

You can choose one of the following protocols to receive the logs:

1. **HTTP** (recommended) – Lambda delivers logs to a local HTTP endpoint (`http://sandbox.localdomain:${PORT}/${PATH}`) as an array of records in JSON format. The `$PATH` parameter is optional. Note that only HTTP is supported, not HTTPS. You can choose to receive logs through PUT or POST.

1. **TCP** – Lambda delivers logs to a TCP port in [Newline delimited JSON (NDJSON) format](https://github.com/ndjson/ndjson-spec).

We recommend using HTTP rather than TCP. With TCP, the Lambda platform cannot acknowledge when it delivers logs to the application layer. Therefore, you might lose logs if your extension crashes. HTTP does not share this limitation.

We also recommend setting up the local HTTP listener or the TCP port before subscribing to receive logs. During setup, note the following:
+ Lambda sends logs only to destinations that are inside the execution environment.
+ Lambda retries the attempt to send the logs (with backoff) if there is no listener, or if the POST or PUT request results in an error. If the log subscriber crashes, it continues to receive logs after Lambda restarts the execution environment.
+ Lambda reserves port 9001. There are no other port number restrictions or recommendations.

## Buffering configuration
<a name="runtimes-logs-api-buffering"></a>

Lambda can buffer logs and deliver them to the subscriber. You can configure this behavior in the subscription request by specifying the following optional fields. Note that Lambda uses the default value for any field that you do not specify.
+ **timeoutMs** – The maximum time (in milliseconds) to buffer a batch. Default: 1,000. Minimum: 25. Maximum: 30,000.
+ **maxBytes** – The maximum size (in bytes) of the logs to buffer in memory. Default: 262,144. Minimum: 262,144. Maximum: 1,048,576.
+ **maxItems** – The maximum number of events to buffer in memory. Default: 10,000. Minimum: 1,000. Maximum: 10,000.

During buffering configuration, note the following points:
+ Lambda flushes the logs if any of the input streams are closed, for example, if the runtime crashes.
+ Each subscriber can specify a different buffering configuration in their subscription request.
+ Consider the buffer size that you need for reading the data. Expect to receive payloads as large as `2*maxBytes+metadata`, where `maxBytes` is configured in the subscribe request. For example, Lambda adds the following metadata bytes to each record:

  ```
  {
  "time": "2020-08-20T12:31:32.123Z",
  "type": "function",
  "record": "Hello World"
  }
  ```
+ If the subscriber cannot process incoming logs quickly enough, Lambda might drop logs to keep memory utilization bounded. To indicate the number of dropped records, Lambda sends a `platform.logsDropped` log. For more information, see [Lambda: Not all of my function's logs appear](troubleshooting-execution.md#troubleshooting-execution-missinglogs).

## Example subscription
<a name="runtimes-logs-api-subs-example"></a>

The following example shows a request to subscribe to the platform and function logs.

```
PUT http://${AWS_LAMBDA_RUNTIME_API}/2020-08-15/logs HTTP/1.1
{ "schemaVersion": "2020-08-15",
  "types": [
      "platform",
      "function"
    ],
  "buffering": {
      "maxItems": 1000,
      "maxBytes": 262144,
      "timeoutMs": 100
    },
  "destination": {
    "protocol": "HTTP",
    "URI": "http://sandbox.localdomain:8080/lambda_logs"
  }
}
```

If the request succeeds, the subscriber receives an HTTP 200 success response.

```
HTTP/1.1 200 OK
"OK"
```

## Sample code for Logs API
<a name="runtimes-logs-api-samples"></a>

For sample code showing how to send logs to a custom destination, see [Using AWS Lambda extensions to send logs to custom destinations](https://aws.amazon.com/blogs/compute/using-aws-lambda-extensions-to-send-logs-to-custom-destinations/) on the AWS Compute Blog.

For Python and Go code examples showing how to develop a basic Lambda extension and subscribe to the Logs API, see [AWS Lambda Extensions](https://github.com/aws-samples/aws-lambda-extensions) on the AWS Samples GitHub repository. For more information about building a Lambda extension, see [Using the Lambda Extensions API to create extensions](runtimes-extensions-api.md).

## Logs API reference
<a name="runtimes-logs-api-ref"></a>

You can retrieve the Logs API endpoint from the `AWS_LAMBDA_RUNTIME_API` environment variable. To send an API request, use the prefix `2020-08-15/` before the API path. For example:

```
http://${AWS_LAMBDA_RUNTIME_API}/2020-08-15/logs
```

The OpenAPI specification for the Logs API version **2020-08-15** is available here: [logs-api-request.zip](samples/logs-api-request.zip)

### Subscribe
<a name="runtimes-logs-api-ref-a"></a>

To subscribe to one or more of the log streams available in the Lambda execution environment, extensions send a Subscribe API request.

**Path** – `/logs`

**Method** – **PUT**

**Body parameters**

`destination` – See [Destination protocols](#runtimes-logs-api-dest). Required: yes. Type: strings.

`buffering` – See [Buffering configuration](#runtimes-logs-api-buffering). Required: no. Type: strings.

`types` – An array of the types of logs to receive. Required: yes. Type: array of strings. Valid values: "platform", "function", "extension".

`schemaVersion` – Required: no. Default value: "2020-08-15". Set to "2021-03-18" for the extension to receive [`platform.runtimeDone`](#runtimes-logs-api-ref-done) messages.

****Response parameters****

The OpenAPI specifications for the subscription responses version **2020-08-15** are available for the HTTP and TCP protocols:
+ HTTP: [logs-api-http-response.zip](samples/logs-api-http-response.zip)
+ TCP: [logs-api-tcp-response.zip](samples/logs-api-tcp-response.zip)

****Response codes****
+ 200 – Request completed successfully
+ 202 – Request accepted. Response to a subscription request during local testing.
+ 4XX – Bad Request
+ 500 – Service error

If the request succeeds, the subscriber receives an HTTP 200 success response.

```
HTTP/1.1 200 OK
"OK"
```

If the request fails, the subscriber receives an error response. For example:

```
HTTP/1.1 400 OK
{
    "errorType": "Logs.ValidationError",
    "errorMessage": URI port is not provided; types should not be empty"
}
```

## Log messages
<a name="runtimes-logs-api-msg"></a>

The Logs API allows extensions to subscribe to three different logs streams:
+ Function – Logs that the Lambda function generates and writes to `stdout` or `stderr`.
+ Extension – Logs that extension code generates.
+ Platform – Logs that the runtime platform generates, which record events and errors related to invocations and extensions.

**Topics**
+ [Function logs](#runtimes-logs-api-msg-function)
+ [Extension logs](#runtimes-logs-api-msg-extension)
+ [Platform logs](#runtimes-logs-api-msg-platform)

### Function logs
<a name="runtimes-logs-api-msg-function"></a>

The Lambda function and internal extensions generate function logs and write them to `stdout` or `stderr`.

The following example shows the format of a function log message. \$1 "time": "2020-08-20T12:31:32.123Z", "type": "function", "record": "ERROR encountered. Stack trace:\$1n\$1my-function (line 10)\$1n" \$1 

### Extension logs
<a name="runtimes-logs-api-msg-extension"></a>

Extensions can generate extension logs. The log format is the same as for a function log.

### Platform logs
<a name="runtimes-logs-api-msg-platform"></a>

Lambda generates log messages for platform events such as `platform.start`, `platform.end`, and `platform.fault`.

Optionally, you can subscribe to the **2021-03-18** version of the Logs API schema, which includes the `platform.runtimeDone` log message.

#### Example platform log messages
<a name="runtimes-logs-api-examples"></a>

The following example shows the platform start and platform end logs. These logs indicate the invocation start time and invocation end time for the invocation that the requestId specifies. 

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.start",
    "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56"}   
}
{
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.end",
    "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56"}   
}
```

The **platform.initRuntimeDone** log message shows the status of the `Runtime init` sub-phase, which is part of the [Init lifecyle phase](lambda-runtime-environment.md#runtimes-lifecycle-ib). When `Runtime init` is successful, the runtime sends a `/next` runtime API request (for the `on-demand` and `provisioned-concurrency` initialization types) or `restore/next` (for the `snap-start` initialization type). The following example shows a successful **platform.initRuntimeDone** log message for the `snap-start` initialization type.

```
{
  "time":"2022-07-17T18:41:57.083Z",
  "type":"platform.initRuntimeDone",
  "record":{
      "initializationType":"snap-start",
      "status":"success"
  }
}
```

The **platform.initReport** log message shows how long the `Init` phase lasted and how many milliseconds you were billed for during this phase. When the initialization type is `provisioned-concurrency`, Lambda sends this message during invocation. When the initialization type is `snap-start`, Lambda sends this message after restoring the snapshot. The following example shows a **platform.initReport** log message for the `snap-start` initialization type.

```
{
  "time":"2022-07-17T18:41:57.083Z",
  "type":"platform.initReport",
  "record":{
      "initializationType":"snap-start",
      "metrics":{
          "durationMs":731.79,
          "billedDurationMs":732
          }
  }
}
```

The platform report log includes metrics about the invocation that the requestId specifies. The `initDurationMs` field is included in the log only if the invocation included a cold start. If AWS X-Ray tracing is active, the log includes X-Ray metadata. The following example shows a platform report log for an invocation that included a cold start.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.report",
    "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56",
        "metrics": {"durationMs": 101.51,
            "billedDurationMs": 300,
            "memorySizeMB": 512,
            "maxMemoryUsedMB": 33,
            "initDurationMs": 116.67
        }
    }
}
```

The platform fault log captures runtime or execution environment errors. The following example shows a platform fault log message. 

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.fault",
    "record": "RequestId: d783b35e-a91d-4251-af17-035953428a2c Process exited before completing request"
}
```

**Note**  
AWS is currently implementing changes to the Lambda service. Due to these changes, you may see minor differences between the structure and content of system log messages and trace segments emitted by different Lambda functions in your AWS account.  
One of the log outputs affected by this change is the platform fault log `"record"` field. The following examples show illustrative `"record"` fields in the old and new formats. The new style of fault log contains a more concise message  
These changes will be implemented during the coming weeks, and all functions in all AWS Regions except the China and GovCloud regions will transition to use the new-format log messages and trace segments.



**Example platform fault log record (old style)**  

```
"record":"RequestId: ...\tError: Runtime exited with error: exit status 255\nRuntime.ExitError"
```

**Example platform fault log record (new style)**  

```
"record":"RequestId: ... Status: error\tErrorType: Runtime.ExitError"
```

Lambda generates a platform extension log when an extension registers with the extensions API. The following example shows a platform extension message. 

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.extension",
    "record": {"name": "Foo.bar",
        "state": "Ready",
        "events": ["INVOKE", "SHUTDOWN"]
     }
}
```

Lambda generates a platform logs subscription log when an extension subscribes to the logs API. The following example shows a logs subscription message. 

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.logsSubscription",
    "record": {"name": "Foo.bar",
        "state": "Subscribed",
        "types": ["function", "platform"],
    }
}
```

Lambda generates a platform logs dropped log when an extension is not able to process the number of logs that it is receiving. The following example shows a `platform.logsDropped` log message. 

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.logsDropped",
    "record": {"reason": "Consumer seems to have fallen behind as it has not acknowledged receipt of logs.",
        "droppedRecords": 123,
        "droppedBytes" 12345
    }
}
```

The **platform.restoreStart** log message shows the time that the `Restore` phase started (`snap-start` initialization type only). Example:

```
{ 
  "time":"2022-07-17T18:43:44.782Z", 
  "type":"platform.restoreStart", 
  "record":{} 
}
```

The **platform.restoreReport** log message shows how long the `Restore` phase lasted and how many milliseconds you were billed for during this phase (`snap-start` initialization type only). Example:

```
{
  "time":"2022-07-17T18:43:45.936Z",
  "type":"platform.restoreReport",
  "record":{
      "metrics":{
          "durationMs":70.87,
          "billedDurationMs":13
      }
  }
}
```

#### Platform `runtimeDone` messages
<a name="runtimes-logs-api-ref-done"></a>

If you set the schema version to "2021-03-18" in the subscribe request, Lambda sends a `platform.runtimeDone` message after the function invocation completes either successfully or with an error. The extension can use this message to stop all the telemetry collection for this function invocation.

The OpenAPI specification for the Log event type in schema version **2021-03-18** is available here: [schema-2021-03-18.zip](samples/schema-2021-03-18.zip)

Lambda generates the `platform.runtimeDone` log message when the runtime sends a `Next` or `Error` runtime API request. The `platform.runtimeDone` log informs consumers of the Logs API that the function invocation completes. Extensions can use this information to decide when to send all the telemetry collected during that invocation.

##### Examples
<a name="runtimes-logs-api-examples"></a>

Lambda sends the `platform.runtimeDone` message after the runtime sends the NEXT request when the function invocation completes. The following examples show messages for each of the status values: success, failure, and timeout.

**Example success message**  

```
{
    "time": "2021-02-04T20:00:05.123Z",
    "type": "platform.runtimeDone",
    "record": {
       "requestId":"6f7f0961f83442118a7af6fe80b88",
       "status": "success"
    }
}
```

**Example failure message**  

```
{
   "time": "2021-02-04T20:00:05.123Z",
   "type": "platform.runtimeDone",
   "record": {
      "requestId":"6f7f0961f83442118a7af6fe80b88",
      "status": "failure"
   }
}
```

**Example timeout message**  

```
{
   "time": "2021-02-04T20:00:05.123Z",
   "type": "platform.runtimeDone",
   "record": {
      "requestId":"6f7f0961f83442118a7af6fe80b88",
      "status": "timeout"
  }
}
```

**Example platform.restoreRuntimeDone message (`snap-start` initialization type only)**  
The **platform.restoreRuntimeDone** log message shows whether or not the `Restore` phase was successful. Lambda sends this message when the runtime sends a `restore/next` runtime API request. There are three possible statuses: success, failure, and timeout. The following example shows a successful **platform.restoreRuntimeDone** log message.  

```
{
  "time":"2022-07-17T18:43:45.936Z",
  "type":"platform.restoreRuntimeDone",
  "record":{
      "status":"success"
  }
}
```