Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions sdk/@launchdarkly/observability-react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,68 @@ await tracer.withSpan('LoadProducts', async (scope) => {
> `LDObserve.withSpan`) for nested async work. See the
> [Tracing Guide](guides/tracing.md) for details.

### Global attributes

`LDObserve.setAttributes` attaches attributes to every span (including
automatic network and error spans), log record and metric recorded after the
call. Calls merge by key; `LDObserve.removeAttributes` removes keys. Global
attributes are kept in memory only, survive session changes, and can be set
before the SDK has finished initializing.

```typescript
import { LDObserve } from '@launchdarkly/observability-react-native';

LDObserve.setAttributes({ 'app.tier': 'premium', 'user.cohort': 'beta' });

// Attributes passed to an individual call win over global attributes.
LDObserve.recordLog('checkout', 'info', { 'app.tier': 'trial' });

LDObserve.removeAttributes(['user.cohort']);
```

A span gets the global attributes current when it starts. Precedence is
per-call attributes, then global attributes, then resource attributes. The
SDK-managed session keys (`highlight.session_id`, `session.id`) cannot be set
this way and are ignored.

### Custom span and log processors

Pass OpenTelemetry processors with the `spanProcessors` and `logProcessors`
options to inspect or modify telemetry before it is exported. They run in the
given order, after global attributes are applied and before the SDK's exporting
processor, so their changes are exported. A processor that throws is isolated
and never prevents the span or log record from being exported.

```typescript
import {
Observability,
type LogRecordProcessor,
type SpanProcessor,
} from '@launchdarkly/observability-react-native';

const tagSpans: SpanProcessor = {
onStart: (span) => span.setAttribute('app.build', 'release'),
onEnd: () => {},
forceFlush: () => Promise.resolve(),
shutdown: () => Promise.resolve(),
};

const tagLogs: LogRecordProcessor = {
onEmit: (logRecord) => logRecord.setAttribute('app.build', 'release'),
forceFlush: () => Promise.resolve(),
shutdown: () => Promise.resolve(),
};

new Observability({
spanProcessors: [tagSpans],
logProcessors: [tagLogs],
});
```

The `SpanProcessor`, `ReadableSpan`, `SdkSpan`, `LogRecordProcessor`,
`SdkLogRecord` and `ReadableLogRecord` types are re-exported from this package,
so you don't need to depend on matching OpenTelemetry package versions.

## Guides

- [Tracing Guide](guides/tracing.md) — a cookbook of common tracing patterns (spans, nested operations, error handling, correlated logs, and end-to-end mobile-to-backend traces).
Expand Down
25 changes: 25 additions & 0 deletions sdk/@launchdarkly/observability-react-native/src/api/Observe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,31 @@ import { SpanScope, WithSpanOptions } from './SpanScope'
import { TrackProperties } from './TrackProperties'

export interface Observe {
/**
* Set global attributes, merged by key into a process-wide map that is
* applied to every span (manual and auto-instrumented), log record and
* metric data point recorded after this call. A span gets the values current
* when it starts.
*
* Attributes passed to an individual call (e.g. `startSpan`, `recordLog`,
* `recordMetric`) take precedence over global attributes, which take
* precedence over resource attributes. SDK-managed session keys
* (`highlight.session_id`, `session.id`) are ignored.
*
* Global attributes are kept in memory only (not persisted), survive
* session changes, and remain until removed with {@link removeAttributes}.
* Safe to call before the SDK has finished initializing.
*
* @param attributes The attributes to set
*/
setAttributes(attributes: Attributes): void

/**
* Remove global attributes previously set with {@link setAttributes}.
* @param keys The attribute keys to remove
*/
removeAttributes(keys: string[]): void

/**
* Record an error with optional context.
* @param error The error to record
Expand Down
20 changes: 20 additions & 0 deletions sdk/@launchdarkly/observability-react-native/src/api/Options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Attributes } from '@opentelemetry/api'
import type { LogRecordProcessor } from '@opentelemetry/sdk-logs'
import type { SpanProcessor } from '@opentelemetry/sdk-trace-web'
import type { LDContext } from '@launchdarkly/js-sdk-common'

export type NetworkRecordingOptions = {
Expand Down Expand Up @@ -214,4 +216,22 @@ export interface ReactNativeOptions {
* @default 5000
*/
uploadIntervalMillis?: number

/**
* Additional OpenTelemetry span processors, invoked in the given order after
* global attributes (see `LDObserve.setAttributes`) are applied and before
* the SDK's exporting processor, so mutations made in `onStart` are
* exported. Errors thrown by a processor are caught and never prevent
* export.
*/
spanProcessors?: SpanProcessor[]

/**
* Additional OpenTelemetry log record processors, invoked in the given order
* after global attributes (see `LDObserve.setAttributes`) are applied and
* before the SDK's exporting processor, so mutations made in `onEmit` are
* exported. Errors thrown by a processor are caught and never prevent
* export.
*/
logProcessors?: LogRecordProcessor[]
}
10 changes: 10 additions & 0 deletions sdk/@launchdarkly/observability-react-native/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ export type { LDTracer } from './LDTracer'
export { wrapTracer } from './LDTracer'
export type { SpanScope, WithSpanOptions } from './SpanScope'
export type { TrackProperties, TrackPropertyValue } from './TrackProperties'
export type {
ReadableSpan,
Span as SdkSpan,
SpanProcessor,
} from '@opentelemetry/sdk-trace-web'
export type {
LogRecordProcessor,
ReadableLogRecord,
SdkLogRecord,
} from '@opentelemetry/sdk-logs'
Loading
Loading