Skip to content

Commit 333d350

Browse files
jpmunzsvrnmtiffany76
authored
[Demo] Add info about React Native app (#5704)
Co-authored-by: Severin Neumann <[email protected]> Co-authored-by: Tiffany Hrabusa <[email protected]>
1 parent f765d42 commit 333d350

File tree

6 files changed

+162
-2
lines changed

6 files changed

+162
-2
lines changed

.cspell/en-words.txt

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ quantile
108108
quantiles
109109
quarkus
110110
quoteservice
111+
react-native-app
111112
recommendationservice
112113
redis
113114
relref

content/en/docs/demo/_index.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ here.
2929
| C++ | | | [Currency Service](services/currency/) |
3030
| Go | | [Checkout Service](services/checkout/), [Product Catalog Service](services/product-catalog/) | [Checkout Service](services/checkout/), [Product Catalog Service](services/product-catalog/) |
3131
| Java | [Ad Service](services/ad/) | | [Ad Service](services/ad/) |
32-
| JavaScript | | [Frontend](services/frontend/) | [Frontend](services/frontend/), [Payment Service](services/payment/) |
32+
| JavaScript | | | [Payment Service](services/payment/) |
33+
| TypeScript | | [Frontend](services/frontend/), [React Native App](services/react-native-app/) | [Frontend](services/frontend/) |
3334
| Kotlin | | [Fraud Detection Service](services/fraud-detection/) | |
3435
| PHP | | [Quote Service](services/quote/) | [Quote Service](services/quote/) |
3536
| Python | [Recommendation Service](services/recommendation/) | | [Recommendation Service](services/recommendation/) |
@@ -54,6 +55,7 @@ found here:
5455
- [Recommendation Service](services/recommendation/)
5556
- [Shipping Service](services/shipping/)
5657
- [Image Provider Service](services/imageprovider/)
58+
- [React Native App](services/react-native-app/)
5759

5860
## Scenarios
5961

content/en/docs/demo/architecture.md

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ quoteservice(Quote Service):::php
3232
recommendationservice(Recommendation Service):::python
3333
shippingservice(Shipping Service):::rust
3434
queue[(queue<br/>&#40Kafka&#41)]:::java
35+
react-native-app(React Native App):::typescript
3536
3637
adservice ---->|gRPC| flagd
3738
@@ -73,6 +74,8 @@ recommendationservice -->|gRPC| productcatalogservice
7374
recommendationservice -->|gRPC| flagd
7475
7576
shippingservice -->|HTTP| quoteservice
77+
78+
react-native-app -->|HTTP| frontendproxy
7679
end
7780
7881
classDef dotnet fill:#178600,color:white;

content/en/docs/demo/services/_index.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ To visualize request flows, see the [Service Diagram](../architecture/).
1515
| [currencyservice](currency/) | C++ | Converts one money amount to another currency. Uses real values fetched from European Central Bank. It's the highest QPS service. |
1616
| [emailservice](email/) | Ruby | Sends users an order confirmation email (mock/). |
1717
| [frauddetectionservice](fraud-detection/) | Kotlin | Analyzes incoming orders and detects fraud attempts (mock/). |
18-
| [frontend](frontend/) | JavaScript | Exposes an HTTP server to serve the website. Does not require sign up / login and generates session IDs for all users automatically. |
18+
| [frontend](frontend/) | TypeScript | Exposes an HTTP server to serve the website. Does not require sign up / login and generates session IDs for all users automatically. |
1919
| [loadgenerator](load-generator/) | Python/Locust | Continuously sends requests imitating realistic user shopping flows to the frontend. |
2020
| [paymentservice](payment/) | JavaScript | Charges the given credit card info (mock/) with the given amount and returns a transaction ID. |
2121
| [productcatalogservice](product-catalog/) | Go | Provides the list of products from a JSON file and ability to search products and get individual products. |
2222
| [quoteservice](quote/) | PHP | Calculates the shipping costs, based on the number of items to be shipped. |
2323
| [recommendationservice](recommendation/) | Python | Recommends other products based on what's given in the cart. |
2424
| [shippingservice](shipping/) | Rust | Gives shipping cost estimates based on the shopping cart. Ships items to the given address (mock/). |
25+
| [react-native-app](react-native-app/) | TypeScript | React Native mobile application that provides a UI on top of the shopping services. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
title: React Native App
3+
cSpell:ignore: typeof
4+
---
5+
6+
The React Native app provides a mobile UI for users on Android and iOS devices
7+
to interact with the demo's services. It is built with
8+
[Expo](https://docs.expo.dev/get-started/introduction/) and uses Expo's
9+
file-based routing to layout the screens for the app.
10+
11+
[React Native app source](https://github.com/open-telemetry/opentelemetry-demo/blob/main/src/react-native-app/)
12+
13+
## Instrumentation
14+
15+
The application uses the OpenTelemetry packages to instrument the application at
16+
the JS layer.
17+
18+
{{% alert title="Important" color="warning" %}}
19+
20+
The JS OTel packages are supported for node and web environments. While they
21+
work for React Native as well, they are not explicitly supported for that
22+
environment, where they might break compatibility with minor version updates or
23+
require workarounds. Building JS OTel package support for React Native is an
24+
area of active development.
25+
26+
{{% /alert %}}
27+
28+
The main entry point for the application is `app/_layout.tsx` where a hook is
29+
used to initialize the instrumentation and make sure it is loaded before
30+
displaying the UI:
31+
32+
```typescript
33+
import { useTracer } from '@/hooks/useTracer';
34+
35+
const { loaded: tracerLoaded } = useTracer();
36+
```
37+
38+
`hooks/useTracer.ts` contains all the code for setting up instrumentation
39+
including initializing a TracerProvider, establishing an OTLP export,
40+
registering trace context propagators, and registering auto-instrumentation of
41+
network requests.
42+
43+
```typescript
44+
import {
45+
CompositePropagator,
46+
W3CBaggagePropagator,
47+
W3CTraceContextPropagator,
48+
} from '@opentelemetry/core';
49+
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
50+
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
51+
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
52+
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
53+
import { registerInstrumentations } from '@opentelemetry/instrumentation';
54+
import { Resource } from '@opentelemetry/resources';
55+
import {
56+
ATTR_DEVICE_ID,
57+
ATTR_OS_NAME,
58+
ATTR_OS_VERSION,
59+
ATTR_SERVICE_NAME,
60+
ATTR_SERVICE_VERSION,
61+
} from '@opentelemetry/semantic-conventions/incubating';
62+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
63+
import getLocalhost from '@/utils/Localhost';
64+
import { useEffect, useState } from 'react';
65+
import {
66+
getDeviceId,
67+
getSystemVersion,
68+
getVersion,
69+
} from 'react-native-device-info';
70+
import { Platform } from 'react-native';
71+
import { SessionIdProcessor } from '@/utils/SessionIdProcessor';
72+
73+
const Tracer = async () => {
74+
const localhost = await getLocalhost();
75+
76+
const resource = new Resource({
77+
[ATTR_SERVICE_NAME]: 'react-native-app',
78+
[ATTR_OS_NAME]: Platform.OS,
79+
[ATTR_OS_VERSION]: getSystemVersion(),
80+
[ATTR_SERVICE_VERSION]: getVersion(),
81+
[ATTR_DEVICE_ID]: getDeviceId(),
82+
});
83+
84+
const provider = new WebTracerProvider({
85+
resource,
86+
spanProcessors: [
87+
new BatchSpanProcessor(
88+
new OTLPTraceExporter({
89+
url: `http://${localhost}:${process.env.EXPO_PUBLIC_FRONTEND_PROXY_PORT}/otlp-http/v1/traces`,
90+
}),
91+
{
92+
scheduledDelayMillis: 500,
93+
},
94+
),
95+
new SessionIdProcessor(),
96+
],
97+
});
98+
99+
provider.register({
100+
propagator: new CompositePropagator({
101+
propagators: [
102+
new W3CBaggagePropagator(),
103+
new W3CTraceContextPropagator(),
104+
],
105+
}),
106+
});
107+
108+
registerInstrumentations({
109+
instrumentations: [
110+
// Some tiptoeing required here, propagateTraceHeaderCorsUrls is required to make the instrumentation
111+
// work in the context of a mobile app even though we are not making CORS requests. `clearTimingResources` must
112+
// be turned off to avoid using the web-only Performance API
113+
new FetchInstrumentation({
114+
propagateTraceHeaderCorsUrls: /.*/,
115+
clearTimingResources: false,
116+
}),
117+
118+
// The React Native implementation of fetch is simply a polyfill on top of XMLHttpRequest:
119+
// https://github.com/facebook/react-native/blob/7ccc5934d0f341f9bc8157f18913a7b340f5db2d/packages/react-native/Libraries/Network/fetch.js#L17
120+
// Because of this when making requests using `fetch` there will an additional span created for the underlying
121+
// request made with XMLHttpRequest. Since in this demo calls to /api/ are made using fetch, turn off
122+
// instrumentation for that path to avoid the extra spans.
123+
new XMLHttpRequestInstrumentation({
124+
ignoreUrls: [/\/api\/.*/],
125+
}),
126+
],
127+
});
128+
};
129+
130+
export interface TracerResult {
131+
loaded: boolean;
132+
}
133+
134+
export const useTracer = (): TracerResult => {
135+
const [loaded, setLoaded] = useState<boolean>(false);
136+
137+
useEffect(() => {
138+
if (!loaded) {
139+
Tracer()
140+
.catch(() => console.warn('failed to setup tracer'))
141+
.finally(() => setLoaded(true));
142+
}
143+
}, [loaded]);
144+
145+
return {
146+
loaded,
147+
};
148+
};
149+
```

static/refcache.json

+4
Original file line numberDiff line numberDiff line change
@@ -2583,6 +2583,10 @@
25832583
"StatusCode": 206,
25842584
"LastSeen": "2024-01-30T16:04:54.134692-05:00"
25852585
},
2586+
"https://docs.expo.dev/get-started/introduction/": {
2587+
"StatusCode": 206,
2588+
"LastSeen": "2025-01-07T10:55:21.674477-05:00"
2589+
},
25862590
"https://docs.fluentbit.io/manual/pipeline/inputs/opentelemetry/": {
25872591
"StatusCode": 206,
25882592
"LastSeen": "2024-01-30T06:05:58.662694-05:00"

0 commit comments

Comments
 (0)