@mukhy/mtn-telemetry-sdk 1.0.0
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/.github/workflows/node.js.yml +81 -0
- package/.github/workflows/npm-publish-github-packages.yml +53 -0
- package/README.md +146 -0
- package/__test__/demo-test.js +3 -0
- package/__test__/test-runner.js +54 -0
- package/__test__/test.js +5 -0
- package/apps/.gradle/8.9/checksums/checksums.lock +0 -0
- package/apps/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/apps/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/apps/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/apps/.gradle/8.9/gc.properties +0 -0
- package/apps/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/apps/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/apps/.gradle/vcs-1/gc.properties +0 -0
- package/apps/build.gradle +14 -0
- package/dist/business.d.ts +26 -0
- package/dist/business.js +79 -0
- package/dist/context.d.ts +3 -0
- package/dist/context.js +27 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +45 -0
- package/dist/instrumentations/app-state.d.ts +7 -0
- package/dist/instrumentations/app-state.js +58 -0
- package/dist/instrumentations/fetch.d.ts +1 -0
- package/dist/instrumentations/fetch.js +41 -0
- package/dist/instrumentations/react-nav.d.ts +1 -0
- package/dist/instrumentations/react-nav.js +23 -0
- package/dist/providers.d.ts +13 -0
- package/dist/providers.js +87 -0
- package/dist/resource.d.ts +2 -0
- package/dist/resource.js +32 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.js +2 -0
- package/package.json +52 -0
- package/src/business.tsx +92 -0
- package/src/context.js +74 -0
- package/src/context.ts +24 -0
- package/src/index.js +127 -0
- package/src/index.ts +47 -0
- package/src/instrumentations/app-state.js +70 -0
- package/src/instrumentations/app-state.ts +64 -0
- package/src/instrumentations/fetch.js +106 -0
- package/src/instrumentations/fetch.ts +41 -0
- package/src/instrumentations/react-nav.js +73 -0
- package/src/instrumentations/react-nav.ts +23 -0
- package/src/providers.js +83 -0
- package/src/providers.ts +95 -0
- package/src/resource.js +22 -0
- package/src/resource.ts +40 -0
- package/src/types.js +2 -0
- package/src/types.ts +22 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Build, Test & Publish MTN Telemetry SDK
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ "master" ]
|
|
6
|
+
release:
|
|
7
|
+
types: [created]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
node-version: [20.19.4, 22.x]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout repository
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Remove package-lock.json (avoid warnings)
|
|
22
|
+
run: |
|
|
23
|
+
if [ -f package-lock.json ]; then
|
|
24
|
+
rm package-lock.json
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
- name: Setup Node.js
|
|
28
|
+
uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: ${{ matrix.node-version }}
|
|
31
|
+
cache: 'yarn'
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: yarn install --frozen-lockfile
|
|
35
|
+
|
|
36
|
+
- name: Build SDK
|
|
37
|
+
run: yarn run clean && yarn run build
|
|
38
|
+
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: yarn run test
|
|
41
|
+
|
|
42
|
+
publish:
|
|
43
|
+
needs: build
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
permissions:
|
|
46
|
+
contents: read
|
|
47
|
+
packages: write
|
|
48
|
+
|
|
49
|
+
steps:
|
|
50
|
+
- name: Checkout repository
|
|
51
|
+
uses: actions/checkout@v4
|
|
52
|
+
|
|
53
|
+
- name: Setup Node.js for GitHub Packages
|
|
54
|
+
uses: actions/setup-node@v4
|
|
55
|
+
with:
|
|
56
|
+
node-version: 20
|
|
57
|
+
registry-url: https://npm.pkg.github.com/
|
|
58
|
+
scope: '@triplemcoder'
|
|
59
|
+
|
|
60
|
+
- name: Install dependencies
|
|
61
|
+
run: yarn install --frozen-lockfile
|
|
62
|
+
|
|
63
|
+
- name: Ensure package is public
|
|
64
|
+
run: npm pkg set publishConfig.access=public
|
|
65
|
+
|
|
66
|
+
- name: Check if version is new
|
|
67
|
+
id: version-check
|
|
68
|
+
run: |
|
|
69
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
70
|
+
echo "PACKAGE_VERSION=$VERSION" >> $GITHUB_ENV
|
|
71
|
+
# Attempt to fetch package info
|
|
72
|
+
if npm info @triplemcoder14/mtn-telemetry-sdk@$VERSION >/dev/null 2>&1; then
|
|
73
|
+
echo "Version $VERSION already exists, skipping publish"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
- name: Publish to GitHub Packages
|
|
78
|
+
if: success()
|
|
79
|
+
run: npm publish
|
|
80
|
+
env:
|
|
81
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Publish MTN Telemetry SDK to GitHub Packages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [created]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout repository
|
|
12
|
+
uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Setup Node.js
|
|
15
|
+
uses: actions/setup-node@v4
|
|
16
|
+
with:
|
|
17
|
+
node-version: 20
|
|
18
|
+
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: npm ci
|
|
21
|
+
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: npm test
|
|
24
|
+
|
|
25
|
+
publish:
|
|
26
|
+
needs: build
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
permissions:
|
|
29
|
+
contents: read
|
|
30
|
+
packages: write
|
|
31
|
+
steps:
|
|
32
|
+
- name: Checkout repository
|
|
33
|
+
uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Setup Node.js for GitHub Packages
|
|
36
|
+
uses: actions/setup-node@v4
|
|
37
|
+
with:
|
|
38
|
+
node-version: 20
|
|
39
|
+
registry-url: https://npm.pkg.github.com/
|
|
40
|
+
scope: '@triplemcoder14' # Replace with your GitHub username or org
|
|
41
|
+
|
|
42
|
+
- name: Install dependencies
|
|
43
|
+
run: npm ci
|
|
44
|
+
|
|
45
|
+
- name: Make package public
|
|
46
|
+
run: |
|
|
47
|
+
# Ensure package.json has a valid public package
|
|
48
|
+
npm pkg set publishConfig.access=public
|
|
49
|
+
|
|
50
|
+
- name: Publish to GitHub Packages
|
|
51
|
+
run: npm publish
|
|
52
|
+
env:
|
|
53
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
### MTN Telemetry SDK
|
|
2
|
+
|
|
3
|
+
#### MTN Telemetry SDK is a lightweight OpenTelemetry wrapper for React and React Native applications, designed to help developers collect traces, metrics, and logs with minimal configuration
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* Easy initialization for React and React Native apps
|
|
8
|
+
* Automatic instrumentation for:
|
|
9
|
+
* Navigation
|
|
10
|
+
* API requests / network calls
|
|
11
|
+
* Supports custom spans and metrics
|
|
12
|
+
* TypeScript-ready, with type definitions
|
|
13
|
+
* Compatible with GitHub Packages for easy installation
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
#### Installation
|
|
17
|
+
|
|
18
|
+
Install via npm:
|
|
19
|
+
|
|
20
|
+
``npm install @triplemcoder14/mtn-telemetry-sdk
|
|
21
|
+
``
|
|
22
|
+
|
|
23
|
+
or via yarn:
|
|
24
|
+
|
|
25
|
+
``yarn add @triplemcoder14/mtn-telemetry-sdk
|
|
26
|
+
``
|
|
27
|
+
|
|
28
|
+
**Make sure your project uses React >=18.0.0 and React Native >=0.72.0.**
|
|
29
|
+
|
|
30
|
+
#### Getting Started
|
|
31
|
+
|
|
32
|
+
1. Initialize the SDK
|
|
33
|
+
|
|
34
|
+
Create a file like src/telemetry/initTelemetry.ts:
|
|
35
|
+
|
|
36
|
+
```import { MTNOTel } from 'mtn-telemetry-sdk';
|
|
37
|
+
import { OTELRNOptions } from 'mtn-telemetry-sdk/dist/types';
|
|
38
|
+
|
|
39
|
+
export function initTelemetry() {
|
|
40
|
+
const options: OTELRNOptions = {
|
|
41
|
+
serviceName: 'demo-app',
|
|
42
|
+
// Optional: exporter endpoint, environment, etc.
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
MTNOTel.init(options);
|
|
46
|
+
console.log('Telemetry initialized');
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. Integrate in React / React Native App
|
|
51
|
+
In your root component (e.g., App.tsx):
|
|
52
|
+
|
|
53
|
+
```import React, { useEffect } from 'react';
|
|
54
|
+
import { initTelemetry } from './telemetry/initTelemetry';
|
|
55
|
+
import { NavigationContainer } from '@react-navigation/native';
|
|
56
|
+
import MainStack from './screens/MainStack';
|
|
57
|
+
|
|
58
|
+
export default function App() {
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
initTelemetry();
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<NavigationContainer>
|
|
65
|
+
<MainStack />
|
|
66
|
+
</NavigationContainer>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. Creating Custom Spans
|
|
72
|
+
|
|
73
|
+
You can measure the performance of any async operation:
|
|
74
|
+
|
|
75
|
+
```import { startSpan, endSpan } from 'mtn-telemetry-sdk';
|
|
76
|
+
|
|
77
|
+
async function fetchUserData() {
|
|
78
|
+
const span = startSpan('fetch_user_data', { url: '/users' });
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch('/users');
|
|
81
|
+
const data = await response.json();
|
|
82
|
+
return data;
|
|
83
|
+
} finally {
|
|
84
|
+
endSpan(span);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
4. Automatic Navigation Instrumentation (Optional)
|
|
90
|
+
If using React Navigation:
|
|
91
|
+
|
|
92
|
+
```const navigationRef = useNavigationContainerRef();
|
|
93
|
+
|
|
94
|
+
<NavigationContainer
|
|
95
|
+
ref={navigationRef}
|
|
96
|
+
onStateChange={() => {
|
|
97
|
+
const span = startSpan('navigation_change');
|
|
98
|
+
endSpan(span);
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
<MainStack />
|
|
102
|
+
</NavigationContainer>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Configuration Options
|
|
107
|
+
|
|
108
|
+
The ``OTELRNOptions`` object can include:
|
|
109
|
+
|
|
110
|
+
| Option | Type | Description |
|
|
111
|
+
| ------------- | ------ | --------------------------------------------- |
|
|
112
|
+
| `serviceName` | string | Name of the service/app |
|
|
113
|
+
| `environment` | string | Optional environment (prod/dev) |
|
|
114
|
+
| `endpoint` | string | Optional OTLP/collector endpoint |
|
|
115
|
+
| `exporter` | string | Optional exporter type (OTLP HTTP/gRPC, etc.) |
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
Publishing & Versioning
|
|
119
|
+
* The SDK is hosted on GitHub Packages:
|
|
120
|
+
``npm install @triplemcoder/mtn-telemetry-sdk``
|
|
121
|
+
|
|
122
|
+
Always increment ``version`` in ``package.json`` before publishing.
|
|
123
|
+
|
|
124
|
+
Contributing
|
|
125
|
+
1. Fork the repo
|
|
126
|
+
2. Create a feature branch:
|
|
127
|
+
``git checkout -b feature/my-feature``
|
|
128
|
+
3. Commit changes
|
|
129
|
+
4. Push branch and open a PR
|
|
130
|
+
|
|
131
|
+
Example Usage in React Native
|
|
132
|
+
|
|
133
|
+
```import { MTNOTel } from 'mtn-telemetry-sdk';
|
|
134
|
+
|
|
135
|
+
MTNOTel.init({
|
|
136
|
+
serviceName: 'chequebase',
|
|
137
|
+
environment: 'production'
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Custom span for API request
|
|
141
|
+
const span = MTNOTel.startSpan('fetch_users');
|
|
142
|
+
// ...fetch API
|
|
143
|
+
MTNOTel.endSpan(span);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// --- this mocks react-native-device-info ---
|
|
2
|
+
require.cache[require.resolve('react-native-device-info')] = {
|
|
3
|
+
exports: {
|
|
4
|
+
getVersion: () => '1.0.0',
|
|
5
|
+
getManufacturerSync: () => 'MockBrand',
|
|
6
|
+
getModel: () => 'MockPhone',
|
|
7
|
+
getSystemName: () => 'MockOS',
|
|
8
|
+
getSystemVersion: () => '1.0',
|
|
9
|
+
getBundleId: () => 'com.mock.app',
|
|
10
|
+
getBuildNumber: () => '100',
|
|
11
|
+
isEmulatorSync: () => true,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
require.cache[require.resolve('react-native')] = {
|
|
16
|
+
exports: {
|
|
17
|
+
Platform: { OS: 'ios', Version: '1.0.0', select: (obj) => obj.ios },
|
|
18
|
+
NativeModules: {},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// --- import the built sdk ---
|
|
23
|
+
const { MTNOTel } = require('../dist/index');
|
|
24
|
+
|
|
25
|
+
// --- Run the SDK init + shutdown test ---
|
|
26
|
+
(async () => {
|
|
27
|
+
try {
|
|
28
|
+
const sdk = MTNOTel.init({
|
|
29
|
+
serviceName: 'mtn-test-service',
|
|
30
|
+
otlp: {
|
|
31
|
+
tracesUrl: 'http://localhost:4318/v1/traces',
|
|
32
|
+
metricsUrl: 'http://localhost:4318/v1/metrics',
|
|
33
|
+
headers: {},
|
|
34
|
+
},
|
|
35
|
+
environment: 'dev',
|
|
36
|
+
release: '1.0.0',
|
|
37
|
+
enableFetch: true,
|
|
38
|
+
enableNavigation: false,
|
|
39
|
+
enableAppState: true,
|
|
40
|
+
samplingRatio: 1.0,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(' MTNOTel SDK initialized successfully.');
|
|
44
|
+
|
|
45
|
+
// simulate app running
|
|
46
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
47
|
+
|
|
48
|
+
await sdk.flushAndShutdown();
|
|
49
|
+
console.log(' SDK flushed and shut down gracefully.');
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.error(' Test failed:', err);
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
|
package/__test__/test.js
ADDED
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
android {
|
|
2
|
+
namespace "com.mtntelemetrydemo"
|
|
3
|
+
compileSdkVersion rootProject.ext.compileSdkVersion
|
|
4
|
+
|
|
5
|
+
defaultConfig {
|
|
6
|
+
applicationId "com.mtntelemetrydemo"
|
|
7
|
+
minSdkVersion rootProject.ext.minSdkVersion
|
|
8
|
+
targetSdkVersion rootProject.ext.targetSdkVersion
|
|
9
|
+
versionCode 1
|
|
10
|
+
versionName "1.0"
|
|
11
|
+
}
|
|
12
|
+
...
|
|
13
|
+
}
|
|
14
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PressableProps } from 'react-native';
|
|
3
|
+
/**
|
|
4
|
+
* BusinessTracer — captures business journeys and steps
|
|
5
|
+
*/
|
|
6
|
+
export declare class BusinessTracer {
|
|
7
|
+
private static currentJourney?;
|
|
8
|
+
/**
|
|
9
|
+
* Start a business journey (e.g. "UserOnboarding", "PurchaseFlow")
|
|
10
|
+
*/
|
|
11
|
+
static start(journeyName: string, attrs?: Record<string, any>): void;
|
|
12
|
+
/**
|
|
13
|
+
* Record a business step within a journey (e.g. "PaymentAuthorized")
|
|
14
|
+
*/
|
|
15
|
+
static step(stepName: string, attrs?: Record<string, any>): void;
|
|
16
|
+
/**
|
|
17
|
+
* Complete a business journey
|
|
18
|
+
*/
|
|
19
|
+
static complete(attrs?: Record<string, any>): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* TrackedPressable — wraps a Pressable and records user interactions as steps
|
|
23
|
+
*/
|
|
24
|
+
export declare function TrackedPressable({ onPress, accessibilityLabel, children, ...rest }: PressableProps & {
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
}): import("react/jsx-runtime").JSX.Element;
|
package/dist/business.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BusinessTracer = void 0;
|
|
4
|
+
exports.TrackedPressable = TrackedPressable;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_native_1 = require("react-native");
|
|
7
|
+
const api_1 = require("@opentelemetry/api");
|
|
8
|
+
/**
|
|
9
|
+
* BusinessTracer — captures business journeys and steps
|
|
10
|
+
*/
|
|
11
|
+
class BusinessTracer {
|
|
12
|
+
/**
|
|
13
|
+
* Start a business journey (e.g. "UserOnboarding", "PurchaseFlow")
|
|
14
|
+
*/
|
|
15
|
+
static start(journeyName, attrs = {}) {
|
|
16
|
+
const tracer = api_1.trace.getTracer('mtn-sdk:business');
|
|
17
|
+
const span = tracer.startSpan(`Journey ${journeyName}`, {
|
|
18
|
+
kind: api_1.SpanKind.INTERNAL,
|
|
19
|
+
attributes: {
|
|
20
|
+
'business.journey': journeyName,
|
|
21
|
+
...attrs,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
this.currentJourney = { name: journeyName, startTime: Date.now() };
|
|
25
|
+
span.end(); // parent marker span; steps are separate child spans
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Record a business step within a journey (e.g. "PaymentAuthorized")
|
|
29
|
+
*/
|
|
30
|
+
static step(stepName, attrs = {}) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const tracer = api_1.trace.getTracer('mtn-sdk:business');
|
|
33
|
+
const journey = (_b = (_a = this.currentJourney) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown';
|
|
34
|
+
const span = tracer.startSpan(`Step ${stepName}`, {
|
|
35
|
+
kind: api_1.SpanKind.INTERNAL,
|
|
36
|
+
attributes: {
|
|
37
|
+
'business.journey': journey,
|
|
38
|
+
'business.step': stepName,
|
|
39
|
+
...attrs,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
span.end();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Complete a business journey
|
|
46
|
+
*/
|
|
47
|
+
static complete(attrs = {}) {
|
|
48
|
+
var _a, _b;
|
|
49
|
+
const tracer = api_1.trace.getTracer('mtn-sdk:business');
|
|
50
|
+
const journey = (_b = (_a = this.currentJourney) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown';
|
|
51
|
+
const dur = this.currentJourney
|
|
52
|
+
? Date.now() - this.currentJourney.startTime
|
|
53
|
+
: undefined;
|
|
54
|
+
const span = tracer.startSpan(`Journey ${journey} Complete`, {
|
|
55
|
+
kind: api_1.SpanKind.INTERNAL,
|
|
56
|
+
attributes: {
|
|
57
|
+
'business.journey': journey,
|
|
58
|
+
'business.completed': true,
|
|
59
|
+
'business.duration_ms': dur,
|
|
60
|
+
...attrs,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
span.end();
|
|
64
|
+
this.currentJourney = undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.BusinessTracer = BusinessTracer;
|
|
68
|
+
/**
|
|
69
|
+
* TrackedPressable — wraps a Pressable and records user interactions as steps
|
|
70
|
+
*/
|
|
71
|
+
function TrackedPressable({ onPress, accessibilityLabel, children, ...rest }) {
|
|
72
|
+
const label = accessibilityLabel ||
|
|
73
|
+
(typeof children === 'string' ? children : 'pressable');
|
|
74
|
+
const handlePress = (e) => {
|
|
75
|
+
BusinessTracer.step(`tap:${label}`);
|
|
76
|
+
onPress === null || onPress === void 0 ? void 0 : onPress(e);
|
|
77
|
+
};
|
|
78
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { ...rest, onPress: handlePress, children: children }));
|
|
79
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { SpanKind } from '@opentelemetry/api';
|
|
2
|
+
export declare function startActiveSpan<T>(name: string, fn: (span: any) => Promise<T> | T, kind?: SpanKind): Promise<T>;
|
|
3
|
+
export declare function withParent<T>(parentContext: import("@opentelemetry/api").Context | undefined, fn: () => T): T;
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startActiveSpan = startActiveSpan;
|
|
4
|
+
exports.withParent = withParent;
|
|
5
|
+
const api_1 = require("@opentelemetry/api");
|
|
6
|
+
function startActiveSpan(name, fn, kind = api_1.SpanKind.INTERNAL) {
|
|
7
|
+
const tracer = api_1.trace.getTracer('mtn-sdk');
|
|
8
|
+
return tracer.startActiveSpan(name, { kind }, async (span) => {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
try {
|
|
11
|
+
const result = await fn(span);
|
|
12
|
+
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
(_a = span.recordException) === null || _a === void 0 ? void 0 : _a.call(span, err);
|
|
17
|
+
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: String((_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err) });
|
|
18
|
+
throw err;
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
span.end();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function withParent(parentContext = api_1.context.active(), fn) {
|
|
26
|
+
return api_1.context.with(parentContext, fn);
|
|
27
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MTNOTel = void 0;
|
|
4
|
+
const providers_1 = require("./providers");
|
|
5
|
+
const resource_1 = require("./resource");
|
|
6
|
+
const fetch_1 = require("./instrumentations/fetch");
|
|
7
|
+
const react_nav_1 = require("./instrumentations/react-nav");
|
|
8
|
+
const app_state_1 = require("./instrumentations/app-state");
|
|
9
|
+
const api_1 = require("@opentelemetry/api");
|
|
10
|
+
class MTNOTel {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.shutdownFns = [];
|
|
13
|
+
}
|
|
14
|
+
static async init(opts) {
|
|
15
|
+
if (MTNOTel._instance)
|
|
16
|
+
return MTNOTel._instance;
|
|
17
|
+
// await and async resource builder
|
|
18
|
+
const resource = await (0, resource_1.buildResource)(opts);
|
|
19
|
+
const { sdk, shutdown } = (0, providers_1.buildProviders)({ ...opts, resource });
|
|
20
|
+
const instance = new MTNOTel();
|
|
21
|
+
instance.shutdownFns.push(shutdown);
|
|
22
|
+
// using otel api to get global tracer and meter
|
|
23
|
+
const tracer = api_1.trace.getTracer(opts.serviceName);
|
|
24
|
+
const meter = api_1.metrics.getMeter(opts.serviceName);
|
|
25
|
+
// conditionally install instrumentation
|
|
26
|
+
if (opts.enableFetch) {
|
|
27
|
+
instance.shutdownFns.push((0, fetch_1.installFetchInstrumentation)(tracer));
|
|
28
|
+
}
|
|
29
|
+
if (opts.enableNavigation) {
|
|
30
|
+
instance.shutdownFns.push((0, react_nav_1.installReactNavigationInstrumentation)(tracer));
|
|
31
|
+
}
|
|
32
|
+
if (opts.enableAppState) {
|
|
33
|
+
instance.shutdownFns.push((0, app_state_1.installAppStateInstrumentation)(tracer, meter));
|
|
34
|
+
}
|
|
35
|
+
MTNOTel._instance = instance;
|
|
36
|
+
return instance;
|
|
37
|
+
}
|
|
38
|
+
async flushAndShutdown() {
|
|
39
|
+
for (const fn of this.shutdownFns) {
|
|
40
|
+
await fn();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.MTNOTel = MTNOTel;
|
|
45
|
+
MTNOTel._instance = null;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Meter } from '@opentelemetry/api';
|
|
2
|
+
/**
|
|
3
|
+
* instruments react native appstate to record when the app
|
|
4
|
+
* triplemcoder14
|
|
5
|
+
* enters foreground/background and emits spans + metrics.
|
|
6
|
+
*/
|
|
7
|
+
export declare function installAppStateInstrumentation(_tracerProvider: any, meter: Meter): () => Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installAppStateInstrumentation = installAppStateInstrumentation;
|
|
4
|
+
const react_native_1 = require("react-native");
|
|
5
|
+
const api_1 = require("@opentelemetry/api");
|
|
6
|
+
/**
|
|
7
|
+
* instruments react native appstate to record when the app
|
|
8
|
+
* triplemcoder14
|
|
9
|
+
* enters foreground/background and emits spans + metrics.
|
|
10
|
+
*/
|
|
11
|
+
function installAppStateInstrumentation(_tracerProvider, meter) {
|
|
12
|
+
const tracer = api_1.trace.getTracer('mtn-sdk:appstate');
|
|
13
|
+
const fgCounter = meter.createCounter('app.foreground.count');
|
|
14
|
+
const bgCounter = meter.createCounter('app.background.count');
|
|
15
|
+
let lastState = react_native_1.AppState.currentState;
|
|
16
|
+
const sub = react_native_1.AppState.addEventListener('change', (state) => {
|
|
17
|
+
if (state === 'active' && lastState !== 'active') {
|
|
18
|
+
fgCounter.add(1);
|
|
19
|
+
tracer.startActiveSpan('App Foreground', { kind: api_1.SpanKind.INTERNAL }, (span) => span.end());
|
|
20
|
+
}
|
|
21
|
+
else if ((state === 'background' || state === 'inactive') && lastState === 'active') {
|
|
22
|
+
bgCounter.add(1);
|
|
23
|
+
tracer.startActiveSpan('App Background', { kind: api_1.SpanKind.INTERNAL }, (span) => span.end());
|
|
24
|
+
}
|
|
25
|
+
lastState = state;
|
|
26
|
+
});
|
|
27
|
+
// return a cleanup function
|
|
28
|
+
return async () => {
|
|
29
|
+
sub.remove();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// import { AppState } from 'react-native';
|
|
33
|
+
// import { trace, SpanKind } from '@opentelemetry/api';
|
|
34
|
+
// import type { MeterProvider } from '@opentelemetry/sdk-metrics';
|
|
35
|
+
//
|
|
36
|
+
//
|
|
37
|
+
// export function installAppStateInstrumentation(_tracerProvider: any, meterProvider: MeterProvider) {
|
|
38
|
+
// const tracer = trace.getTracer('mtn-sdk:appstate');
|
|
39
|
+
// const meter = meterProvider.getMeter('mtn-sdk:appstate');
|
|
40
|
+
// const fgCounter = meter.createCounter('app.foreground.count');
|
|
41
|
+
// const bgCounter = meter.createCounter('app.background.count');
|
|
42
|
+
//
|
|
43
|
+
//
|
|
44
|
+
// let lastState = AppState.currentState;
|
|
45
|
+
// const sub = AppState.addEventListener('change', (state) => {
|
|
46
|
+
// if (state === 'active' && lastState !== 'active') {
|
|
47
|
+
// fgCounter.add(1);
|
|
48
|
+
// tracer.startActiveSpan('App Foreground', { kind: SpanKind.INTERNAL }, (span) => span.end());
|
|
49
|
+
// } else if ((state === 'background' || state === 'inactive') && lastState === 'active') {
|
|
50
|
+
// bgCounter.add(1);
|
|
51
|
+
// tracer.startActiveSpan('App Background', { kind: SpanKind.INTERNAL }, (span) => span.end());
|
|
52
|
+
// }
|
|
53
|
+
// lastState = state as any;
|
|
54
|
+
// });
|
|
55
|
+
//
|
|
56
|
+
//
|
|
57
|
+
// return async () => { sub.remove(); };
|
|
58
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function installFetchInstrumentation(_tracerProvider: any): () => Promise<void>;
|