Skip to main content

Custom Spans

Generates: Spans

Measure the duration of specific operations in your app.

Automatic (closure-based)

trackSpan starts and ends the span automatically:

import { Pulse } from '@dreamhorizonorg/pulse-react-native';

// Sync
const result = Pulse.trackSpan(
'parse_response',
{ attributes: { format: 'json' } },
() => JSON.parse(data)
);

// Async
const users = await Pulse.trackSpan(
'fetch_users',
{},
() => api.fetchUsers()
);

Manual

Use startSpan when the operation spans multiple call sites:

import { Pulse, SpanStatusCode } from '@dreamhorizonorg/pulse-react-native';

const span = Pulse.startSpan('file_upload', {
attributes: { size_bytes: fileData.count },
});

try {
await performUpload(fileData);
span.end(SpanStatusCode.OK);
} catch (error) {
span.recordException(error);
span.end(SpanStatusCode.ERROR);
throw error;
}
warning

Always call span.end(). Leaked spans are flushed eventually but will have incorrect duration.

Span Methods

span.setAttributes({ itemsProcessed: 42 });       // add/update attributes
span.addEvent('checkpoint', { step: 'validate' }); // mark a moment in time
span.recordException(error); // attach an error
span.end(SpanStatusCode.OK); // OK | ERROR | UNSET (default)

Context Control

By default, a new span becomes the active parent for any subsequent spans. Pass inheritContext: false to create an isolated span that won't affect the hierarchy:

const backgroundSpan = Pulse.startSpan('background_sync', {
inheritContext: false,
});

Native side

Instrument Kotlin or Swift when the work does not run through JavaScript:

import com.pulsereactnativeotel.Pulse

Pulse.trackSpan(
spanName = "native_task",
params = emptyMap(),
) {
// your work
}

More detail (startSpan, parameters, troubleshooting): Android APIs · iOS APIs.