

# 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"
  }
}
```