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

# Node.js [Logs]

> OpenTelemetry NodeSDK for Tracelit — Express, Fastify, NestJS, and log libraries.

## 1. Environment

```bash theme={null}
OTEL_SERVICE_NAME=my-service
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.tracelit.app
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <WORKSPACE_INGEST_KEY>
```

## 2. Install

```bash theme={null}
npm install @opentelemetry/sdk-node @opentelemetry/api \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-proto \
  @opentelemetry/exporter-logs-otlp-proto \
  @opentelemetry/sdk-logs
```

## 3. Bootstrap file

Create `tracelit-otel.cjs` and start with:

```bash theme={null}
NODE_OPTIONS="--require ./tracelit-otel.cjs" <your-start-command>
```

The bootstrap must register both a **trace** exporter and a **log** exporter (`OTLPLogExporter` + `BatchLogRecordProcessor`). Traces-only setups will never pass the onboarding log check.

## 4. Log libraries

<Tabs>
  <Tab title="pino">
    Most common for Express/Fastify.

    ### Install

    ```bash theme={null}
    npm install pino @opentelemetry/instrumentation-pino
    ```

    ### Wire

    Add to your `NodeSDK` instrumentations:

    ```js theme={null}
    const { PinoInstrumentation } = require('@opentelemetry/instrumentation-pino');

    instrumentations: [
      getNodeAutoInstrumentations(),
      new PinoInstrumentation(),
    ],
    ```

    ### Produce signals

    ```js theme={null}
    logger.info({ count: 3 }, 'order listed');
    logger.error({ err }, 'payment failed');
    ```
  </Tab>

  <Tab title="winston">
    Classic structured logger.

    ### Install

    ```bash theme={null}
    npm install winston @opentelemetry/instrumentation-winston
    ```

    ### Wire

    ```js theme={null}
    const { WinstonInstrumentation } = require('@opentelemetry/instrumentation-winston');

    instrumentations: [
      getNodeAutoInstrumentations(),
      new WinstonInstrumentation(),
    ],
    ```

    ### Produce signals

    ```js theme={null}
    logger.info('order listed', { count: 3 });
    logger.error('payment failed', { err });
    ```
  </Tab>

  <Tab title="console">
    Prefer pino or winston for real services. Console is fine for proving the OTLP pipe.

    ### Smoke test

    Emit via the OpenTelemetry Logs API after `NodeSDK` starts with a log exporter, or temporarily enable console instrumentation. Then:

    ```js theme={null}
    console.info('order listed');
    console.error('payment failed');
    ```

    If console instrumentation is not enabled, these lines stay local and **will not** appear in Tracelit.
  </Tab>
</Tabs>

## 5. Verify

Emit INFO and ERROR from a route, then confirm both in Tracelit.
