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

# Configuration for client-side observability

> This topic explains how to configure the observability plugin for client-side SDKs.

> For the complete documentation index, see [llms.txt](/llms.txt). For the full documentation snapshot, see [llms-full.txt](/llms-full.txt).

## Overview

This topic explains how to configure the observability plugin for client-side SDKs.

The observability plugin collects and sends observability data to LaunchDarkly, so you can review error monitoring, logs, traces, and more from within the LaunchDarkly UI.

To get started with the observability plugin, read the observability reference guide for your SDK. Use the docs site navigation on the left, or find your SDK under [Observability SDKs](/sdk/observability#observability-sdks).

Details about each SDK's configuration are available in the SDK-specific sections below:

* [Client-side SDKs](#client-side-sdks)

## Client-side SDKs

This feature is available in the observability plugin for the following client-side SDKs:

* [iOS](#ios)
* [Android](#android)
* [JavaScript](#javascript)
* [React Native](#react-native)
* [React Web](#react-web)
* [Vue](#vue)

### iOS

<Accordion title="Expand iOS code sample">
  To specify the observability plugin configuration options, use `Options` for the plugin.

  Here's how:

  <CodeGroup>
    ```swift title="Plugin options, iOS SDK v9.14+" theme={null}
          let config = LDConfig(mobileKey: "example-mobile-key", autoEnvAttributes: .enabled)
          config.plugins = [
                Observability(
                    options: .init(
                        serviceName: "custom service name",
                        serviceVersion: "1.0.0",
                        resourceAttributes: [
                            "my-resource": .string("my-value")
                        ],
                        isDebug: true,
                        logs: .enabled,
                        traces: .enabled,
                        metrics: .enabled
                    )
                )
            ]
    ```
  </CodeGroup>

  For a complete list of configuration options, read [`Configuration`](https://github.com/launchdarkly/swift-launchdarkly-observability/blob/main/Sources/LaunchDarklyObservability/API/Options.swift).
</Accordion>

### Android

<Accordion title="Expand Android code sample">
  To specify the observability plugin configuration options, use `Options` for the plugin.

  Here's how:

  <CodeGroup>
    ```java title="Plugin configuration options" theme={null}
          val ldConfig = new LDConfig.Builder(AutoEnvAttributes.Enabled)
              .mobileKey("example-mobile-key")
              .plugins(
                Components.plugins().setPlugins(
                  Collections.singletonList<Plugin>(
                    Observability(
                      this@BaseApplication,
                      Options(
                        resourceAttributes = Attributes.of(
                          AttributeKey.stringKey("serviceName"), "example-service"
                        )
                      )
                    )
                  )
                )
              )
              .build();

          LDContext context = LDContext.create("example-context-key");

          LDClient client = LDClient.init(this@BaseApplication, ldConfig, context, 0);
    ```
  </CodeGroup>

  For a complete list of configuration options, read [`Options javadoc`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-android/com/launchdarkly/observability/api/Options.html).
</Accordion>

### Java

Script

<Accordion title="Expand JavaScript code sample">
  The observability plugin supports the following configuration options. After you [initialize the SDK](/sdk/observability/javascript#initialize-the-client), you can set these when you [configure the observability plugin options](/sdk/observability/javascript#configure-the-plugin-options). Then, you can access the related features from within your application.

  #### Recording network requests and Web

  Socket events

  By default, the observability plugin shows you all the network request durations, response codes, and sizes for a session.

  You can configure the options for the observability plugin to additionally record the headers and bodies of network requests and responses. Then, provide these options when you initialize the SDK client.

  Here's how to construct the `options` object:

  <CodeGroup>
    ```js title="Plugin options" theme={null}
          const options = {
            plugins: [
              new Observability({
                networkRecording: {
                  enabled: true,
                  recordHeadersAndBody: true
                }
              })
            ]
          }
    ```
  </CodeGroup>

  By default, the plugin does not record the following headers:

  * `Authorization`
  * `Cookie`
  * `Proxy-Authorization`

  To redact other headers, set `networkRecording.networkHeadersToRedact`. To redact specific keys in the request/response body, set `networkRecording.networkBodyKeysToRedact`. Alternatively, you can use an allowlist, and set `networkRecording.headerKeysToRecord` and `networkRecording.bodyKeysToRecord`.

  By default, the plugins do not record the following URLs:

  * `https://www.googleapis.com/identitytoolkit`
  * `https://securetoken.googleapis.com`

  To redact other URLs, for example if you have APIs that you know will always return secrets in their headers, body, or both, add the option `urlBlocklist` to your plugin options and set it to a list of URLs:

  <CodeGroup>
    ```js title="Plugin options" theme={null}
          const options = {
            plugins: [
              new Observability({
                networkRecording: {
                  enabled: true,
                  recordHeadersAndBody: true
                },
                urlBlocklist: [
                  'https://salted-passwords.com',
                ]
              })
            ]
          };
    ```
  </CodeGroup>

  If none of these options are specific enough, you can write your own method to sanitize network responses. Define a `networkRecording.requestResponseSanitizer` function that receives a request/response pair and returns either `null`, if you want to drop the request entirely, or a sanitized request/response pair. We do not recommend dropping requests completely unless absolutely necessary, as it can cause issues with debugging due to the missing requests. Instead, we recommend deleting or redacting header and body fields in your `requestResponseSanitizer` function.

  When `networkRecording.recordHeadersAndBody` is `true`, the plugins record all of the WebSocket events in your sessions, including opening a connection, sending and receiving messages, receiving an error, and closing a connection.

  To disable WebSocket events, but keep recording the headers and bodies of network requests, set `networkRecording.disableWebSocketEventRecordings` to `true`.

  #### Console messages

  By default, the plugins show the console messages that were logged during a session.

  To disable console recording, set `disableConsoleRecording` to `true` when you [configure the plugin options](/sdk/observability/javascript#configure-the-plugin-options) for either the observability plugin or the session replay plugin.

  If you are not seeing console logs in your session recordings, ensure that `disableConsoleRecording` is set to `false` in your plugin options.

  To specify which console methods to record, set `consoleMethodsToRecord`.

  #### Using a proxy

  If your sessions or errors are not appearing in LaunchDarkly, it may be that requests to LaunchDarkly are being blocked. This may be happening for any of several reasons, including third-party browser extensions, browser configuration, or VPN settings.

  If you have access to your domain's DNS settings, you can set up a proxy from your domain to LaunchDarkly to avoid having requests blocked.

  Here's how:

  1. On your domain, add two `CNAME` records:

     * A `CNAME` record that points `pub.ld.<your_domain>` to `pub.observability.app.launchdarkly.com`
     * A `CNAME` record that points `otel.ld.<your_domain>` to `otel.observability.app.launchdarkly.com`

     Together, these records mean that if you have an app running at `<your_domain>`, your DNS records will point `pub.ld.<your_domain>` and `otel.ld.<your_domain>` to the LaunchDarkly servers.

  2. In your application, set the `backendUrl` and `otel` options when you [configure the observability plugin](/sdk/observability/javascript#configure-the-plugin-options).

     * Set the `backendUrl` option to `pub.ld.<your_domain>`
     * Set the `otel` option to `otel.ld.<your_domain>`

     Here's how:

  <CodeGroup>
    ```js title="Plugin options" theme={null}
             // the examples assume your_domain is acme.com

             const options = {
               plugins: [
                 new Observability({
                   backendUrl: 'https://pub.ld.acme.com',
                   otel: { otlpEndpoint: 'https://otel.ld.acme.com', },
                 })
               ]
             };
    ```
  </CodeGroup>

  #### Fullstack mapping

  We recommend instrumenting your application so that you can attribute frontend requests with backend errors and logs.

  To do this, set following plugin options:

  * `tracingOrigins`:
    * set to the URI of your application's backend API to propagate the trace context. Matching API requests include a {/* cSpell:disable */}`traceparent`{/* cSpell:enable */} HTTP header that propagates the trace context, allowing server-side tracing and logging to associate its data with the frontend trace.
    * set to `true` to include all domains and subdomains of the URL for your frontend application.
    * set to an array of patterns matching the location of your backend if you want to include specific URLs. You'll need to use this option if your application makes cross-origin requests that you would like to trace. For example, if your frontend sends requests to `https://backend.example.com/api`, set the value to `['backend.example.com/api']`.
  * `networkRecording`:
    * set `enabled` to `true`
    * set `recordHeadersAndBody` to `true`

  Here's how:

  <CodeGroup>
    ```js title="Plugin options" theme={null}
          const options = {
            plugins: [
              new Observability({
                tracingOrigins: true,
                networkRecording: {
                  enabled: true,
                  recordHeadersAndBody: true
                }
              })
            ]
          };
    ```
  </CodeGroup>

  #### Versioning sessions and errors

  When you [configure the plugin options](/sdk/observability/javascript#configure-the-plugin-options), you can optionally set a `version` field. The version is then included in the [error and session views in the LaunchDarkly UI](/home/observability).

  This `version` field is configured manually, and is separate from any versions that may be set if you [configure automatic environment attributes](/sdk/features/environment-attributes) in the LaunchDarkly SDK.
</Accordion>

### React Native

<Accordion title="Expand React Native code sample">
  To specify the observability plugin configuration options, use the `ReactNativeOptions` interface to set the options.

  Here's how:

  <CodeGroup>
    ```js title="Plugin configuration options" theme={null}
          const client = new ReactNativeLDClient(
              'example-mobile-key',
              AutoEnvAttributes.Enabled,
              {
                plugins: [
                  new Observability({
                    serviceName: 'example-service',
                    // we recommend setting service_version to the latest deployed git SHA
                    serviceVersion: 'example-sha'
                  })
                ],
              }
          );
    ```
  </CodeGroup>

  For a complete list of configuration options, read [`ReactNativeOptions`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-react-native/interfaces/ReactNativeOptions.html).
</Accordion>

### React Web

Configuring the observability plugin in the React Web SDK follows the examples given for the [JavaScript SDK](#javascript).

### Vue

Configuring the observability plugin in the Vue SDK follows the examples given for the [JavaScript SDK](#javascript).

## Monkey patches

When the observability plugin runs, it [monkey patches](https://en.wikipedia.org/wiki/Monkey_patch) browser APIs in order to record errors, console messages, network requests, and changes on the page.

<Accordion title="Expand Browser APIs subject to monkey patching">
  ### Browser APIs subject to monkey patching

  Here is a list of the browser APIs that the LaunchDarkly observability plugins may monkey patch:

  * `window.sessionStorage.setItem`
  * `window.sessionStorage.getItem`
  * `window.sessionStorage.removeItem`
  * `window.onerror`
  * `window.fetch`
  * `window.FontFace`
  * `window.scroll`
  * `window.scrollTo`
  * `window.scrollBy`
  * `window.scrollIntoView`
  * `window.WebGLRenderingContext`
  * `window.WebGL2RenderingContext`
  * `window.CanvasRenderingContext2D`
  * `window.HTMLCanvasElement`
  * `window.CSSStyleSheet.prototype.insertRule`
  * `window.CSSStyleSheet.prototype.deleteRule`
  * `window.CSSGroupingRule`
  * `window.CSSMediaRule`
  * `window.CSSConditionRule`
  * `window.CSSSupportsRule`
  * `window.CSSStyleDeclaration.prototype.setProperty`
  * `window.CSSStyleDeclaration.prototype.removeProperty`
  * `history.pushState`
  * `history.replaceState`
  * `XMLHttpRequest.prototype.open`
  * `XMLHttpRequest.prototype.setRequestHeader`
  * `XMLHttpRequest.prototype.send`
  * `console.assert`
  * `console.clear`
  * `console.count`
  * `console.countReset`
  * `console.debug`
  * `console.dir`
  * `console.dirxml`
  * `console.error`
  * `console.group`
  * `console.groupCollapsed`
  * `console.groupEnd`
  * `console.info`
  * `console.log`
  * `console.table`
  * `console.time`
  * `console.timeEnd`
  * `console.timeLog`
  * `console.trace`
  * `console.warn`
</Accordion>
