Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,14 @@ IMAGE_PROVIDER_PORT=8081
IMAGE_PROVIDER_DOCKERFILE=./src/image-provider/Dockerfile

# Load Generator
LOAD_GENERATOR_VUS=5
K6_TARGET_URL=http://${FRONTEND_PROXY_ADDR}
LOCUST_WEB_PORT=8089
LOCUST_USERS=5
LOCUST_HOST=http://${FRONTEND_PROXY_ADDR}
LOCUST_WEB_HOST=load-generator
LOCUST_AUTOSTART=true
LOCUST_HTTP_USER_WEIGHT=9
LOCUST_BROWSER_USER_WEIGHT=1
LOCUST_HEADLESS=false
LOAD_GENERATOR_DOCKERFILE=./src/load-generator/Dockerfile

# Payment Service
Expand Down
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ updates:
patterns:
- "*"
multi-ecosystem-group: "src-chatbot"
- package-ecosystem: "gomod" # zizmor: ignore[dependabot-cooldown] cooldown prevents multi-ecosystem batching
- package-ecosystem: "pip" # zizmor: ignore[dependabot-cooldown] cooldown prevents multi-ecosystem batching
directories:
- "/src/load-generator/**"
patterns:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ the release.

## Unreleased

* [load-generator] Revert #3564: replace k6 with the pre-k6 Locust-based load
generator, removing the now-unused `loadGeneratorTraffic` and
`loadGeneratorVUs` feature flags along with it
([#3873](https://github.com/open-telemetry/opentelemetry-demo/pull/3873))
* [react-native-app] Catch errors from `placeOrder` in the Cart screen and
show an error toast so payment failures are visible to the user instead of
being silently dropped
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Once the images are built and containers are started, visit:
- **Grafana**: [http://localhost:8080/grafana/](http://localhost:8080/grafana/)
- **OpAMP**: [http://localhost:8080/opamp/](http://localhost:8080/opamp/)
- **Feature Flags UI**: [http://localhost:8080/feature/](http://localhost:8080/feature/)
- **Load Generator UI**: [http://localhost:8080/loadgen/](http://localhost:8080/loadgen/)

The OpAMP UI shows the OpenTelemetry Collector as a managed agent. Click the
collector instance ID to view its health status, version, attributes, and
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ start:
@echo "Go to http://localhost:8080 for the demo UI."
@echo "Go to http://localhost:8080/jaeger/ui for the Jaeger UI."
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:8080/feature/ to change feature flags."
@echo "Go to http://localhost:8080/telemetry/ for the Weaver generated telemetry documentation."

Expand All @@ -294,6 +295,7 @@ start-minimal:
@echo "Go to http://localhost:8080 for the demo UI."
@echo "Go to http://localhost:8080/jaeger/ui for the Jaeger UI."
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:8080/feature/ to change feature flags."
@echo "Go to http://localhost:8080/telemetry/ for the Weaver generated telemetry documentation."

Expand All @@ -303,6 +305,7 @@ start-no-o11y:
@echo ""
@echo "OpenTelemetry Demo is running (no observability stack)."
@echo "Go to http://localhost:8080 for the demo UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:8080/feature/ to change feature flags."
@echo "Go to http://localhost:8080/telemetry/ for the Weaver generated telemetry documentation."

Expand All @@ -312,6 +315,7 @@ start-minimal-no-o11y:
@echo ""
@echo "OpenTelemetry Demo in minimal mode is running (no observability stack)."
@echo "Go to http://localhost:8080 for the demo UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:8080/feature/ to change feature flags."
@echo "Go to http://localhost:8080/telemetry/ for the Weaver generated telemetry documentation."

Expand All @@ -323,6 +327,7 @@ start-profiling:
@echo "Go to http://localhost:8080 for the demo UI."
@echo "Go to http://localhost:8080/jaeger/ui for the Jaeger UI."
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:8080/profiles/ for the Firepit UI."
@echo "Go to http://localhost:8080/telemetry/ for the Weaver generated telemetry documentation."

Expand All @@ -334,6 +339,7 @@ start-agentic:
@echo "Go to http://localhost:8080 for the demo UI."
@echo "Go to http://localhost:8080/jaeger/ui for the Jaeger UI."
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:8080/feature/ to change feature flags."
@echo "Go to http://localhost:8080/telemetry/ for the Weaver generated telemetry documentation."
@echo "Go to http://localhost:8080/chatbot/ for interacting with demo application using an agent."
Expand Down
38 changes: 22 additions & 16 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ services:
environment:
- FRONTEND_PORT
- FRONTEND_HOST
- LOCUST_WEB_HOST
- LOCUST_WEB_PORT
- GRAFANA_PORT
- GRAFANA_HOST
- JAEGER_UI_PORT
Expand Down Expand Up @@ -366,6 +368,8 @@ services:
depends_on:
frontend:
condition: service_healthy
load-generator:
condition: service_started
flagd-ui:
condition: service_healthy
telemetry-docs:
Expand Down Expand Up @@ -417,35 +421,37 @@ services:
deploy:
resources:
limits:
memory: 512M
memory: 1500M
restart: unless-stopped
ports:
- "${LOCUST_WEB_PORT}"
environment:
- LOAD_GENERATOR_VUS
- K6_TARGET_URL
- OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP}
- OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
- LOCUST_WEB_PORT
- LOCUST_USERS
- LOCUST_HOST
- LOCUST_HEADLESS
- LOCUST_AUTOSTART
- LOCUST_BROWSER_TRAFFIC_ENABLED=true
- LOCUST_HTTP_USER_WEIGHT
- LOCUST_BROWSER_USER_WEIGHT
- OTEL_EXPORTER_OTLP_ENDPOINT
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
- OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES},service.criticality=low
- OTEL_SERVICE_NAME=load-generator
- PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
- LOCUST_WEB_HOST=0.0.0.0
- FLAGD_HOST
- FLAGD_PORT
- FLAGD_OFREP_PORT
- K6_OTEL_EXPORTER_PROTOCOL=http/protobuf
- K6_OTEL_HTTP_EXPORTER_ENDPOINT=${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP}
- K6_OTEL_HTTP_EXPORTER_INSECURE=true
- K6_BROWSER_ENABLED=true
- K6_BROWSER_ARGS=no-sandbox,disable-dev-shm-usage
- K6_OTEL_METRIC_PREFIX=k6.
healthcheck:
test: ["CMD-SHELL", "pgrep k6"]
start_period: 10s
test: ["CMD", "python3", "-c", "import socket; s=socket.create_connection(('localhost',${LOCUST_WEB_PORT}),2); s.close()"]
start_period: 30s
interval: 5s
timeout: 5s
retries: 5
retries: 20
depends_on:
frontend:
condition: service_healthy
frontend-proxy:
condition: service_healthy
flagd:
condition: service_started
logging: *logging
Expand Down
5 changes: 2 additions & 3 deletions src/flagd-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ Each interval the scheduler activates up to a configured number of distinct
randomly picked flags. Every activation gets its own hold duration between the
configured minimum and maximum, and its own offset, so that the whole activation
fits inside the interval. When a hold expires that flag is set back to its
resting variant, the flag's own configured default. That is `off` for most
failure scenarios, but `on` for `loadGeneratorTraffic` and `5` for
`loadGeneratorVUs`.
resting variant, the flag's own configured default, which is `off` for every
failure scenario.

The following can be configured:

Expand Down
59 changes: 6 additions & 53 deletions src/flagd-ui/test/flagd_ui/scheduler_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,6 @@ defmodule FlagdUi.SchedulerTest do
assert {"cartFailure", ["10%", "100%", "25%", "50%", "75%", "90%"]} in flags
end

test "offers loadGeneratorTraffic, whose resting state is on" do
flags = Storage |> GenServer.call(:read) |> Scheduler.schedulable_flags()

assert {"loadGeneratorTraffic", ["off"]} in flags
end

test "offers loadGeneratorVUs, whose resting state is its default variant" do
flags = Storage |> GenServer.call(:read) |> Scheduler.schedulable_flags()

assert {"loadGeneratorVUs", ["10", "25", "50"]} in flags
end

test "tolerates a configuration without flags" do
assert Scheduler.schedulable_flags(%{}) == []
assert Scheduler.schedulable_flags(%{"flags" => nil}) == []
Expand Down Expand Up @@ -176,52 +164,13 @@ defmodule FlagdUi.SchedulerTest do
assert Enum.any?(Scheduler.state(scheduler).history, &(&1.flag == flag))
end

test "reverts loadGeneratorTraffic to on, not off" do
scheduler = start_scheduler(TrafficRevertScheduler)

config = immediate_config(%{flags: %{"loadGeneratorTraffic" => ["off"]}})

assert :ok = Scheduler.start_schedule(scheduler, config)

assert_receive {:scheduler_state, %{active: [%{flag: "loadGeneratorTraffic"}]}}, 2000
assert eventually(fn -> variant_of("loadGeneratorTraffic") == "off" end)

assert :ok = Scheduler.stop_schedule(scheduler)

assert eventually(fn -> variant_of("loadGeneratorTraffic") == "on" end)
end

test "reverts loadGeneratorVUs to its own default, not off" do
scheduler = start_scheduler(VUsRevertScheduler)

config = immediate_config(%{flags: %{"loadGeneratorVUs" => ["25"]}})

assert :ok = Scheduler.start_schedule(scheduler, config)

assert_receive {:scheduler_state, %{active: [%{flag: "loadGeneratorVUs", variant: "25"}]}},
2000

assert :ok = Scheduler.stop_schedule(scheduler)

assert eventually(fn -> variant_of("loadGeneratorVUs") == "5" end)
end

test "reverts every flag it activates when holds fill the whole interval" do
scheduler = start_scheduler(BackToBackScheduler)

# Restrict to off-resting flags: loadGeneratorTraffic and loadGeneratorVUs
# rest elsewhere and are covered by their own revert tests above.
selection =
Storage
|> GenServer.call(:read)
|> Scheduler.schedulable_flags()
|> Enum.reject(fn {name, _} -> name in ["loadGeneratorTraffic", "loadGeneratorVUs"] end)
|> Map.new()

# A hold as long as the interval makes each revert land exactly on the next
# interval boundary, which previously left the earlier flag switched on.
assert :ok =
Scheduler.start_schedule(scheduler, immediate_config(%{seed: 99, flags: selection}))
Scheduler.start_schedule(scheduler, immediate_config(%{seed: 99}))

assert_receive {:scheduler_state, %{active: [%{flag: _}]}}, 2000

Expand Down Expand Up @@ -367,7 +316,11 @@ defmodule FlagdUi.SchedulerTest do
test "reverts every concurrently held flag when stopped" do
scheduler = start_scheduler(ConcurrentStopScheduler)

assert :ok = Scheduler.start_schedule(scheduler, held_config(%{concurrency: 4}))
assert :ok =
Scheduler.start_schedule(
scheduler,
held_config(%{concurrency: 4})
)

assert_receive {:scheduler_state, %{active: [_, _, _, _] = active}}, 2000

Expand Down
1 change: 0 additions & 1 deletion src/flagd-ui/test/flagd_ui_web/live/scheduler_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ defmodule FlagdUiWeb.SchedulerTest do
assert html =~ "Scheduler stopped"
assert html =~ "Idle"
assert html =~ "adFailure"
assert html =~ "loadGeneratorVUs"
end

test "navigating from the dashboard live redirects", %{conn: conn} do
Expand Down
19 changes: 4 additions & 15 deletions src/flagd/demo.flagd.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,24 +93,13 @@
"on": 100
}
},
"loadGeneratorTraffic": {
"defaultVariant": "on",
"description": "Enable synthetic traffic from the load generator. Turn off to pause all load-generator scenarios.",
"loadGeneratorFloodHomepage": {
"defaultVariant": "off",
"description": "Flood the frontend with a large amount of requests.",
"state": "ENABLED",
"variants": {
"off": 0,
"on": 1
}
},
"loadGeneratorVUs": {
"defaultVariant": "5",
"description": "Number of concurrent virtual users the load generator's HTTP scenario runs. Changes take effect on the wrapper's next poll, restarting k6.",
"state": "ENABLED",
"variants": {
"10": 10,
"25": 25,
"5": 5,
"50": 50
"on": 100
}
},
"paymentFailure": {
Expand Down
36 changes: 32 additions & 4 deletions src/frontend-proxy/envoy.tmpl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ static_resources:
domains:
- "*"
routes:
- match: { path: "/loadgen" }
redirect: { path_redirect: "/loadgen/" }
- match: { prefix: "/loadgen/" }
route: { cluster: loadgen, prefix_rewrite: "/" }
- match: { prefix: "/otlp-http/" }
route: { cluster: opentelemetry_collector_http, prefix_rewrite: "/" }
route:
{
cluster: opentelemetry_collector_http,
prefix_rewrite: "/",
}
- match: { path: "/jaeger" }
redirect: { path_redirect: "/jaeger/" }
- match: { prefix: "/jaeger/" }
Expand All @@ -53,11 +61,18 @@ static_resources:
- match: { path: "/telemetry" }
redirect: { path_redirect: "/telemetry/" }
- match: { prefix: "/telemetry/" }
route: { cluster: telemetry-docs, prefix_rewrite: "/" }
route:
{ cluster: telemetry-docs, prefix_rewrite: "/" }
- match: { prefix: "/images/" }
route: { cluster: image-provider, prefix_rewrite: "/" }
route:
{ cluster: image-provider, prefix_rewrite: "/" }
- match: { prefix: "/flagservice/" }
route: { cluster: flagservice, prefix_rewrite: "/", timeout: 0s }
route:
{
cluster: flagservice,
prefix_rewrite: "/",
timeout: 0s,
}
- match: { prefix: "/feature" }
route:
cluster: flagd-ui
Expand Down Expand Up @@ -233,6 +248,19 @@ static_resources:
socket_address:
address: ${FLAGD_UI_HOST}
port_value: ${FLAGD_UI_PORT}
- name: loadgen
type: STRICT_DNS
lb_policy: ROUND_ROBIN
typed_dns_resolver_config: *dns_resolver
load_assignment:
cluster_name: loadgen
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: ${LOCUST_WEB_HOST}
port_value: ${LOCUST_WEB_PORT}
- name: grafana
type: STRICT_DNS
lb_policy: ROUND_ROBIN
Expand Down
Loading
Loading