Configure the EDOT React Native SDK

This page lists the settings available for EDOT React Native, how your app supplies them at initialization, and how initialization reports errors.

On Android and iOS, EDOT React Native reads its configuration from one file, elastic-otel-config.json, at the React Native project root. A host that builds its configuration in code can pass a native BootstrapConfiguration in place of the file; see Configure in code.

Create elastic-otel-config.json next to package.json, metro.config.js, and babel.config.js:

{
  "$schema": "./node_modules/@elastic/otel-react-native/elastic-otel-config.schema.json",
  "exportUrl": "https://your-otlp-endpoint.example",
  "apiKey": "your-api-key",
  "exportProtocol": "http",
  "sessionSampleRate": 1,
  "resourceAttributes": {
    "service.name": "your-service",
    "service.version": "1.4.0",
    "deployment.environment.name": "production",
    "service.namespace": "shop"
  }
}
		

The $schema line points your editor at the JSON schema shipped in the package, which gives completion and validation while you edit. EDOT React Native ignores it.

Key Type Required Default Sets
$schema string no Nothing. Editors use it; EDOT React Native ignores it.
exportUrl string yes The OTLP base URL. See Export connectivity.
apiKey string no no authentication The API key sent with each export request.
exportProtocol "http" or "grpc" no "http" The OTLP transport.
sessionSampleRate number from 0 to 1 no 1 The fraction of sessions that are recorded.
resourceAttributes object of string values yes, with service.name One resource attribute for each entry.

Use OpenTelemetry semantic convention keys in resourceAttributes. service.name is required. service.version defaults to the application version. Set deployment.environment.name and other attributes, such as service.namespace, as needed. See Service identity.

The file accepts only the keys in this table. An unknown key, such as a misspelled apikey, is rejected rather than ignored, so a typo cannot silently drop a setting. String values must not be blank, except $schema, which only needs to be a string. Write each key once: a repeated key is not reported, and only one of its values is used.

On Android, setup-android applies the package's elastic-otel.gradle script in android/app/build.gradle. At build time the script copies elastic-otel-config.json into the application assets. If the file does not exist, the build logs a warning with the expected path and continues. In MainApplication.onCreate, ElasticOtelReactNative.initialize(this) reads the file from the assets and starts EDOT Android before React Native loads.

On iOS, setup-ios adds elastic-otel-config.json to the app target in the Xcode project. The entry references the file at the project root, path ../elastic-otel-config.json, in the target's Copy Bundle Resources build phase, so each build copies the current file into the app bundle. At the start of application(_:didFinishLaunchingWithOptions:), try ElasticOtelReactNative.initialize() reads the file from the app bundle and starts EDOT iOS before React Native starts.

Rebuild the app after you change the file. For what happens when the file is missing or invalid, see Initialization and errors.

An API key in this file is compiled into the app, like every telemetry credential that ships in a mobile app, and can be extracted from the binary. Use an API key that only grants telemetry ingestion, and rotate it like any other client credential. If the file holds an API key, keep it out of public repositories.

A host that builds its configuration in code can call the BootstrapConfiguration overload in place of reading the file. This form also accepts a secret token through AuthenticationConfiguration.secretToken. On Android:

ElasticOtelReactNative.initialize(
    this,
    BootstrapConfiguration(
        exportUrl = "https://your-otlp-endpoint.example",
        authentication = AuthenticationConfiguration.apiKey("your-api-key"),
        protocol = Transport.HTTP,
        sessionSampleRate = 1.0,
        resourceAttributes = mapOf(
            "service.name" to "your-service",
            "service.version" to "1.4.0",
            "deployment.environment.name" to "production",
            "service.namespace" to "shop",
        ),
    ),
)
		

On iOS:

do {
  try ElasticOtelReactNative.initialize(
    BootstrapConfiguration(
      exportUrl: "https://your-otlp-endpoint.example",
      authentication: .apiKey("your-api-key"),
      transport: .http,
      sessionSampleRate: 1.0,
      resourceAttributes: [
        "service.name": "your-service",
        "service.version": "1.4.0",
        "deployment.environment.name": "production",
        "service.namespace": "shop",
      ]
    )
  )
} catch {
  fatalError("EDOT iOS bootstrap failed: \(error)")
}
		

