react-native-otel 0.1.0 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1137 -13
- package/lib/module/context/span-context.js +56 -5
- package/lib/module/context/span-context.js.map +1 -1
- package/lib/module/core/ids.js +21 -7
- package/lib/module/core/ids.js.map +1 -1
- package/lib/module/core/meter.js +101 -12
- package/lib/module/core/meter.js.map +1 -1
- package/lib/module/core/processor.js +28 -0
- package/lib/module/core/processor.js.map +1 -0
- package/lib/module/core/resource.js +1 -0
- package/lib/module/core/resource.js.map +1 -1
- package/lib/module/core/sampler.js +55 -0
- package/lib/module/core/sampler.js.map +1 -0
- package/lib/module/core/span.js +15 -1
- package/lib/module/core/span.js.map +1 -1
- package/lib/module/core/tracer.js +94 -5
- package/lib/module/core/tracer.js.map +1 -1
- package/lib/module/exporters/console-exporter.js +8 -1
- package/lib/module/exporters/console-exporter.js.map +1 -1
- package/lib/module/exporters/multi-exporter.js +57 -0
- package/lib/module/exporters/multi-exporter.js.map +1 -0
- package/lib/module/exporters/otlp-http-exporter.js +159 -25
- package/lib/module/exporters/otlp-http-exporter.js.map +1 -1
- package/lib/module/exporters/wal.js +129 -0
- package/lib/module/exporters/wal.js.map +1 -0
- package/lib/module/index.js +16 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/instrumentation/errors.js +21 -0
- package/lib/module/instrumentation/errors.js.map +1 -1
- package/lib/module/instrumentation/expo-router.js +76 -0
- package/lib/module/instrumentation/expo-router.js.map +1 -0
- package/lib/module/instrumentation/fetch.js +99 -0
- package/lib/module/instrumentation/fetch.js.map +1 -0
- package/lib/module/instrumentation/lifecycle.js +6 -1
- package/lib/module/instrumentation/lifecycle.js.map +1 -1
- package/lib/module/instrumentation/linking.js +65 -0
- package/lib/module/instrumentation/linking.js.map +1 -0
- package/lib/module/instrumentation/network.js +35 -0
- package/lib/module/instrumentation/network.js.map +1 -1
- package/lib/module/instrumentation/startup.js +46 -0
- package/lib/module/instrumentation/startup.js.map +1 -0
- package/lib/module/sdk.js +87 -5
- package/lib/module/sdk.js.map +1 -1
- package/lib/module/version.js +7 -0
- package/lib/module/version.js.map +1 -0
- package/lib/typescript/src/context/span-context.d.ts +14 -4
- package/lib/typescript/src/context/span-context.d.ts.map +1 -1
- package/lib/typescript/src/core/ids.d.ts.map +1 -1
- package/lib/typescript/src/core/meter.d.ts +12 -2
- package/lib/typescript/src/core/meter.d.ts.map +1 -1
- package/lib/typescript/src/core/processor.d.ts +29 -0
- package/lib/typescript/src/core/processor.d.ts.map +1 -0
- package/lib/typescript/src/core/resource.d.ts +3 -0
- package/lib/typescript/src/core/resource.d.ts.map +1 -1
- package/lib/typescript/src/core/sampler.d.ts +31 -0
- package/lib/typescript/src/core/sampler.d.ts.map +1 -0
- package/lib/typescript/src/core/span.d.ts +16 -0
- package/lib/typescript/src/core/span.d.ts.map +1 -1
- package/lib/typescript/src/core/tracer.d.ts +16 -6
- package/lib/typescript/src/core/tracer.d.ts.map +1 -1
- package/lib/typescript/src/exporters/console-exporter.d.ts.map +1 -1
- package/lib/typescript/src/exporters/multi-exporter.d.ts +28 -0
- package/lib/typescript/src/exporters/multi-exporter.d.ts.map +1 -0
- package/lib/typescript/src/exporters/otlp-http-exporter.d.ts +20 -2
- package/lib/typescript/src/exporters/otlp-http-exporter.d.ts.map +1 -1
- package/lib/typescript/src/exporters/types.d.ts +17 -3
- package/lib/typescript/src/exporters/types.d.ts.map +1 -1
- package/lib/typescript/src/exporters/wal.d.ts +21 -0
- package/lib/typescript/src/exporters/wal.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +15 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/instrumentation/errors.d.ts.map +1 -1
- package/lib/typescript/src/instrumentation/expo-router.d.ts +31 -0
- package/lib/typescript/src/instrumentation/expo-router.d.ts.map +1 -0
- package/lib/typescript/src/instrumentation/fetch.d.ts +18 -0
- package/lib/typescript/src/instrumentation/fetch.d.ts.map +1 -0
- package/lib/typescript/src/instrumentation/lifecycle.d.ts.map +1 -1
- package/lib/typescript/src/instrumentation/linking.d.ts +23 -0
- package/lib/typescript/src/instrumentation/linking.d.ts.map +1 -0
- package/lib/typescript/src/instrumentation/network.d.ts.map +1 -1
- package/lib/typescript/src/instrumentation/startup.d.ts +16 -0
- package/lib/typescript/src/instrumentation/startup.d.ts.map +1 -0
- package/lib/typescript/src/sdk.d.ts +35 -0
- package/lib/typescript/src/sdk.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +2 -0
- package/lib/typescript/src/version.d.ts.map +1 -0
- package/package.json +12 -2
- package/src/context/span-context.ts +61 -8
- package/src/core/ids.ts +21 -7
- package/src/core/meter.ts +136 -14
- package/src/core/processor.ts +33 -0
- package/src/core/resource.ts +6 -0
- package/src/core/sampler.ts +65 -0
- package/src/core/span.ts +28 -1
- package/src/core/tracer.ts +140 -19
- package/src/exporters/console-exporter.ts +18 -4
- package/src/exporters/multi-exporter.ts +59 -0
- package/src/exporters/otlp-http-exporter.ts +191 -29
- package/src/exporters/types.ts +24 -3
- package/src/exporters/wal.ts +145 -0
- package/src/index.ts +36 -1
- package/src/instrumentation/errors.ts +27 -0
- package/src/instrumentation/expo-router.ts +94 -0
- package/src/instrumentation/fetch.ts +134 -0
- package/src/instrumentation/lifecycle.ts +7 -1
- package/src/instrumentation/linking.ts +83 -0
- package/src/instrumentation/network.ts +39 -0
- package/src/instrumentation/startup.ts +49 -0
- package/src/sdk.ts +115 -4
- package/src/version.ts +6 -0
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["otel","Span","NoopSpan","Tracer","Meter","Counter","Histogram","Gauge","OtelLogger","spanContext","ConsoleSpanExporter","ConsoleMetricExporter","ConsoleLogExporter","OtlpHttpExporter","OtlpHttpMetricExporter","OtlpHttpLogExporter","createNavigationInstrumentation","createAxiosInstrumentation","installErrorInstrumentation","OtelProvider","OtelContext","useOtel"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA,SAASA,IAAI,QAAQ,UAAO;AAG5B;AACA,SAASC,IAAI,EAAEC,QAAQ,QAAQ,gBAAa;
|
|
1
|
+
{"version":3,"names":["otel","Span","NoopSpan","Tracer","Meter","Counter","Histogram","Gauge","OtelLogger","AlwaysOnSampler","AlwaysOffSampler","TraceIdRatioSampler","SimpleSpanProcessor","NoopSpanProcessor","SDK_VERSION","spanContext","ConsoleSpanExporter","ConsoleMetricExporter","ConsoleLogExporter","OtlpHttpExporter","OtlpHttpMetricExporter","OtlpHttpLogExporter","MultiSpanExporter","MultiMetricExporter","MultiLogExporter","createNavigationInstrumentation","createAxiosInstrumentation","installErrorInstrumentation","createFetchInstrumentation","uninstallFetchInstrumentation","installStartupInstrumentation","createLinkingInstrumentation","recordPushNotification","OtelProvider","OtelContext","useOtel"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA,SAASA,IAAI,QAAQ,UAAO;AAG5B;AACA,SAASC,IAAI,EAAEC,QAAQ,QAAQ,gBAAa;AAS5C,SAASC,MAAM,QAAQ,kBAAe;AAEtC,SAASC,KAAK,EAAEC,OAAO,EAAEC,SAAS,EAAEC,KAAK,QAAQ,iBAAc;AAE/D,SAASC,UAAU,QAAQ,sBAAmB;;AAK9C;;AAEA,SACEC,eAAe,EACfC,gBAAgB,EAChBC,mBAAmB,QACd,mBAAgB;;AAEvB;AACA,SAASC,mBAAmB,EAAEC,iBAAiB,QAAQ,qBAAkB;;AAEzE;AACA,SAASC,WAAW,QAAQ,cAAW;;AAEvC;AACA,SAASC,WAAW,QAAQ,2BAAwB;;AAGpD;;AAQA,SACEC,mBAAmB,EACnBC,qBAAqB,EACrBC,kBAAkB,QACb,iCAA8B;AACrC,SACEC,gBAAgB,EAChBC,sBAAsB,EACtBC,mBAAmB,QACd,mCAAgC;AAMvC,SACEC,iBAAiB,EACjBC,mBAAmB,EACnBC,gBAAgB,QACX,+BAA4B;;AAEnC;AACA,SAASC,+BAA+B,QAAQ,iCAA8B;AAE9E,SAASC,0BAA0B,QAAQ,8BAA2B;AAOtE,SAASC,2BAA2B,QAAQ,6BAA0B;AAEtE,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,4BAAyB;AAEhC,SAASC,6BAA6B,QAAQ,8BAA2B;AACzE,SACEC,4BAA4B,EAC5BC,sBAAsB,QACjB,8BAA2B;AAGlC;AACA,SAASC,YAAY,EAAEC,WAAW,QAAQ,yBAAsB;AAEhE,SAASC,OAAO,QAAQ,oBAAiB","ignoreList":[]}
|
|
@@ -59,5 +59,26 @@ export function installErrorInstrumentation(params) {
|
|
|
59
59
|
}
|
|
60
60
|
originalHandler?.(error, isFatal);
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
// Wire up unhandled Promise rejection tracking.
|
|
64
|
+
// globalThis.onunhandledrejection is available in Hermes (default RN engine since 0.70).
|
|
65
|
+
// Without this, async errors that are never .catch()-ed are silently swallowed.
|
|
66
|
+
const prevRejectionHandler = globalThis.onunhandledrejection;
|
|
67
|
+
globalThis.onunhandledrejection = event => {
|
|
68
|
+
const reason = event.reason;
|
|
69
|
+
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
70
|
+
const span = tracer.startSpan(`unhandled_rejection.${error.name}`, {
|
|
71
|
+
kind: 'INTERNAL',
|
|
72
|
+
attributes: {
|
|
73
|
+
[ATTR_EXCEPTION_TYPE]: error.name,
|
|
74
|
+
[ATTR_EXCEPTION_MESSAGE]: error.message,
|
|
75
|
+
[ATTR_EXCEPTION_STACKTRACE]: error.stack ?? '',
|
|
76
|
+
'exception.unhandled_rejection': true
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
span.setStatus('ERROR', error.message);
|
|
80
|
+
span.end();
|
|
81
|
+
prevRejectionHandler?.call(globalThis, event);
|
|
82
|
+
};
|
|
62
83
|
}
|
|
63
84
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ATTR_EXCEPTION_MESSAGE","ATTR_EXCEPTION_STACKTRACE","ATTR_EXCEPTION_TYPE","Span","CRASH_KEY","installErrorInstrumentation","params","tracer","storage","exporter","pending","getSync","crashRecord","JSON","parse","export","deleteSync","originalHandler","ErrorUtils","getGlobalHandler","setGlobalHandler","error","isFatal","span","startSpan","name","kind","attributes","message","stack","setStatus","end","record","traceId","spanId","startTimeMs","endTimeMs","Date","now","events","status","statusMessage","setSync","stringify"],"sourceRoot":"../../../src","sources":["instrumentation/errors.ts"],"mappings":";;AAAA,SACEA,sBAAsB,EACtBC,yBAAyB,EACzBC,mBAAmB,QACd,qCAAqC;AAE5C,SAASC,IAAI,QAAQ,iBAAc;AAInC,MAAMC,SAAS,GAAG,kCAAkC;;AAUpD;;AAiBA,OAAO,SAASC,2BAA2BA,CAACC,MAI3C,EAAQ;EACP,MAAM;IAAEC,MAAM;IAAEC,OAAO;IAAEC;EAAS,CAAC,GAAGH,MAAM;;EAE5C;EACA,IAAIE,OAAO,IAAIC,QAAQ,EAAE;IACvB,MAAMC,OAAO,GAAGF,OAAO,CAACG,OAAO,CAACP,SAAS,CAAC;IAC1C,IAAIM,OAAO,EAAE;MACX,IAAI;QACF,MAAME,WAAW,GAAGC,IAAI,CAACC,KAAK,CAACJ,OAAO,CAAoB;QAC1DD,QAAQ,CAACM,MAAM,CAAC,CAACH,WAAW,CAA4B,CAAC;MAC3D,CAAC,CAAC,MAAM;QACN;MAAA;MAEFJ,OAAO,CAACQ,UAAU,CAACZ,SAAS,CAAC;IAC/B;EACF;;EAEA;EACA,MAAMa,eAAe,GACnBC,UAAU,CACVC,gBAAgB,GAAG,CAAC;EAEtBD,UAAU,CAACE,gBAAgB,CAAC,CAACC,KAAY,EAAEC,OAAiB,KAAK;IAC/D,MAAMC,IAAI,GAAGhB,MAAM,CAACiB,SAAS,CAAC,SAASH,KAAK,CAACI,IAAI,EAAE,EAAE;MACnDC,IAAI,EAAE,UAAU;MAChBC,UAAU,EAAE;QACV,CAACzB,mBAAmB,GAAGmB,KAAK,CAACI,IAAI;QACjC,CAACzB,sBAAsB,GAAGqB,KAAK,CAACO,OAAO;QACvC,CAAC3B,yBAAyB,GAAGoB,KAAK,CAACQ,KAAK,IAAI,EAAE;QAC9C,gBAAgB,EAAEP,OAAO,IAAI,KAAK,CAAE;MACtC;IACF,CAAC,CAAC;IACFC,IAAI,CAACO,SAAS,CAAC,OAAO,EAAET,KAAK,CAACO,OAAO,CAAC;IACtCL,IAAI,CAACQ,GAAG,CAAC,CAAC;;IAEV;IACA,IAAIT,OAAO,IAAId,OAAO,IAAIe,IAAI,YAAYpB,IAAI,EAAE;MAC9C,MAAM6B,MAAuB,GAAG;QAC9BC,OAAO,EAAEV,IAAI,CAACU,OAAO;QACrBC,MAAM,EAAEX,IAAI,CAACW,MAAM;QACnBT,IAAI,EAAEF,IAAI,CAACE,IAAI;QACfU,WAAW,EAAEZ,IAAI,CAACY,WAAW;QAC7BC,SAAS,EAAEb,IAAI,CAACa,SAAS,IAAIC,IAAI,CAACC,GAAG,CAAC,CAAC;QACvCX,UAAU,EAAEJ,IAAI,CAACI,UAAqC;QACtDY,MAAM,EAAEhB,IAAI,CAACgB,MAAM;QACnBC,MAAM,EAAEjB,IAAI,CAACiB,MAAM;QACnBC,aAAa,EAAElB,IAAI,CAACkB;MACtB,CAAC;MACDjC,OAAO,CAACkC,OAAO,CAACtC,SAAS,EAAES,IAAI,CAAC8B,SAAS,CAACX,MAAM,CAAC,CAAC;IACpD;IAEAf,eAAe,GAAGI,KAAK,EAAEC,OAAO,CAAC;EACnC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["ATTR_EXCEPTION_MESSAGE","ATTR_EXCEPTION_STACKTRACE","ATTR_EXCEPTION_TYPE","Span","CRASH_KEY","installErrorInstrumentation","params","tracer","storage","exporter","pending","getSync","crashRecord","JSON","parse","export","deleteSync","originalHandler","ErrorUtils","getGlobalHandler","setGlobalHandler","error","isFatal","span","startSpan","name","kind","attributes","message","stack","setStatus","end","record","traceId","spanId","startTimeMs","endTimeMs","Date","now","events","status","statusMessage","setSync","stringify","prevRejectionHandler","globalThis","onunhandledrejection","event","reason","Error","String","call"],"sourceRoot":"../../../src","sources":["instrumentation/errors.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Expo Router instrumentation — optional adapter.
|
|
5
|
+
*
|
|
6
|
+
* This module requires `expo-router` as a peer dependency. It is intentionally
|
|
7
|
+
* NOT re-exported from the main index.ts so that apps without expo-router
|
|
8
|
+
* don't need to install it.
|
|
9
|
+
*
|
|
10
|
+
* Usage (in your root layout, e.g. app/_layout.tsx):
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { useExpoRouterInstrumentation } from 'react-native-otel/src/instrumentation/expo-router';
|
|
13
|
+
* import { otel } from 'react-native-otel';
|
|
14
|
+
*
|
|
15
|
+
* export default function RootLayout() {
|
|
16
|
+
* useExpoRouterInstrumentation(otel.getTracer());
|
|
17
|
+
* return <Slot />;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* The hook creates a new span on every route change and ends the previous one.
|
|
22
|
+
* Requires: expo-router ^3 or ^4 (usePathname / useSegments hooks).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// We use dynamic require so that bundlers can tree-shake this when expo-router
|
|
26
|
+
// is not installed. The try/catch provides a helpful error at runtime.
|
|
27
|
+
let usePathname;
|
|
28
|
+
let useSegments;
|
|
29
|
+
let useEffect;
|
|
30
|
+
let useRef;
|
|
31
|
+
try {
|
|
32
|
+
const expoRouter = require('expo-router');
|
|
33
|
+
usePathname = expoRouter.usePathname;
|
|
34
|
+
useSegments = expoRouter.useSegments;
|
|
35
|
+
const react = require('react');
|
|
36
|
+
useEffect = react.useEffect;
|
|
37
|
+
useRef = react.useRef;
|
|
38
|
+
} catch {
|
|
39
|
+
// expo-router not installed — useExpoRouterInstrumentation will throw.
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* React hook that tracks Expo Router navigation as OTel spans.
|
|
43
|
+
* Each route change ends the previous route span and starts a new one.
|
|
44
|
+
*
|
|
45
|
+
* Must be called inside a component that is rendered within the expo-router
|
|
46
|
+
* provider (e.g. the root layout).
|
|
47
|
+
*/
|
|
48
|
+
export function useExpoRouterInstrumentation(tracer) {
|
|
49
|
+
if (!usePathname || !useSegments || !useEffect || !useRef) {
|
|
50
|
+
throw new Error('[react-native-otel] expo-router is not installed. ' + 'Add it as a dependency to use useExpoRouterInstrumentation.');
|
|
51
|
+
}
|
|
52
|
+
const pathname = usePathname();
|
|
53
|
+
const segments = useSegments();
|
|
54
|
+
const spanRef = useRef(undefined);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
// End the previous route span.
|
|
57
|
+
spanRef.current?.end();
|
|
58
|
+
const routeName = pathname || '/';
|
|
59
|
+
const span = tracer.startSpan(`screen.${routeName}`, {
|
|
60
|
+
kind: 'INTERNAL',
|
|
61
|
+
attributes: {
|
|
62
|
+
'screen.name': routeName,
|
|
63
|
+
'screen.segments': segments.join('/')
|
|
64
|
+
},
|
|
65
|
+
parent: null
|
|
66
|
+
});
|
|
67
|
+
spanRef.current = span;
|
|
68
|
+
return () => {
|
|
69
|
+
span.end();
|
|
70
|
+
spanRef.current = undefined;
|
|
71
|
+
};
|
|
72
|
+
// Re-run when the pathname changes.
|
|
73
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
+
}, [pathname]);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=expo-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["usePathname","useSegments","useEffect","useRef","expoRouter","require","react","useExpoRouterInstrumentation","tracer","Error","pathname","segments","spanRef","undefined","current","end","routeName","span","startSpan","kind","attributes","join","parent"],"sourceRoot":"../../../src","sources":["instrumentation/expo-router.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAIA,WAAuC;AAC3C,IAAIC,WAAyC;AAC7C,IAAIC,SAES;AACb,IAAIC,MAAuD;AAE3D,IAAI;EACF,MAAMC,UAAU,GAAGC,OAAO,CAAC,aAAa,CAGvC;EACDL,WAAW,GAAGI,UAAU,CAACJ,WAAW;EACpCC,WAAW,GAAGG,UAAU,CAACH,WAAW;EAEpC,MAAMK,KAAK,GAAGD,OAAO,CAAC,OAAO,CAG5B;EACDH,SAAS,GAAGI,KAAK,CAACJ,SAAS;EAC3BC,MAAM,GAAGG,KAAK,CAACH,MAAM;AACvB,CAAC,CAAC,MAAM;EACN;AAAA;AAMF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASI,4BAA4BA,CAACC,MAAc,EAAQ;EACjE,IAAI,CAACR,WAAW,IAAI,CAACC,WAAW,IAAI,CAACC,SAAS,IAAI,CAACC,MAAM,EAAE;IACzD,MAAM,IAAIM,KAAK,CACb,oDAAoD,GAClD,6DACJ,CAAC;EACH;EAEA,MAAMC,QAAQ,GAAGV,WAAW,CAAC,CAAC;EAC9B,MAAMW,QAAQ,GAAGV,WAAW,CAAC,CAAC;EAC9B,MAAMW,OAAO,GAAGT,MAAM,CAA8BU,SAAS,CAAC;EAE9DX,SAAS,CAAC,MAAM;IACd;IACAU,OAAO,CAACE,OAAO,EAAEC,GAAG,CAAC,CAAC;IAEtB,MAAMC,SAAS,GAAGN,QAAQ,IAAI,GAAG;IACjC,MAAMO,IAAI,GAAGT,MAAM,CAACU,SAAS,CAAC,UAAUF,SAAS,EAAE,EAAE;MACnDG,IAAI,EAAE,UAAU;MAChBC,UAAU,EAAE;QACV,aAAa,EAAEJ,SAAS;QACxB,iBAAiB,EAAEL,QAAQ,CAACU,IAAI,CAAC,GAAG;MACtC,CAAC;MACDC,MAAM,EAAE;IACV,CAAC,CAAC;IACFV,OAAO,CAACE,OAAO,GAAGG,IAAI;IAEtB,OAAO,MAAM;MACXA,IAAI,CAACF,GAAG,CAAC,CAAC;MACVH,OAAO,CAACE,OAAO,GAAGD,SAAS;IAC7B,CAAC;IACD;IACA;EACF,CAAC,EAAE,CAACH,QAAQ,CAAC,CAAC;AAChB","ignoreList":[]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE } from '@opentelemetry/semantic-conventions';
|
|
4
|
+
import { spanContext } from "../context/span-context.js";
|
|
5
|
+
import { generateSpanId } from "../core/ids.js";
|
|
6
|
+
import { Span } from "../core/span.js";
|
|
7
|
+
// Map from internal ID → active span, mirroring the Axios instrumentation pattern.
|
|
8
|
+
const activeFetchSpans = new Map();
|
|
9
|
+
let originalFetch;
|
|
10
|
+
let installed = false;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Patches globalThis.fetch to create OTel spans for every HTTP request.
|
|
14
|
+
* Call `uninstallFetchInstrumentation()` to restore the original fetch.
|
|
15
|
+
*
|
|
16
|
+
* Options:
|
|
17
|
+
* ignoreUrls – URL substrings that should not be instrumented (e.g. your
|
|
18
|
+
* OTLP endpoint to prevent infinite recursion).
|
|
19
|
+
*/
|
|
20
|
+
export function createFetchInstrumentation(tracer, options) {
|
|
21
|
+
if (installed) {
|
|
22
|
+
return {
|
|
23
|
+
uninstall: () => uninstallFetchInstrumentation()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const ignoreUrls = options?.ignoreUrls ?? [];
|
|
27
|
+
originalFetch = globalThis.fetch;
|
|
28
|
+
installed = true;
|
|
29
|
+
globalThis.fetch = async function instrumentedFetch(input, init) {
|
|
30
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
|
|
31
|
+
|
|
32
|
+
// Skip ignored URLs.
|
|
33
|
+
if (ignoreUrls.some(pattern => url.includes(pattern))) {
|
|
34
|
+
return originalFetch(input, init);
|
|
35
|
+
}
|
|
36
|
+
const method = (init?.method ?? (typeof input !== 'string' && !(input instanceof URL) ? input.method : 'GET')).toUpperCase();
|
|
37
|
+
|
|
38
|
+
// Capture parent context NOW by value — concurrent-safe.
|
|
39
|
+
const currentSpan = spanContext.current();
|
|
40
|
+
const parent = currentSpan?.traceId && currentSpan?.spanId ? {
|
|
41
|
+
traceId: currentSpan.traceId,
|
|
42
|
+
spanId: currentSpan.spanId
|
|
43
|
+
} : null;
|
|
44
|
+
const span = tracer.startSpan(`http.${method} ${url}`, {
|
|
45
|
+
kind: 'CLIENT',
|
|
46
|
+
parent,
|
|
47
|
+
attributes: {
|
|
48
|
+
[ATTR_HTTP_REQUEST_METHOD]: method,
|
|
49
|
+
'http.url': url
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Inject W3C traceparent header for sampled spans.
|
|
54
|
+
let patchedInit = init;
|
|
55
|
+
if (span instanceof Span) {
|
|
56
|
+
const existingHeaders = init?.headers instanceof Headers ? Object.fromEntries(init.headers.entries()) : init?.headers ?? {};
|
|
57
|
+
patchedInit = {
|
|
58
|
+
...init,
|
|
59
|
+
headers: {
|
|
60
|
+
...existingHeaders,
|
|
61
|
+
traceparent: `00-${span.traceId}-${span.spanId}-01`
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const otelId = generateSpanId();
|
|
66
|
+
activeFetchSpans.set(otelId, span);
|
|
67
|
+
try {
|
|
68
|
+
const response = await originalFetch(input, patchedInit);
|
|
69
|
+
span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, response.status);
|
|
70
|
+
if (response.ok) {
|
|
71
|
+
span.setStatus('OK');
|
|
72
|
+
} else {
|
|
73
|
+
span.setStatus('ERROR', `HTTP ${response.status}`);
|
|
74
|
+
}
|
|
75
|
+
span.end();
|
|
76
|
+
activeFetchSpans.delete(otelId);
|
|
77
|
+
return response;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
span.recordException(err);
|
|
80
|
+
span.setStatus('ERROR', err.message);
|
|
81
|
+
span.end();
|
|
82
|
+
activeFetchSpans.delete(otelId);
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
uninstall: () => uninstallFetchInstrumentation()
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function uninstallFetchInstrumentation() {
|
|
91
|
+
if (!installed) return;
|
|
92
|
+
if (originalFetch) {
|
|
93
|
+
globalThis.fetch = originalFetch;
|
|
94
|
+
originalFetch = undefined;
|
|
95
|
+
}
|
|
96
|
+
installed = false;
|
|
97
|
+
activeFetchSpans.clear();
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ATTR_HTTP_REQUEST_METHOD","ATTR_HTTP_RESPONSE_STATUS_CODE","spanContext","generateSpanId","Span","activeFetchSpans","Map","originalFetch","installed","createFetchInstrumentation","tracer","options","uninstall","uninstallFetchInstrumentation","ignoreUrls","globalThis","fetch","instrumentedFetch","input","init","url","URL","toString","some","pattern","includes","method","toUpperCase","currentSpan","current","parent","traceId","spanId","span","startSpan","kind","attributes","patchedInit","existingHeaders","headers","Headers","Object","fromEntries","entries","traceparent","otelId","set","response","setAttribute","status","ok","setStatus","end","delete","err","recordException","message","undefined","clear"],"sourceRoot":"../../../src","sources":["instrumentation/fetch.ts"],"mappings":";;AAAA,SACEA,wBAAwB,EACxBC,8BAA8B,QACzB,qCAAqC;AAE5C,SAASC,WAAW,QAAQ,4BAAyB;AACrD,SAASC,cAAc,QAAQ,gBAAa;AAC5C,SAASC,IAAI,QAAkB,iBAAc;AAU7C;AACA,MAAMC,gBAAgB,GAAG,IAAIC,GAAG,CAA0B,CAAC;AAE3D,IAAIC,aAAuC;AAC3C,IAAIC,SAAS,GAAG,KAAK;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,0BAA0BA,CACxCC,MAAc,EACdC,OAAqC,EACV;EAC3B,IAAIH,SAAS,EAAE;IACb,OAAO;MAAEI,SAAS,EAAEA,CAAA,KAAMC,6BAA6B,CAAC;IAAE,CAAC;EAC7D;EAEA,MAAMC,UAAU,GAAGH,OAAO,EAAEG,UAAU,IAAI,EAAE;EAC5CP,aAAa,GAAGQ,UAAU,CAACC,KAAK;EAChCR,SAAS,GAAG,IAAI;EAEhBO,UAAU,CAACC,KAAK,GAAG,eAAeC,iBAAiBA,CACjDC,KAAwB,EACxBC,IAAkB,EACC;IACnB,MAAMC,GAAG,GACP,OAAOF,KAAK,KAAK,QAAQ,GACrBA,KAAK,GACLA,KAAK,YAAYG,GAAG,GACpBH,KAAK,CAACI,QAAQ,CAAC,CAAC,GACfJ,KAAK,CAAaE,GAAG;;IAE5B;IACA,IAAIN,UAAU,CAACS,IAAI,CAAEC,OAAO,IAAKJ,GAAG,CAACK,QAAQ,CAACD,OAAO,CAAC,CAAC,EAAE;MACvD,OAAOjB,aAAa,CAAEW,KAAK,EAAEC,IAAI,CAAC;IACpC;IAEA,MAAMO,MAAM,GAAG,CACbP,IAAI,EAAEO,MAAM,KACX,OAAOR,KAAK,KAAK,QAAQ,IAAI,EAAEA,KAAK,YAAYG,GAAG,CAAC,GAChDH,KAAK,CAAaQ,MAAM,GACzB,KAAK,CAAC,EACVC,WAAW,CAAC,CAAC;;IAEf;IACA,MAAMC,WAAW,GAAG1B,WAAW,CAAC2B,OAAO,CAAC,CAAC;IACzC,MAAMC,MAAM,GACVF,WAAW,EAAEG,OAAO,IAAIH,WAAW,EAAEI,MAAM,GACvC;MAAED,OAAO,EAAEH,WAAW,CAACG,OAAO;MAAEC,MAAM,EAAEJ,WAAW,CAACI;IAAO,CAAC,GAC5D,IAAI;IAEV,MAAMC,IAAI,GAAGvB,MAAM,CAACwB,SAAS,CAAC,QAAQR,MAAM,IAAIN,GAAG,EAAE,EAAE;MACrDe,IAAI,EAAE,QAAQ;MACdL,MAAM;MACNM,UAAU,EAAE;QACV,CAACpC,wBAAwB,GAAG0B,MAAM;QAClC,UAAU,EAAEN;MACd;IACF,CAAC,CAAC;;IAEF;IACA,IAAIiB,WAAW,GAAGlB,IAAI;IACtB,IAAIc,IAAI,YAAY7B,IAAI,EAAE;MACxB,MAAMkC,eAAe,GACnBnB,IAAI,EAAEoB,OAAO,YAAYC,OAAO,GAC5BC,MAAM,CAACC,WAAW,CAAEvB,IAAI,CAACoB,OAAO,CAAaI,OAAO,CAAC,CAAC,CAAC,GACtDxB,IAAI,EAAEoB,OAAO,IAA2C,CAAC,CAAC;MAEjEF,WAAW,GAAG;QACZ,GAAGlB,IAAI;QACPoB,OAAO,EAAE;UACP,GAAGD,eAAe;UAClBM,WAAW,EAAE,MAAMX,IAAI,CAACF,OAAO,IAAIE,IAAI,CAACD,MAAM;QAChD;MACF,CAAC;IACH;IAEA,MAAMa,MAAM,GAAG1C,cAAc,CAAC,CAAC;IAC/BE,gBAAgB,CAACyC,GAAG,CAACD,MAAM,EAAEZ,IAAI,CAAC;IAElC,IAAI;MACF,MAAMc,QAAQ,GAAG,MAAMxC,aAAa,CAAEW,KAAK,EAAEmB,WAAW,CAAC;MACzDJ,IAAI,CAACe,YAAY,CAAC/C,8BAA8B,EAAE8C,QAAQ,CAACE,MAAM,CAAC;MAClE,IAAIF,QAAQ,CAACG,EAAE,EAAE;QACfjB,IAAI,CAACkB,SAAS,CAAC,IAAI,CAAC;MACtB,CAAC,MAAM;QACLlB,IAAI,CAACkB,SAAS,CAAC,OAAO,EAAE,QAAQJ,QAAQ,CAACE,MAAM,EAAE,CAAC;MACpD;MACAhB,IAAI,CAACmB,GAAG,CAAC,CAAC;MACV/C,gBAAgB,CAACgD,MAAM,CAACR,MAAM,CAAC;MAC/B,OAAOE,QAAQ;IACjB,CAAC,CAAC,OAAOO,GAAG,EAAE;MACZrB,IAAI,CAACsB,eAAe,CAACD,GAAY,CAAC;MAClCrB,IAAI,CAACkB,SAAS,CAAC,OAAO,EAAGG,GAAG,CAAWE,OAAO,CAAC;MAC/CvB,IAAI,CAACmB,GAAG,CAAC,CAAC;MACV/C,gBAAgB,CAACgD,MAAM,CAACR,MAAM,CAAC;MAC/B,MAAMS,GAAG;IACX;EACF,CAAC;EAED,OAAO;IAAE1C,SAAS,EAAEA,CAAA,KAAMC,6BAA6B,CAAC;EAAE,CAAC;AAC7D;AAEA,OAAO,SAASA,6BAA6BA,CAAA,EAAS;EACpD,IAAI,CAACL,SAAS,EAAE;EAChB,IAAID,aAAa,EAAE;IACjBQ,UAAU,CAACC,KAAK,GAAGT,aAAa;IAChCA,aAAa,GAAGkD,SAAS;EAC3B;EACAjD,SAAS,GAAG,KAAK;EACjBH,gBAAgB,CAACqD,KAAK,CAAC,CAAC;AAC1B","ignoreList":[]}
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
import { AppState } from 'react-native';
|
|
4
4
|
import { spanContext } from "../context/span-context.js";
|
|
5
5
|
export function installLifecycleInstrumentation(meter) {
|
|
6
|
+
const foregroundCounter = meter.createCounter('app.foreground_count');
|
|
7
|
+
const backgroundCounter = meter.createCounter('app.background_count');
|
|
6
8
|
AppState.addEventListener('change', state => {
|
|
7
9
|
spanContext.current()?.addEvent(`app.lifecycle.${state}`, {
|
|
8
10
|
'app.state': state
|
|
9
11
|
});
|
|
10
|
-
if (state === '
|
|
12
|
+
if (state === 'active') {
|
|
13
|
+
foregroundCounter.add(1);
|
|
14
|
+
} else if (state === 'background') {
|
|
15
|
+
backgroundCounter.add(1);
|
|
11
16
|
meter.flush();
|
|
12
17
|
}
|
|
13
18
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["AppState","spanContext","installLifecycleInstrumentation","meter","addEventListener","state","current","addEvent","flush"],"sourceRoot":"../../../src","sources":["instrumentation/lifecycle.ts"],"mappings":";;AACA,SAASA,QAAQ,QAAQ,cAAc;AAEvC,SAASC,WAAW,QAAQ,4BAAyB;AAGrD,OAAO,SAASC,+BAA+BA,CAACC,KAAY,EAAQ;
|
|
1
|
+
{"version":3,"names":["AppState","spanContext","installLifecycleInstrumentation","meter","foregroundCounter","createCounter","backgroundCounter","addEventListener","state","current","addEvent","add","flush"],"sourceRoot":"../../../src","sources":["instrumentation/lifecycle.ts"],"mappings":";;AACA,SAASA,QAAQ,QAAQ,cAAc;AAEvC,SAASC,WAAW,QAAQ,4BAAyB;AAGrD,OAAO,SAASC,+BAA+BA,CAACC,KAAY,EAAQ;EAClE,MAAMC,iBAAiB,GAAGD,KAAK,CAACE,aAAa,CAAC,sBAAsB,CAAC;EACrE,MAAMC,iBAAiB,GAAGH,KAAK,CAACE,aAAa,CAAC,sBAAsB,CAAC;EAErEL,QAAQ,CAACO,gBAAgB,CAAC,QAAQ,EAAGC,KAAqB,IAAK;IAC7DP,WAAW,CAACQ,OAAO,CAAC,CAAC,EAAEC,QAAQ,CAAC,iBAAiBF,KAAK,EAAE,EAAE;MACxD,WAAW,EAAEA;IACf,CAAC,CAAC;IAEF,IAAIA,KAAK,KAAK,QAAQ,EAAE;MACtBJ,iBAAiB,CAACO,GAAG,CAAC,CAAC,CAAC;IAC1B,CAAC,MAAM,IAAIH,KAAK,KAAK,YAAY,EAAE;MACjCF,iBAAiB,CAACK,GAAG,CAAC,CAAC,CAAC;MACxBR,KAAK,CAACS,KAAK,CAAC,CAAC;IACf;EACF,CAAC,CAAC;AACJ","ignoreList":[]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Linking } from 'react-native';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a span for every deep link that opens the app, and optionally
|
|
6
|
+
* records push-notification payloads as span events.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```ts
|
|
10
|
+
* const linking = createLinkingInstrumentation(tracer);
|
|
11
|
+
* // later, when shutting down:
|
|
12
|
+
* linking.uninstall();
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export function createLinkingInstrumentation(tracer) {
|
|
16
|
+
const subscription = Linking.addEventListener('url', event => {
|
|
17
|
+
const span = tracer.startSpan('app.deep_link', {
|
|
18
|
+
kind: 'SERVER',
|
|
19
|
+
attributes: {
|
|
20
|
+
'app.link.url': event.url
|
|
21
|
+
},
|
|
22
|
+
parent: null
|
|
23
|
+
});
|
|
24
|
+
span.end();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Record the initial URL if the app was opened via a deep link.
|
|
28
|
+
Linking.getInitialURL().then(url => {
|
|
29
|
+
if (url) {
|
|
30
|
+
const span = tracer.startSpan('app.deep_link.initial', {
|
|
31
|
+
kind: 'SERVER',
|
|
32
|
+
attributes: {
|
|
33
|
+
'app.link.url': url,
|
|
34
|
+
'app.link.initial': true
|
|
35
|
+
},
|
|
36
|
+
parent: null
|
|
37
|
+
});
|
|
38
|
+
span.end();
|
|
39
|
+
}
|
|
40
|
+
}).catch(() => {
|
|
41
|
+
// Ignore — not all platforms support getInitialURL.
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
uninstall: () => {
|
|
45
|
+
subscription.remove();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Record a push-notification payload as a span event on the currently
|
|
52
|
+
* active span, or as a standalone root span when there is no active span.
|
|
53
|
+
*/
|
|
54
|
+
export function recordPushNotification(tracer, payload) {
|
|
55
|
+
const span = tracer.startSpan('app.push_notification', {
|
|
56
|
+
kind: 'SERVER',
|
|
57
|
+
attributes: {
|
|
58
|
+
'messaging.system': 'push'
|
|
59
|
+
},
|
|
60
|
+
parent: null
|
|
61
|
+
});
|
|
62
|
+
span.addEvent('push_notification.received', payload);
|
|
63
|
+
span.end();
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=linking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Linking","createLinkingInstrumentation","tracer","subscription","addEventListener","event","span","startSpan","kind","attributes","url","parent","end","getInitialURL","then","catch","uninstall","remove","recordPushNotification","payload","addEvent"],"sourceRoot":"../../../src","sources":["instrumentation/linking.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,cAAc;AAQtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,4BAA4BA,CAC1CC,MAAc,EACU;EACxB,MAAMC,YAAY,GAAGH,OAAO,CAACI,gBAAgB,CAC3C,KAAK,EACJC,KAAsB,IAAK;IAC1B,MAAMC,IAAI,GAAGJ,MAAM,CAACK,SAAS,CAAC,eAAe,EAAE;MAC7CC,IAAI,EAAE,QAAQ;MACdC,UAAU,EAAE;QACV,cAAc,EAAEJ,KAAK,CAACK;MACxB,CAAC;MACDC,MAAM,EAAE;IACV,CAAC,CAAC;IACFL,IAAI,CAACM,GAAG,CAAC,CAAC;EACZ,CACF,CAAC;;EAED;EACAZ,OAAO,CAACa,aAAa,CAAC,CAAC,CACpBC,IAAI,CAAEJ,GAAG,IAAK;IACb,IAAIA,GAAG,EAAE;MACP,MAAMJ,IAAI,GAAGJ,MAAM,CAACK,SAAS,CAAC,uBAAuB,EAAE;QACrDC,IAAI,EAAE,QAAQ;QACdC,UAAU,EAAE;UACV,cAAc,EAAEC,GAAG;UACnB,kBAAkB,EAAE;QACtB,CAAC;QACDC,MAAM,EAAE;MACV,CAAC,CAAC;MACFL,IAAI,CAACM,GAAG,CAAC,CAAC;IACZ;EACF,CAAC,CAAC,CACDG,KAAK,CAAC,MAAM;IACX;EAAA,CACD,CAAC;EAEJ,OAAO;IACLC,SAAS,EAAEA,CAAA,KAAM;MACfb,YAAY,CAACc,MAAM,CAAC,CAAC;IACvB;EACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CACpChB,MAAc,EACdiB,OAAgC,EAC1B;EACN,MAAMb,IAAI,GAAGJ,MAAM,CAACK,SAAS,CAAC,uBAAuB,EAAE;IACrDC,IAAI,EAAE,QAAQ;IACdC,UAAU,EAAE;MACV,kBAAkB,EAAE;IACtB,CAAC;IACDE,MAAM,EAAE;EACV,CAAC,CAAC;EACFL,IAAI,CAACc,QAAQ,CACX,4BAA4B,EAC5BD,OACF,CAAC;EACDb,IAAI,CAACM,GAAG,CAAC,CAAC;AACZ","ignoreList":[]}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE } from '@opentelemetry/semantic-conventions';
|
|
4
4
|
import { spanContext } from "../context/span-context.js";
|
|
5
5
|
import { generateSpanId } from "../core/ids.js";
|
|
6
|
+
import { Span } from "../core/span.js";
|
|
6
7
|
// Concurrent-safe: parent context is captured by value at request start
|
|
7
8
|
const activeNetworkSpans = new Map();
|
|
8
9
|
|
|
@@ -119,6 +120,40 @@ export function createAxiosInstrumentation(tracer, options) {
|
|
|
119
120
|
const serialized = toJsonAttr(redacted);
|
|
120
121
|
if (serialized) span.setAttribute('http.request.body', serialized);
|
|
121
122
|
}
|
|
123
|
+
|
|
124
|
+
// W3C Trace Context: inject traceparent + tracestate + baggage headers.
|
|
125
|
+
// Only injected for sampled (real) spans — NoopSpan has empty IDs.
|
|
126
|
+
if (span instanceof Span) {
|
|
127
|
+
const additionalHeaders = {
|
|
128
|
+
// flags: 01 = sampled
|
|
129
|
+
traceparent: `00-${span.traceId}-${span.spanId}-01`
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Forward tracestate from the current active span if available.
|
|
133
|
+
const activeSpan = spanContext.current();
|
|
134
|
+
if (activeSpan && 'attributes' in activeSpan) {
|
|
135
|
+
const tracestate = activeSpan.attributes.tracestate;
|
|
136
|
+
if (typeof tracestate === 'string') {
|
|
137
|
+
additionalHeaders.tracestate = tracestate;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Build a W3C baggage header from span attributes prefixed with 'baggage.'.
|
|
142
|
+
const baggageEntries = [];
|
|
143
|
+
for (const [key, val] of Object.entries(span.attributes)) {
|
|
144
|
+
if (key.startsWith('baggage.') && typeof val === 'string') {
|
|
145
|
+
const baggageKey = key.slice('baggage.'.length);
|
|
146
|
+
baggageEntries.push(`${encodeURIComponent(baggageKey)}=${encodeURIComponent(val)}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (baggageEntries.length > 0) {
|
|
150
|
+
additionalHeaders.baggage = baggageEntries.join(',');
|
|
151
|
+
}
|
|
152
|
+
config.headers = {
|
|
153
|
+
...(config.headers ?? {}),
|
|
154
|
+
...additionalHeaders
|
|
155
|
+
};
|
|
156
|
+
}
|
|
122
157
|
activeNetworkSpans.set(otelId, span);
|
|
123
158
|
config.__otelId = otelId;
|
|
124
159
|
return config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ATTR_HTTP_REQUEST_METHOD","ATTR_HTTP_RESPONSE_STATUS_CODE","spanContext","generateSpanId","activeNetworkSpans","Map","leafKeysForSection","section","paths","prefix","result","Set","path","toLowerCase","startsWith","add","slice","length","redactObject","obj","sensitive","size","key","Object","keys","has","normalizeBody","data","undefined","Array","isArray","parsed","JSON","parse","toJsonAttr","stringify","createAxiosInstrumentation","tracer","options","sensitiveKeys","map","k","sensitiveHeaders","sensitiveBody","sensitiveParams","sensitiveResponse","onRequest","config","otelId","method","toUpperCase","url","currentSpan","current","parent","traceId","spanId","span","startSpan","kind","attributes","headers","redacted","serialized","setAttribute","params","reqBody","set","__otelId","onResponse","response","get","status","resBody","setStatus","end","delete","onError","error","errBody","recordException","message","Promise","reject"],"sourceRoot":"../../../src","sources":["instrumentation/network.ts"],"mappings":";;AAAA,SACEA,wBAAwB,EACxBC,8BAA8B,QACzB,qCAAqC;AAE5C,SAASC,WAAW,QAAQ,4BAAyB;AACrD,SAASC,cAAc,QAAQ,gBAAa;
|
|
1
|
+
{"version":3,"names":["ATTR_HTTP_REQUEST_METHOD","ATTR_HTTP_RESPONSE_STATUS_CODE","spanContext","generateSpanId","Span","activeNetworkSpans","Map","leafKeysForSection","section","paths","prefix","result","Set","path","toLowerCase","startsWith","add","slice","length","redactObject","obj","sensitive","size","key","Object","keys","has","normalizeBody","data","undefined","Array","isArray","parsed","JSON","parse","toJsonAttr","stringify","createAxiosInstrumentation","tracer","options","sensitiveKeys","map","k","sensitiveHeaders","sensitiveBody","sensitiveParams","sensitiveResponse","onRequest","config","otelId","method","toUpperCase","url","currentSpan","current","parent","traceId","spanId","span","startSpan","kind","attributes","headers","redacted","serialized","setAttribute","params","reqBody","additionalHeaders","traceparent","activeSpan","tracestate","baggageEntries","val","entries","baggageKey","push","encodeURIComponent","baggage","join","set","__otelId","onResponse","response","get","status","resBody","setStatus","end","delete","onError","error","errBody","recordException","message","Promise","reject"],"sourceRoot":"../../../src","sources":["instrumentation/network.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Capture the module-load timestamp as a proxy for the earliest possible
|
|
4
|
+
// start time. Importing this module before SDK init will give a longer
|
|
5
|
+
// (more accurate) cold-start duration.
|
|
6
|
+
const MODULE_LOAD_TIME_MS = Date.now();
|
|
7
|
+
let startupSpanInstalled = false;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Emits a single `app.startup` span whose duration covers the period from
|
|
11
|
+
* module-load time (or SDK init time if this module was imported later) to
|
|
12
|
+
* the point when this function is called — typically just before rendering
|
|
13
|
+
* the first screen.
|
|
14
|
+
*
|
|
15
|
+
* Call this once, as early as possible in your app entry point, after
|
|
16
|
+
* `otel.init()` completes.
|
|
17
|
+
*
|
|
18
|
+
* Returns the span so callers can add custom attributes before it ends.
|
|
19
|
+
*/
|
|
20
|
+
export function installStartupInstrumentation(tracer) {
|
|
21
|
+
if (startupSpanInstalled) return;
|
|
22
|
+
startupSpanInstalled = true;
|
|
23
|
+
const sdkInitTime = Date.now();
|
|
24
|
+
const startTime = Math.min(MODULE_LOAD_TIME_MS, sdkInitTime);
|
|
25
|
+
const span = tracer.startSpan('app.startup', {
|
|
26
|
+
kind: 'INTERNAL',
|
|
27
|
+
attributes: {
|
|
28
|
+
'app.startup.module_load_ms': MODULE_LOAD_TIME_MS,
|
|
29
|
+
'app.startup.sdk_init_ms': sdkInitTime
|
|
30
|
+
},
|
|
31
|
+
// Force root span — startup is not a child of any screen span.
|
|
32
|
+
parent: null
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Back-date the span start to when the module was loaded.
|
|
36
|
+
if ('startTimeMs' in span) {
|
|
37
|
+
span.startTimeMs = startTime;
|
|
38
|
+
}
|
|
39
|
+
span.end();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Reset for testing purposes only. */
|
|
43
|
+
export function _resetStartupInstrumentation() {
|
|
44
|
+
startupSpanInstalled = false;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=startup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MODULE_LOAD_TIME_MS","Date","now","startupSpanInstalled","installStartupInstrumentation","tracer","sdkInitTime","startTime","Math","min","span","startSpan","kind","attributes","parent","startTimeMs","end","_resetStartupInstrumentation"],"sourceRoot":"../../../src","sources":["instrumentation/startup.ts"],"mappings":";;AAEA;AACA;AACA;AACA,MAAMA,mBAAmB,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;AAEtC,IAAIC,oBAAoB,GAAG,KAAK;;AAEhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,6BAA6BA,CAACC,MAAc,EAAQ;EAClE,IAAIF,oBAAoB,EAAE;EAC1BA,oBAAoB,GAAG,IAAI;EAE3B,MAAMG,WAAW,GAAGL,IAAI,CAACC,GAAG,CAAC,CAAC;EAC9B,MAAMK,SAAS,GAAGC,IAAI,CAACC,GAAG,CAACT,mBAAmB,EAAEM,WAAW,CAAC;EAE5D,MAAMI,IAAI,GAAGL,MAAM,CAACM,SAAS,CAAC,aAAa,EAAE;IAC3CC,IAAI,EAAE,UAAU;IAChBC,UAAU,EAAE;MACV,4BAA4B,EAAEb,mBAAmB;MACjD,yBAAyB,EAAEM;IAC7B,CAAC;IACD;IACAQ,MAAM,EAAE;EACV,CAAC,CAAC;;EAEF;EACA,IAAI,aAAa,IAAIJ,IAAI,EAAE;IACxBA,IAAI,CAA6BK,WAAW,GAAGR,SAAS;EAC3D;EAEAG,IAAI,CAACM,GAAG,CAAC,CAAC;AACZ;;AAEA;AACA,OAAO,SAASC,4BAA4BA,CAAA,EAAS;EACnDd,oBAAoB,GAAG,KAAK;AAC9B","ignoreList":[]}
|
package/lib/module/sdk.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
import { Platform } from 'react-native';
|
|
3
4
|
import { spanContext } from "./context/span-context.js";
|
|
4
5
|
import { setMaxStringLength } from "./core/attributes.js";
|
|
5
6
|
import { OtelLogger } from "./core/log-record.js";
|
|
@@ -8,9 +9,31 @@ import { buildResource } from "./core/resource.js";
|
|
|
8
9
|
import { Tracer } from "./core/tracer.js";
|
|
9
10
|
import { installErrorInstrumentation } from "./instrumentation/errors.js";
|
|
10
11
|
import { installLifecycleInstrumentation } from "./instrumentation/lifecycle.js";
|
|
12
|
+
import { createFetchInstrumentation, uninstallFetchInstrumentation } from "./instrumentation/fetch.js";
|
|
13
|
+
import { setFetchImpl } from "./exporters/wal.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Implement this interface to let the SDK pause/resume flush operations based
|
|
17
|
+
* on network connectivity — without adding a native dependency.
|
|
18
|
+
*
|
|
19
|
+
* Example (using @react-native-community/netinfo):
|
|
20
|
+
* ```ts
|
|
21
|
+
* import NetInfo from '@react-native-community/netinfo';
|
|
22
|
+
*
|
|
23
|
+
* const networkAdapter: NetworkAdapter = {
|
|
24
|
+
* addListener(cb) {
|
|
25
|
+
* const unsub = NetInfo.addEventListener(state => cb(!!state.isConnected));
|
|
26
|
+
* return unsub;
|
|
27
|
+
* },
|
|
28
|
+
* };
|
|
29
|
+
* otel.init({ ..., networkAdapter });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
11
33
|
class OtelSDK {
|
|
12
34
|
userAttributes_ = {};
|
|
13
35
|
sensitiveKeys_ = [];
|
|
36
|
+
isOnline_ = true;
|
|
14
37
|
initialized = false;
|
|
15
38
|
init(config) {
|
|
16
39
|
if (this.initialized) return;
|
|
@@ -22,31 +45,47 @@ class OtelSDK {
|
|
|
22
45
|
this.exporter_ = config.exporter;
|
|
23
46
|
this.metricExporter_ = config.metricExporter;
|
|
24
47
|
this.logExporter_ = config.logExporter;
|
|
48
|
+
|
|
49
|
+
// Auto-detect platform fields when not explicitly provided.
|
|
50
|
+
const osName = config.osName ?? Platform.OS;
|
|
51
|
+
const osVersion = config.osVersion ?? String(Platform.Version);
|
|
25
52
|
this.resource_ = buildResource({
|
|
26
53
|
serviceName: config.serviceName,
|
|
27
54
|
serviceVersion: config.serviceVersion ?? '0.0.0',
|
|
28
|
-
osName
|
|
29
|
-
osVersion
|
|
55
|
+
osName,
|
|
56
|
+
osVersion,
|
|
30
57
|
deviceBrand: config.deviceBrand ?? '',
|
|
31
58
|
deviceModel: config.deviceModel ?? '',
|
|
32
59
|
deviceType: config.deviceType ?? '',
|
|
33
60
|
appBuild: config.appBuild ?? '',
|
|
34
|
-
environment: config.environment ?? 'production'
|
|
61
|
+
environment: config.environment ?? 'production',
|
|
62
|
+
extra: config.resourceAttributes
|
|
35
63
|
});
|
|
36
64
|
|
|
37
|
-
// If any exporter supports resource injection (e.g. OtlpHttp*Exporter),
|
|
38
|
-
// hand it the resource so it can include
|
|
65
|
+
// If any exporter supports resource/storage injection (e.g. OtlpHttp*Exporter),
|
|
66
|
+
// hand it the resource and optional storage so it can include them in payloads
|
|
67
|
+
// and persist undelivered batches across sessions.
|
|
39
68
|
const injectResource = exp => {
|
|
40
69
|
if (exp && typeof exp === 'object' && 'setResource' in exp) {
|
|
41
70
|
exp.setResource(this.resource_);
|
|
42
71
|
}
|
|
43
72
|
};
|
|
73
|
+
const injectStorage = exp => {
|
|
74
|
+
if (config.storage && exp && typeof exp === 'object' && 'setStorage' in exp) {
|
|
75
|
+
exp.setStorage(config.storage);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
44
78
|
injectResource(config.exporter);
|
|
45
79
|
injectResource(config.metricExporter);
|
|
46
80
|
injectResource(config.logExporter);
|
|
81
|
+
injectStorage(config.exporter);
|
|
82
|
+
injectStorage(config.metricExporter);
|
|
83
|
+
injectStorage(config.logExporter);
|
|
47
84
|
this.tracer_ = new Tracer({
|
|
48
85
|
exporter: config.exporter,
|
|
49
86
|
sampleRate: config.sampleRate,
|
|
87
|
+
sampler: config.sampler,
|
|
88
|
+
processors: config.processors,
|
|
50
89
|
getUserAttributes: () => ({
|
|
51
90
|
...this.userAttributes_
|
|
52
91
|
})
|
|
@@ -54,6 +93,27 @@ class OtelSDK {
|
|
|
54
93
|
this.meter_ = new Meter(config.metricExporter);
|
|
55
94
|
this.logger_ = new OtelLogger(config.logExporter);
|
|
56
95
|
|
|
96
|
+
// Wire up connectivity-aware flushing when a NetworkAdapter is supplied.
|
|
97
|
+
if (config.networkAdapter) {
|
|
98
|
+
this.networkUnsubscribe_ = config.networkAdapter.addListener(isConnected => {
|
|
99
|
+
this.isOnline_ = isConnected;
|
|
100
|
+
if (isConnected) {
|
|
101
|
+
// Flush buffered data immediately when coming back online.
|
|
102
|
+
this.flush();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Lock the WAL's fetch to the original (pre-patch) implementation so that
|
|
108
|
+
// OTLP delivery calls are never themselves instrumented — which would cause
|
|
109
|
+
// infinite recursion once fetch instrumentation is installed below.
|
|
110
|
+
setFetchImpl(globalThis.fetch);
|
|
111
|
+
|
|
112
|
+
// Auto-install fetch instrumentation. Wraps globalThis.fetch to create a
|
|
113
|
+
// CLIENT span for every app-level HTTP request. The OTLP exporter is immune
|
|
114
|
+
// because it uses the pre-patch fetch captured above.
|
|
115
|
+
createFetchInstrumentation(this.tracer_);
|
|
116
|
+
|
|
57
117
|
// Check for pending crash span and install global error handler
|
|
58
118
|
installErrorInstrumentation({
|
|
59
119
|
tracer: this.tracer_,
|
|
@@ -101,7 +161,29 @@ class OtelSDK {
|
|
|
101
161
|
}
|
|
102
162
|
return this.logger_;
|
|
103
163
|
}
|
|
164
|
+
|
|
165
|
+
// Flush all buffered spans and metrics without tearing down the SDK.
|
|
166
|
+
// When a NetworkAdapter is configured, flush is a no-op while offline —
|
|
167
|
+
// data stays buffered until connectivity is restored.
|
|
168
|
+
flush() {
|
|
169
|
+
if (!this.isOnline_) return;
|
|
170
|
+
this.meter_?.flush();
|
|
171
|
+
const flushExporter = exp => {
|
|
172
|
+
if (exp && typeof exp === 'object' && 'flush' in exp) {
|
|
173
|
+
exp.flush();
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
flushExporter(this.exporter_);
|
|
177
|
+
flushExporter(this.logExporter_);
|
|
178
|
+
}
|
|
104
179
|
async shutdown() {
|
|
180
|
+
// Remove connectivity listener.
|
|
181
|
+
this.networkUnsubscribe_?.();
|
|
182
|
+
this.networkUnsubscribe_ = undefined;
|
|
183
|
+
|
|
184
|
+
// Restore the original fetch.
|
|
185
|
+
uninstallFetchInstrumentation();
|
|
186
|
+
|
|
105
187
|
// End active screen span
|
|
106
188
|
const current = spanContext.current();
|
|
107
189
|
if (current) {
|