| name | otel-expo-style |
| description | Expo / React Native OpenTelemetry style: bootstrap guards, init ordering, public env vars, mobile-compatible exporters, and product action spans. |
OTel Expo Style
Preserve existing runtime guards. If the app avoids native SDKs in Expo Go or an
unsupported runtime branch, initialize OTel only inside the supported branch.
const isExpoGo = process.env.EXPO_PUBLIC_RUNTIME === "expo-go";
if (!isExpoGo) {
initObservability();
Sentry.init({ dsn: process.env.EXPO_PUBLIC_SENTRY_DSN });
}
registerRootComponent(App);
In supported builds, call initObservability() before Sentry and before app
registration/user code.
SDK Shape
Use native OTel JS APIs and browser/mobile-compatible providers/exporters. Do
not create recordCounter, sendSuperlogSpan, or tracking-specific helper
files.
export const tracer = trace.getTracer("mugline.mobile");
export const meter = metrics.getMeter("mugline.mobile");
export const ordersSubmitted = meter.createCounter("mug.orders.submitted");
Add automatic fetch/XHR instrumentation when compatible so API calls get spans
without wrapping application code.
Product Actions
Wrap low-risk business operations with native active spans.
await tracer.startActiveSpan("mug.order.submit", async (span) => {
try {
span.setAttribute("tenant.id", tenantId);
ordersSubmitted.add(1, { "tenant.id": tenantId, outcome: "success" });
} catch (error) {
span.recordException(error as Error);
span.setStatus({ code: SpanStatusCode.ERROR });
throw error;
} finally {
span.end();
}
});
Env
Client bundles need public build-time vars:
EXPO_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT=https://intake.superlog.sh
EXPO_PUBLIC_OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer <key>
EXPO_PUBLIC_OTEL_SERVICE_NAME=mugline-mobile