Custom Span Instrumentation
Generates: Spans
Create custom performance traces (spans) to measure the execution time of specific operations.
Automatic Span Management (Recommended)
The trackSpan() function automatically manages the span lifecycle:
// Automatic span management (recommended)
PulseSDK.INSTANCE.trackSpan(
spanName = "database_query",
params = mapOf("table" to "users", "operation" to "select"),
) {
// Your operation here
val users = database.getUsers()
processUsers(users)
}
Manual Span Control
Use startSpan() when you need fine-grained control:
// Manual span control
val endSpan = PulseSDK.INSTANCE.startSpan(
spanName = "image_processing",
params = mapOf("imageId" to "img-123", "format" to "jpeg"),
)
try {
processImage()
} finally {
endSpan() // Always end the span
}
Access OpenTelemetry APIs
For advanced use cases, access the underlying OpenTelemetry APIs:
// Get OpenTelemetry RUM instance
val otelRum = PulseSDK.INSTANCE.getOtelOrNull()
// Or throw if not initialized
val otelRum = PulseSDK.INSTANCE.getOtelOrThrow()
// Use OpenTelemetry APIs directly
val tracer = otelRum.getOpenTelemetry()
.tracerProvider
.get("my-instrumentation")
val span = tracer.spanBuilder("custom_operation").startSpan()
try {
// Your operation
} finally {
span.end()
}
Generated Telemetry
Type: Span
Span Name: Custom (set by you)
Span Kind: INTERNAL
pulse.type: Not set by default (only set for specific instrumentations like network, screen_load, etc.)
Attributes
Custom Span Attributes
| Attribute | Description | Example | Always Present |
|---|---|---|---|
| Custom attributes | Any key-value pairs you define | table: "users", operation: "select" | ⚠️ Only if provided |
screen.name | Current screen/activity name | "MainActivity" | ⚠️ If available |
session.id | Session identifier | "f40364c92b85ec0c19c35a65be42b97f" | ✅ Yes |
Note: All custom spans include global attributes (service, device, OS, session, network carrier, etc.) in the
resourcesobject. See Global Attributes for complete list.
Sample Payload: Custom Span
{
"name": "database_query",
"kind": "INTERNAL",
"startTimeUnixNano": "1701000050000000000",
"endTimeUnixNano": "1701000050125000000",
"duration": "125ms",
"attributes": {
"table": "users",
"operation": "select",
"screen.name": "MainActivity",
"session.id": "f40364c92b85ec0c19c35a65be42b97f"
},
"resources": {
"android.os.api_level": "36",
"app.build_id": "1",
"app.build_name": "1.0_1",
"device.manufacturer": "Google",
"device.model.identifier": "sdk_gphone64_arm64",
"device.model.name": "sdk_gphone64_arm64",
"os.description": "BE2A.250530.026.D1",
"os.name": "Android",
"os.type": "linux",
"os.version": "16",
"rum.sdk.version": "0.16.0-alpha-SNAPSHOT",
"service.name": "PulseReactNativeOtelExample",
"service.version": "1.0_1",
"telemetry.sdk.language": "java",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.54.1"
}
}
Note: Custom spans created via
trackSpan()orstartSpan()do not have apulse.typeattribute by default. Thepulse.typeattribute is only automatically set for specific instrumentations like network requests (network), screen loads (screen_load), app starts (app_start), etc.
Best Practices
- Prefer automatic spans: Use
trackSpan()unless you need fine-grained control - Always end manual spans: Use
try/finallyto ensure spans are ended - Add meaningful attributes: Include IDs, counts, or other context in
params
Related
- Custom Events - Track business events
- Error Tracking - Report non-fatal errors
- API Reference - Complete API documentation