Skip to content

Commit 46912ce

Browse files
Add browser traffic in loadgenerator and export traces in frontend (open-telemetry#1345)
* Add locust_plugins as a dependency * Increased memory constraints and introduced LOCUST_BROWSER_TRAFFIC_ENABLED environment variable * Added playwright on load generator docker image * Inceased delay interval in milliseconds between two consecutive exports * Use different otel endpoint when request contains the synthetic_request=true header * Add locust example using playwright. The header synthetic_request is set to true to identify them in the frontend * Updated changelog * Use the same otelName (OTEL_COLLECTOR_HOST) for both k8s and docker * Removed select option event * Revert - Removed select option event * Added IS_SYNTHETIC_REQUEST window.env used to set the span web attribute in FrontendTracer.ts --------- Co-authored-by: Juliano Costa <[email protected]>
1 parent 6815c84 commit 46912ce

File tree

10 files changed

+78
-14
lines changed

10 files changed

+78
-14
lines changed

.env

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ LOCUST_HOST=http://${FRONTEND_PROXY_ADDR}
6767
LOCUST_WEB_HOST=loadgenerator
6868
LOCUST_AUTOSTART=true
6969
LOCUST_HEADLESS=false
70+
LOCUST_BROWSER_TRAFFIC_ENABLED=false
7071

7172
# Payment Service
7273
PAYMENT_SERVICE_PORT=50051

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ release.
1717
([#1335](https://github.com/open-telemetry/opentelemetry-demo/pull/1335))
1818
* [ffspostgres] define and use demo specific postgres image
1919
([#1338](https://github.com/open-telemetry/opentelemetry-demo/pull/1338))
20+
* [loadgenerator, frontend] enable browser traffic in loadgenerator using playwright
21+
([#1345](https://github.com/open-telemetry/opentelemetry-demo/pull/1345))
2022
* [accountingservice] update wiki link
2123
([#1346](https://github.com/open-telemetry/opentelemetry-demo/pull/1346))
2224
* [checkoutservice] update wiki link

docker-compose.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ services:
296296
- PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
297297
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
298298
- WEB_OTEL_SERVICE_NAME=frontend-web
299+
- OTEL_COLLECTOR_HOST
299300
depends_on:
300301
adservice:
301302
condition: service_started
@@ -371,7 +372,7 @@ services:
371372
deploy:
372373
resources:
373374
limits:
374-
memory: 120M
375+
memory: 1G
375376
restart: unless-stopped
376377
ports:
377378
- "${LOCUST_WEB_PORT}"
@@ -381,6 +382,7 @@ services:
381382
- LOCUST_HOST
382383
- LOCUST_HEADLESS
383384
- LOCUST_AUTOSTART
385+
- LOCUST_BROWSER_TRAFFIC_ENABLED
384386
- OTEL_EXPORTER_OTLP_ENDPOINT
385387
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
386388
- OTEL_RESOURCE_ATTRIBUTES

kubernetes/opentelemetry-demo.yaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -9824,6 +9824,8 @@ spec:
98249824
value: http://localhost:8080/otlp-http/v1/traces
98259825
- name: OTEL_RESOURCE_ATTRIBUTES
98269826
value: service.name=$(OTEL_SERVICE_NAME),service.namespace=opentelemetry-demo
9827+
- name: OTEL_COLLECTOR_HOST
9828+
value: $(OTEL_COLLECTOR_NAME)
98279829
resources:
98289830
limits:
98299831
memory: 200Mi
@@ -10041,6 +10043,8 @@ spec:
1004110043
value: "false"
1004210044
- name: LOCUST_AUTOSTART
1004310045
value: "true"
10046+
- name: LOCUST_BROWSER_TRAFFIC_ENABLED
10047+
value: "false"
1004410048
- name: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION
1004510049
value: python
1004610050
- name: OTEL_EXPORTER_OTLP_ENDPOINT
@@ -10049,7 +10053,7 @@ spec:
1004910053
value: service.name=$(OTEL_SERVICE_NAME),service.namespace=opentelemetry-demo
1005010054
resources:
1005110055
limits:
10052-
memory: 120Mi
10056+
memory: 1Gi
1005310057
---
1005410058
# Source: opentelemetry-demo/templates/component.yaml
1005510059
apiVersion: apps/v1

src/frontend/pages/_app.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ declare global {
1717
NEXT_PUBLIC_PLATFORM?: string;
1818
NEXT_PUBLIC_OTEL_SERVICE_NAME?: string;
1919
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?: string;
20+
IS_SYNTHETIC_REQUEST?: string;
2021
};
2122
}
2223
}

src/frontend/pages/_document.tsx

+16-9
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,9 @@
33

44
import Document, { DocumentContext, Html, Head, Main, NextScript } from 'next/document';
55
import { ServerStyleSheet } from 'styled-components';
6+
import {context, propagation} from "@opentelemetry/api";
67

7-
const { ENV_PLATFORM, WEB_OTEL_SERVICE_NAME, PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT } = process.env;
8-
9-
const envString = `
10-
window.ENV = {
11-
NEXT_PUBLIC_PLATFORM: '${ENV_PLATFORM}',
12-
NEXT_PUBLIC_OTEL_SERVICE_NAME: '${WEB_OTEL_SERVICE_NAME}',
13-
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT}',
14-
};
15-
`;
8+
const { ENV_PLATFORM, WEB_OTEL_SERVICE_NAME, PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_COLLECTOR_HOST} = process.env;
169

1710
export default class MyDocument extends Document<{ envString: string }> {
1811
static async getInitialProps(ctx: DocumentContext) {
@@ -26,6 +19,20 @@ export default class MyDocument extends Document<{ envString: string }> {
2619
});
2720

2821
const initialProps = await Document.getInitialProps(ctx);
22+
const baggage = propagation.getBaggage(context.active());
23+
const isSyntheticRequest = baggage?.getEntry('synthetic_request')?.value === 'true';
24+
25+
const otlpTracesEndpoint = isSyntheticRequest
26+
? `http://${OTEL_COLLECTOR_HOST}:4318/v1/traces`
27+
: PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
28+
29+
const envString = `
30+
window.ENV = {
31+
NEXT_PUBLIC_PLATFORM: '${ENV_PLATFORM}',
32+
NEXT_PUBLIC_OTEL_SERVICE_NAME: '${WEB_OTEL_SERVICE_NAME}',
33+
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${otlpTracesEndpoint}',
34+
IS_SYNTHETIC_REQUEST: '${isSyntheticRequest}',
35+
};`;
2936
return {
3037
...initialProps,
3138
styles: [initialProps.styles, sheet.getStyleElement()],

src/frontend/utils/telemetry/FrontendTracer.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
1212
import { SessionIdProcessor } from './SessionIdProcessor';
1313
import { detectResourcesSync } from '@opentelemetry/resources/build/src/detect-resources';
1414

15-
const { NEXT_PUBLIC_OTEL_SERVICE_NAME = '', NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = '' } =
15+
const { NEXT_PUBLIC_OTEL_SERVICE_NAME = '', NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = '', IS_SYNTHETIC_REQUEST = '' } =
1616
typeof window !== 'undefined' ? window.ENV : {};
1717

1818
const FrontendTracer = async (collectorString: string) => {
@@ -34,7 +34,9 @@ const FrontendTracer = async (collectorString: string) => {
3434
new BatchSpanProcessor(
3535
new OTLPTraceExporter({
3636
url: NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || collectorString || 'http://localhost:4318/v1/traces',
37-
})
37+
}), {
38+
scheduledDelayMillis : 500
39+
}
3840
)
3941
);
4042

@@ -55,7 +57,7 @@ const FrontendTracer = async (collectorString: string) => {
5557
propagateTraceHeaderCorsUrls: /.*/,
5658
clearTimingResources: true,
5759
applyCustomAttributesOnSpan(span) {
58-
span.setAttribute('app.synthetic_request', 'false');
60+
span.setAttribute('app.synthetic_request', IS_SYNTHETIC_REQUEST);
5961
},
6062
},
6163
}),

src/loadgenerator/Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ WORKDIR /usr/src/app/
1717
COPY --from=builder /reqs /usr/local
1818
COPY ./src/loadgenerator/locustfile.py .
1919
COPY ./src/loadgenerator/people.json .
20+
ENV LOCUST_PLAYWRIGHT=1
21+
RUN playwright install --with-deps chromium
2022
ENTRYPOINT locust

src/loadgenerator/locustfile.py

+42
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66

77
import json
8+
import os
89
import random
910
import uuid
1011
from locust import HttpUser, task, between
12+
from locust_plugins.users.playwright import PlaywrightUser, pw, PageWithRetry, event
1113

1214
from opentelemetry import context, baggage, trace
1315
from opentelemetry.metrics import set_meter_provider
@@ -21,6 +23,7 @@
2123
from opentelemetry.instrumentation.requests import RequestsInstrumentor
2224
from opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor
2325
from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor
26+
from playwright.async_api import Route, Request
2427

2528
exporter = OTLPMetricExporter(insecure=True)
2629
set_meter_provider(MeterProvider([PeriodicExportingMetricReader(exporter)]))
@@ -130,3 +133,42 @@ def on_start(self):
130133
context.attach(ctx)
131134
self.index()
132135

136+
137+
browser_traffic_enabled = os.environ.get('LOCUST_BROWSER_TRAFFIC_ENABLED', False)
138+
139+
if browser_traffic_enabled:
140+
class WebsiteBrowserUser(PlaywrightUser):
141+
headless = True # to use a headless browser, without a GUI
142+
143+
@task
144+
@pw
145+
async def open_cart_page_and_change_currency(self, page: PageWithRetry):
146+
try:
147+
page.on("console", lambda msg: print(msg.text))
148+
await page.route('**/*', add_baggage_header)
149+
await page.goto("/cart", wait_until="domcontentloaded")
150+
await page.select_option('[name="currency_code"]', 'CHF')
151+
await page.wait_for_timeout(2000) # giving the browser time to export the traces
152+
except:
153+
pass
154+
155+
@task
156+
@pw
157+
async def add_product_to_cart(self, page: PageWithRetry):
158+
try:
159+
page.on("console", lambda msg: print(msg.text))
160+
await page.route('**/*', add_baggage_header)
161+
await page.goto("/", wait_until="domcontentloaded")
162+
await page.click('p:has-text("Roof Binoculars")', wait_until="domcontentloaded")
163+
await page.click('button:has-text("Add To Cart")', wait_until="domcontentloaded")
164+
await page.wait_for_timeout(2000) # giving the browser time to export the traces
165+
except:
166+
pass
167+
168+
169+
async def add_baggage_header(route: Route, request: Request):
170+
headers = {
171+
**request.headers,
172+
'baggage': 'synthetic_request=true'
173+
}
174+
await route.continue_(headers=headers)

src/loadgenerator/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ idna==3.4
1616
itsdangerous==2.1.2
1717
jinja2==3.1.2
1818
locust==2.18.2
19+
locust_plugins==3.4.0
1920
markupsafe==2.1.3
2021
msgpack==1.0.7
2122
opentelemetry-api==1.21.0

0 commit comments

Comments
 (0)