# Custom instrumentation

Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Frum%2Fsdk-installation%2Freact-native%2Freact-native-plugin%2Ffeatures%2Fcustom-instrumentation.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Frum%2Fsdk-installation%2Freact-native%2Freact-native-plugin%2Ffeatures%2Fcustom-instrumentation.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

### Custom Spans[​](#custom-spans "Direct link to Custom Spans")

Create manual RUM spans to instrument custom flows in your application. Requires `traceParentInHeader.enabled: true`.

**Prerequisite:**

```
await CoralogixRum.init({

  // ...

  traceParentInHeader: { enabled: true },

});
```

**Basic usage — global span with a child:**

```
import { CoralogixRum } from '@coralogix/react-native-plugin';



const tracer = CoralogixRum.getCustomTracer();



const globalSpan = await tracer.startGlobalSpan('checkout', { step: 'start' });

if (!globalSpan) return; // another global span is already active



const childSpan = await globalSpan.startCustomSpan('validate-cart');

await childSpan?.endSpan();



await globalSpan.endSpan();
```

**Linking network requests with `withContext`:**

When you call `fetch` inside `withContext`, the network request is automatically linked to the active global span's trace.

```
const globalSpan = await tracer.startGlobalSpan('checkout');



await globalSpan.withContext(async () => {

  await fetch('https://api.example.com/cart'); // linked to globalSpan's traceId

});



await globalSpan.endSpan();
```

**`ignoredInstruments` — exclude auto-instrumentation from the trace:**

Pass instrument names to prevent network requests, errors, or interactions fired during this tracer's spans from being linked to your custom trace.

```
const tracer = CoralogixRum.getCustomTracer(['networkRequests', 'userInteractions', 'errors']);
```

Note

Only one global span may be active at a time. `startGlobalSpan` returns `null` if a global span is already open.

### Time Measurement[​](#time-measurement "Direct link to Time Measurement")

Measure the duration of arbitrary flows with a pair of `startTimeMeasure(name, labels?)` / `endTimeMeasure(name)` calls. The native SDK records start/end timestamps and reports the delta as a custom-measurement span (milliseconds).

```
import { CoralogixRum } from '@coralogix/react-native-plugin';



CoralogixRum.startTimeMeasure('checkout', { flow: 'checkout' });



await validateCart();

await charge();

await confirm();



CoralogixRum.endTimeMeasure('checkout');
```

**Behaviour:**

* Both calls are fire-and-forget — they cross the bridge directly into native and return immediately.
* The JS side keeps no state; the native SDK owns the in-flight registry.
* **You are responsible for pairing every `startTimeMeasure(name, labels?)` with exactly one `endTimeMeasure(name)`.** Leaked starts persist in memory until `CoralogixRum.shutdown()`.
* Unmatched `endTimeMeasure` calls are dropped silently by the native SDK.
* Calling `startTimeMeasure` again with an open `name` overwrites the previous start.
