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

# Node.js (server-side) SDK observability reference

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic documents how to get started with the LaunchDarkly observability plugin for the Node.js (server-side) SDK.

The Node.js (server-side) SDK supports the **observability plugin** for error monitoring, logging, and tracing.

<Note>
  **SDK quick links**

  LaunchDarkly's SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, and a sample application:

  <table>
    <thead>
      <tr>
        <th>Resource</th>
        <th>Location</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>SDK API documentation</td>
        <td>[Observability plugin API docs](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-node/)</td>
      </tr>

      <tr>
        <td>GitHub repository</td>
        <td>[@launchdarkly/observability-node](https://github.com/launchdarkly/observability-sdk/tree/main/sdk/%40launchdarkly/observability-node)</td>
      </tr>

      <tr>
        <td>Sample application</td>
        <td>[Example Express app](https://github.com/launchdarkly/observability-sdk/blob/main/e2e/node-plugin-express/README.md)</td>
      </tr>

      <tr>
        <td>Published module</td>
        <td>[npm](https://www.npmjs.com/package/@launchdarkly/observability-node)</td>
      </tr>
    </tbody>
  </table>
</Note>

<Warning>
  **For use in server-side applications only**

  The observability-node plugin is intended for use in multi-user Node.js server applications. If you want to set up LaunchDarkly in JavaScript in a browser environment, read the [JavaScript SDK reference](/docs/sdk/client-side/javascript) and [JavaScript SDK observability reference](/docs/sdk/observability/javascript).

  To learn more about LaunchDarkly's different SDK types, read [Choosing an SDK type](/docs/sdk/concepts/client-side-server-side).
</Warning>

## Prerequisites and dependencies

This reference guide assumes that you are somewhat familiar with the LaunchDarkly [Node.js (server-side) SDK](/docs/sdk/server-side/node-js).

The observability plugin is compatible with the [Node.js (server-side) SDK](/docs/sdk/server-side/node-js), version 9.10.0 and later.

## Get started

Follow these steps to get started:

* [Install the plugin](#install-the-plugin)
* [Initialize the Node.js (server-side) SDK client](#initialize-the-client)
* [Import the plugin before other libraries](#import-the-plugin-before-other-libraries)
* [Configure the plugin options](#configure-the-plugin-options)
* [Explore supported features](#explore-supported-features)
* [Review observability data in LaunchDarkly](#review-observability-data-in-launchdarkly)

## Install the plugin

LaunchDarkly uses a plugin to the Node.js (server-side) SDK to provide observability.

The first step is to make both the SDK and the observability plugins available as dependencies.

Here's how:

<CodeGroup>
  ```bash title="npm, Node.js SDK v9.10+" lines wrap theme={null}
    npm install @launchdarkly/node-server-sdk
    npm install @launchdarkly/observability-node
  ```

  ```bash title="yarn, Node.js SDK v9.10+" lines wrap theme={null}
    yarn add @launchdarkly/node-server-sdk
    yarn add @launchdarkly/observability-node
  ```
</CodeGroup>

Then, import the plugin into your code:

<CodeGroup>
  ```js title="Import, Node.js SDK v9.10+" lines wrap theme={null}
  import { init } from '@launchdarkly/node-server-sdk'
  import { Observability } from "@launchdarkly/observability-node";
  ```
</CodeGroup>

## Initialize the client

Next, initialize the SDK and the plugin.

To initialize, you need your LaunchDarkly environment's SDK key. This authorizes your application to connect to a particular environment within LaunchDarkly. To learn more, read [Initialize the client](/docs/sdk/server-side/node-js#initialize-the-client) in the Node.js (server-side) SDK reference guide.

Here's how to initialize the SDK and plugin:

<CodeGroup>
  ```js title="Initialize, Node.js SDK v9.10+" lines wrap theme={null}
  const client = init(
    'YOUR_SDK_KEY',
    {
      plugins: [
        new Observability(),
      ],
    },
  )
  ```
</CodeGroup>

## Import the plugin before other libraries

The observability plugin instruments supported libraries, such as Express and database drivers, by hooking into the Node.js CommonJS module loader. Importing `@launchdarkly/observability-node` installs those hooks. The plugin instruments only the libraries that your application loads after the hooks are in place. If your application loads Express before it imports the plugin, the plugin does not capture Express routes or middleware.

Your application does not need to wait for the LaunchDarkly client to finish initializing before it loads other libraries.

To control the order, initialize the SDK in a dedicated module, then load that module before your application loads anything else. How you load it depends on whether your application uses CommonJS or ECMAScript modules (ESM).

<Warning>
  **Automatic instrumentation is limited in ESM applications**

  The hooks only intercept CommonJS module loading. The plugin does not instrument libraries that your application loads with an ESM `import`, which means that ESM applications do not receive spans for Express routes or middleware.

  Most frameworks load the Node.js `http` module internally through CommonJS. As a result, ESM applications still receive spans for incoming and outgoing HTTP requests, along with the metrics that LaunchDarkly generates from those spans. If your application does not load `http` this way, the plugin captures no automatic spans.

  In either case, you can record spans, metrics, logs, and errors manually with `LDObserve`. To learn more, read [Tracing](/docs/sdk/features/observability-traces#node-js-server-side).
</Warning>

<Accordion title="CommonJS applications">
  Here is the dedicated module:

  <CodeGroup>
    ```js title="launchdarkly.js" lines wrap theme={null}
    const { init } = require('@launchdarkly/node-server-sdk')
    const { Observability } = require('@launchdarkly/observability-node')

    module.exports = init(
    'YOUR_SDK_KEY',
    {
      plugins: [
        new Observability(),
      ],
    },
    )
    ```
  </CodeGroup>

  Then load that module from the first line of your application's entry point, before you require any other library:

  <CodeGroup>
    ```js title="server.js" lines wrap theme={null}
    const client = require('./launchdarkly')
    const express = require('express')

    const app = express()
    ```
  </CodeGroup>

  Alternatively, preload the module with the Node.js `--require` option. This keeps the ordering requirement out of your application code:

  <CodeGroup>
    ```bash title="Preload the module" lines wrap theme={null}
    node --require ./launchdarkly.js server.js
    ```
  </CodeGroup>

  If you write your application in TypeScript and compile it to CommonJS, the same ordering applies to the compiled output. Put the initialization in its own source file, such as `launchdarkly.ts`, and import that file first.
</Accordion>

<Accordion title="ESM applications">
  In an ESM application, Node.js evaluates every `import` statement in a file before it runs any of that file's own code. Initializing the SDK in the body of your entry point is too late, because your application has already loaded Express and your other libraries by that point. Put the initialization in its own module instead.

  Ordering determines whether an ESM application produces any telemetry at all. If the plugin loads first, it captures HTTP request spans through the imports your framework makes internally. If it loads later, it captures nothing.

  Here is the dedicated module:

  <CodeGroup>
    ```js title="instrumentation.js" lines wrap theme={null}
    import { init } from '@launchdarkly/node-server-sdk'
    import { Observability } from '@launchdarkly/observability-node'

    export const client = init(
    'YOUR_SDK_KEY',
    {
      plugins: [
        new Observability(),
      ],
    },
    )
    ```
  </CodeGroup>

  Then preload the module with the Node.js `--import` option:

  <CodeGroup>
    ```bash title="Preload the module" lines wrap theme={null}
    node --import ./instrumentation.js server.js
    ```
  </CodeGroup>

  You can also load the module as the first import in your entry point. We recommend the `--import` option instead, because bundlers and automatic import sorting can reorder import statements:

  <CodeGroup>
    ```js title="server.js" lines wrap theme={null}
    import './instrumentation.js'
    import express from 'express'

    const app = express()
    ```
  </CodeGroup>
</Accordion>

## Configure the plugin options

You can configure options for the observability plugin when you initialize the SDK. The plugin constructor takes an optional object with the configuration details.

Here is an example:

<CodeGroup>
  ```js title="Plugin options, Node.js SDK v9.10+" lines wrap theme={null}
  const client = init(
    'YOUR_SDK_KEY',
    {
      plugins: [
        new Observability({
          serviceName: 'example-service',
          // we recommend setting serviceVersion to the latest deployed git SHA
          serviceVersion: 'example-sha'
        }),
      ],
    },
  )
  ```
</CodeGroup>

For more information on plugin options, as well as how they interact with environment variables and existing OpenTelemetry configuration, read [Configuration for server-side observability](/docs/sdk/features/observability-config-server-side).

## Explore supported features

The observability plugin supports the following features. After the SDK and plugins are initialized, you can access these from within your application:

* [Configuration for server-side observability](/docs/sdk/features/observability-config-server-side#node-js-server-side)
* [Errors](/docs/sdk/features/observability-errors#node-js-server-side)
* [Logs](/docs/sdk/features/observability-logs#node-js-server-side)
* [Metrics](/docs/sdk/features/observability-metrics#node-js-server-side)
* [Tracing](/docs/sdk/features/observability-traces#node-js-server-side)

## Review observability data in LaunchDarkly

After you initialize the SDK and observability plugin, your application automatically starts sending observability data back to LaunchDarkly in the form of custom events. You can review this information in the LaunchDarkly user interface. To learn how, read [Observability](/docs/home/observability).

Specifically, the observability data includes events that LaunchDarkly uses to automatically create the following metrics:

* User HTTP error rate (OpenTelemetry)
* User HTTP 5XX response rate (OpenTelemetry)
* User non-HTTP exception rate (OpenTelemetry)
* Average, P95, and P99 request latency (OpenTelemetry)

To learn more, read [OpenTelemetry autogenerated metrics](/docs/home/metrics/autogen/opentelemetry).
