> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trace0hq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js — AWS Lambda

> Instrument a Node.js Lambda function with OpenTelemetry and send traces, logs and metrics to Trace0.

## 1. Add the OpenTelemetry Lambda Layer

Find the latest `layer-nodejs` ARN for your AWS region from the [opentelemetry-lambda releases page](https://github.com/open-telemetry/opentelemetry-lambda/releases). Add the layer ARN to your function.

## 2. Add the Collector Lambda Extension

Find the latest `layer-collector` ARN for your AWS region from the [opentelemetry-lambda releases page](https://github.com/open-telemetry/opentelemetry-lambda/releases).

Add the layer ARN to your function and then add the following `collector.yaml` file to the root of your Lambda deployment folder. Replace `YOUR_TRACE0_ENV_API_KEY` with the API key from your Trace0 environment.

```yaml theme={null}
receivers:
  telemetryapi:

  otlp:
    protocols:
      grpc:
      http:

exporters:
  otlp_http/trace0:
    endpoint: https://app.trace0hq.com/api
    headers:
      X-API-KEY: 'YOUR_TRACE0_ENV_API_KEY'

processors:
  batch:

  decouple:

  resource:
    attributes:
      - key: service.name
        value: "${env:OTEL_SERVICE_NAME}"
        action: upsert

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [resource, batch, decouple]
      exporters: [otlp_http/trace0]

    metrics:
      receivers: [otlp]
      processors: [resource, batch, decouple]
      exporters: [otlp_http/trace0]

    logs:
      receivers: [telemetryapi]
      processors: [resource, batch, decouple]
      exporters: [otlp_http/trace0]
```

## 3. Set Environment Variables

Add the following environment variables to your Lambda function.

| Variable | Value |
| - | - |
| `AWS_LAMBDA_EXEC_WRAPPER` | `/opt/otel-handler` |
| `OTEL_SERVICE_NAME` | `YOUR_SERVICE_NAME` |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4318` |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/protobuf` |
| `OPENTELEMETRY_COLLECTOR_CONFIG_URI` | `/var/task/collector.yaml` |

## 4. Add Logger

To correlate logs with traces in Trace0, your application must use an OpenTelemetry-supported logger. We recommend using [Pino](https://github.com/pinojs/pino), a low overhead JavaScript logger for Node.js. The instructions below use `Pino`, but the same approach applies to other supported loggers such as [Winston](https://github.com/winstonjs/winston).

First, install the library:

```bash theme={null}
npm install pino
```

Then create a `logger.js` file:

```javascript theme={null}
import pino from 'pino';

const logger = pino({
  mixin() {
    return {
      'service.name': process.env['OTEL_SERVICE_NAME'],
    };
  },

  formatters: {
    level: (label) => {
      return { level: label };
    },
  },
});

export default logger;
```

You can now use the logger in your app:

```typescript theme={null}
import logger from './logger.js';

logger.info(`Hello world!`);
```

All logs will now be exported to the local collector, which will in turn export them to the Trace0 ingest endpoint.

**Enable Trace Context Injection in Pino Logs**

To inject trace context (trace ID, span ID) into Pino log records, the Pino instrumentation must be loaded, as it is not loaded by default. Enable it by setting this environment variable on your Lambda:

| Variable | Value |
| - | - |
| `OTEL_NODE_ENABLED_INSTRUMENTATIONS` | `pino` |

<Note>
  Setting `OTEL_NODE_ENABLED_INSTRUMENTATIONS` disables all the default instrumentation libraries and only enables the ones you specify, except the [AWS SDK v3 instrumentation](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-aws-sdk), which is always loaded regardless. See [here](https://github.com/open-telemetry/opentelemetry-lambda/blob/main/nodejs/README.md) for full details on configuring the auto instrumentation for Node.js Lambda.
</Note>

## 5. Set HTTP request spans

For lambdas triggered via API Gateway, the HTTP request and response attributes are not set automatically on the lambda invocation span by the OTel Lambda auto-instrumentation. Therefore, they need to be set manually in your lambda code handler.

```typescript theme={null}
import { trace, SpanStatusCode } from '@opentelemetry/api';

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context
): Promise<APIGatewayProxyResult> => {
  const { httpMethod, path, requestContext } = event;

  //Set the http request method and route on the parent span.
  const span = trace.getActiveSpan();
  span?.setAttributes({
    'http.request.method': event.httpMethod,
    'http.route': event.path
  });

  const result = await processEvent(event)

  // Set the HTTP response code and mark the span as failed for 4xx/5xx responses.
  span?.setAttributes({ 'http.response.status_code': result.statusCode });
  span?.setStatus({ code: result.statusCode < 400 ? SpanStatusCode.OK : SpanStatusCode.ERROR });

  return result;
}
```

## 6. Deploy service

Deploy your service and watch traces, metrics, and logs appear in the [Trace0 dashboard](https://app.trace0hq.com) within seconds.

## Example service

See our [Node.js Lambda example app](https://github.com/Trace0-HQ/trace0-examples/tree/main/node-js-lambda) for a working service you can deploy to your AWS account.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.