From ed1cbaaabb34b08ab5f85fedac74cf7dffdf6d78 Mon Sep 17 00:00:00 2001 From: "markus.eisl" Date: Mon, 8 Apr 2024 14:40:49 +0200 Subject: [PATCH 1/2] adservice add highcpu load ff This commit adds a new ff to the adservice. When enabled, the adservice uses an abnormal amout of CPU. Should you want to demo cpu throtteling, you need to add cpu limits to the pod/container --- .../src/main/java/oteldemo/AdService.java | 4 + .../java/oteldemo/problempattern/CPULoad.java | 116 ++++++++++++++++++ src/flagd/demo.flagd.json | 9 ++ 3 files changed, 129 insertions(+) create mode 100644 src/adservice/src/main/java/oteldemo/problempattern/CPULoad.java diff --git a/src/adservice/src/main/java/oteldemo/AdService.java b/src/adservice/src/main/java/oteldemo/AdService.java index 4bdd81ac86..7963c8055d 100644 --- a/src/adservice/src/main/java/oteldemo/AdService.java +++ b/src/adservice/src/main/java/oteldemo/AdService.java @@ -35,6 +35,7 @@ import oteldemo.Demo.AdRequest; import oteldemo.Demo.AdResponse; import oteldemo.problempattern.GarbageCollectionTrigger; +import oteldemo.problempattern.CPULoad; import dev.openfeature.contrib.providers.flagd.FlagdOptions; import dev.openfeature.contrib.providers.flagd.FlagdProvider; import dev.openfeature.sdk.Client; @@ -130,6 +131,7 @@ private static class AdServiceImpl extends oteldemo.AdServiceGrpc.AdServiceImplB private static final String ADSERVICE_FAILURE = "adServiceFailure"; private static final String ADSERVICE_MANUAL_GC_FEATURE_FLAG = "adServiceManualGc"; + private static final String ADSERVICE_HIGH_CPU_FEATURE_FLAG = "adServiceHighCpu"; private AdServiceImpl() {} @@ -143,6 +145,8 @@ private AdServiceImpl() {} @Override public void getAds(AdRequest req, StreamObserver responseObserver) { AdService service = AdService.getInstance(); + CPULoad cpuload = CPULoad.getInstance(); + cpuload.execute(getFeatureFlagEnabled(ADSERVICE_HIGH_CPU_FEATURE_FLAG)); // get the current span in context Span span = Span.current(); diff --git a/src/adservice/src/main/java/oteldemo/problempattern/CPULoad.java b/src/adservice/src/main/java/oteldemo/problempattern/CPULoad.java new file mode 100644 index 0000000000..178f773370 --- /dev/null +++ b/src/adservice/src/main/java/oteldemo/problempattern/CPULoad.java @@ -0,0 +1,116 @@ +/* +* Copyright The OpenTelemetry Authors +* SPDX-License-Identifier: Apache-2.0 +*/ +package oteldemo.problempattern; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import io.grpc.ManagedChannelBuilder; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * This class is designed to simulate a high CPU load scenario. + * It contains methods to start and stop a specified number of worker threads designed to + * perform CPU-intensive calculations. + */ +public class CPULoad { + private static final Logger logger = LogManager.getLogger(CPULoad.class.getName()); + private static final int THREAD_COUNT = 4; + private boolean running = false; + private final List runningWorkers = new ArrayList<>(); + + private static CPULoad instance; + + /** + * Singleton pattern to get the instance of CPULoad. + * @return The singleton instance of CPULoad. + */ + public static CPULoad getInstance() { + if (instance == null) { + instance = new CPULoad(); + } + return instance; + } + + /** + * Starts or stops the CPU load generation based on the input parameter. + * If enabled, it launches worker threads. If disabled, it stops any running threads. + * + * @param enabled Flag to start (true) or stop (false) the CPU load simulation. + */ + public void execute(Boolean enabled) { + if (enabled) { + logger.info("High CPU-Load problempattern enabled"); + if (!running) { + spawnLoadWorkers(THREAD_COUNT); + running = true; + } + } else { + running = false; + stopWorkers(); + } + } + + /** + * Creates and starts a specified number of Logarithmizer threads to simulate CPU load. + * + * @param threadCount The number of threads to be started. + */ + private void spawnLoadWorkers(int threadCount) { + synchronized(runningWorkers) { + for (int i = 0; i < threadCount; i++) { + Logarithmizer logarithmizer = new Logarithmizer(); + Thread thread = new Thread(logarithmizer); + thread.setDaemon(true); + thread.start(); + runningWorkers.add(logarithmizer); + } + } + } + + /** + * Signals all running Logarithmizer threads to stop and clears the list of running workers. + */ + private void stopWorkers() { + synchronized(runningWorkers) { + for (Logarithmizer logarithmizer : runningWorkers) { + logarithmizer.setShouldRun(false); + } + runningWorkers.clear(); + } + } + + /** + * Inner class representing a worker focused on calculating logarithms to consume CPU resources. + */ + private static class Logarithmizer implements Runnable { + + private volatile boolean shouldRun = true; + + /** + * Continuously calculates the logarithm of the current system time until + * requested to stop. + */ + @Override + public void run() { + while (shouldRun) { + Math.log(System.currentTimeMillis()); + } + } + + /** + * Sets the shouldRun flag to control whether this Logarithmizer should continue + * to run. + * + * @param shouldRun A boolean flag to continue (true) or stop (false) the logarithm computation. + */ + public void setShouldRun(boolean shouldRun) { + this.shouldRun = shouldRun; + } + } +} diff --git a/src/flagd/demo.flagd.json b/src/flagd/demo.flagd.json index 26c2c71b94..9c9bab1f2e 100644 --- a/src/flagd/demo.flagd.json +++ b/src/flagd/demo.flagd.json @@ -28,6 +28,15 @@ }, "defaultVariant": "off" }, + "adServiceHighCpu": { + "description": "Triggers high cpu load in the ad service", + "state": "ENABLED", + "variants": { + "on": true, + "off": false + }, + "defaultVariant": "off" + }, "adServiceFailure": { "description": "Fail ad service", "state": "ENABLED", From daff385749696c6074e57dfa3d9d67d550142116 Mon Sep 17 00:00:00 2001 From: "markus.eisl" Date: Mon, 8 Apr 2024 14:45:05 +0200 Subject: [PATCH 2/2] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb45909690..89981d6bbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,8 @@ the release. ([#1473](https://github.com/open-telemetry/opentelemetry-demo/pull/1473)) * [Imageprovider] Create Nginx service to host images, add instrumentation to it ([#1462](https://github.com/open-telemetry/opentelemetry-demo/pull/1462)) +* [adservice] add adServiceHighCpu feature flag + ([#1510](https://github.com/open-telemetry/opentelemetry-demo/pull/1510)) ## 1.8.0