Use one form. The file and the code are never merged, and calling both forms throws; see Initialization and errors.

exportUrl is required. Supply the base URL of either:

  • an Elastic Agent OTLP endpoint for self-managed deployments, Elastic Cloud Enterprise, or Elastic Cloud on Kubernetes; or
  • the Elastic Cloud Managed OTLP Endpoint for Elastic Cloud Hosted or Elastic Cloud Serverless.

The URL must use http or https, include a host, and contain no query, fragment, or signal-specific suffix such as /v1/traces. A gateway prefix such as https://gateway.example/tenant/otel is valid. For OTLP/HTTP, the native SDK appends signal paths to the supplied base URL. The URL scheme selects TLS or plaintext transport.

OTLP/HTTP is the default transport. Select "exportProtocol": "grpc", Android Transport.GRPC, or iOS .grpc only when the chosen endpoint accepts OTLP/gRPC.

For an Android emulator reaching a local OTLP/HTTP endpoint on the host, use http://10.0.2.2:4318. For the iOS simulator, use http://127.0.0.1:4318. When one configuration file serves both platforms, use http://localhost:4318 and run adb reverse tcp:4318 tcp:4318 so the Android emulator reaches the host; the reverse lasts until the emulator restarts or adb reconnects.

In the configuration file, set apiKey or omit it. In code, the Kotlin and Swift AuthenticationConfiguration types each hold one form: no authentication, an API key, or a secret token. Choose one:

AuthenticationConfiguration.none()
AuthenticationConfiguration.apiKey("api-key")
AuthenticationConfiguration.secretToken("secret-token")
		
AuthenticationConfiguration.none
AuthenticationConfiguration.apiKey("api-key")
AuthenticationConfiguration.secretToken("secret-token")
		

Blank credentials are rejected. See API keys in the app for how a bundled credential is exposed.

sessionSampleRate is optional. When supplied, it must be finite and between 0.0 and 1.0, inclusive. EDOT Android and EDOT iOS make the session sampling decision.

On both platforms, the service.name resource attribute is required. No resource attribute key or value may be blank, and each key is at most 255 printable ASCII characters. Initialization rejects an attribute that breaks these rules, with a message that names the key unless the key is blank. The same rules apply to a BootstrapConfiguration passed in code. Use a stable name that identifies the mobile application as the telemetry-producing service.

When service.version is absent, the application version is used.

Call Android ElasticOtelReactNative.initialize once from Application.onCreate, with or without a BootstrapConfiguration. Call the Swift equivalent once from AppDelegate before React Native starts.

A missing configuration file, invalid JSON, an unknown key, a value of the wrong type, or an invalid value throws BootstrapException from initialize(this) on Android and from initialize() on iOS. The message describes the configuration or file error. An invalid BootstrapConfiguration passed in code throws BootstrapException the same way. Telemetry is not initialized. Because the file is bundled at build time, the error appears on the first run of the build that contains it.

When the file is missing from the iOS app bundle, the message is:

elastic-otel-config.json was not found in the app bundle. Create it at the React Native project root, run setup-ios, and check that the file is in the app target's Copy Bundle Resources build phase.
		

A second call throws BootstrapException for the duplicate initialization before it reads or validates any configuration. A failed validation or native agent construction leaves no partially initialized agent.

JavaScript calls return promises. Before successful native bootstrap, manual telemetry calls reject with code E_ELASTIC_OTEL_REACT_NATIVE. Blank span names, blank log bodies, unsupported log severities, and unknown or already-ended handles also reject. Invalid parent handles create no child, and invalid log handles emit no log.

EDOT Android and EDOT iOS report native crashes as app.crash log records. On Android, the EDOT Android crash plugin, which setup-android or the Expo config plugin applies, records uncaught JVM exceptions and attempts to flush the logs before the app terminates. EDOT iOS enables native crash reporting by default, stores a crash report on the device, and exports it the next time the app starts. Crash reporting has no JavaScript setting.

Crash events appear in the "Crashes" section of each platform's Application Overview dashboard. Refer to Visualize telemetry to install and open the dashboards.