diff --git a/src/main/java/org/springframework/samples/petclinic/errors/MonitorService.java b/src/main/java/org/springframework/samples/petclinic/errors/MonitorService.java index af0ad68a219..044bded7b8c 100644 --- a/src/main/java/org/springframework/samples/petclinic/errors/MonitorService.java +++ b/src/main/java/org/springframework/samples/petclinic/errors/MonitorService.java @@ -6,72 +6,115 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.SmartLifecycle; import org.springframework.stereotype.Component; - -import java.util.InvalidPropertiesFormatException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Component public class MonitorService implements SmartLifecycle { - private boolean running = false; - private Thread backgroundThread; - @Autowired - private OpenTelemetry openTelemetry; - - @Override - public void start() { - var otelTracer = openTelemetry.getTracer("MonitorService"); - - running = true; - backgroundThread = new Thread(() -> { - while (running) { - - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - Span span = otelTracer.spanBuilder("monitor").startSpan(); - - try { - - System.out.println("Background service is running..."); - monitor(); - } catch (Exception e) { - span.recordException(e); - span.setStatus(StatusCode.ERROR); - } finally { - span.end(); - } - } - }); - - // Start the background thread - backgroundThread.start(); - System.out.println("Background service started."); - } - - private void monitor() throws InvalidPropertiesFormatException { - Utils.throwException(IllegalStateException.class,"monitor failure"); - } - - - - @Override - public void stop() { - // Stop the background task - running = false; - if (backgroundThread != null) { - try { - backgroundThread.join(); // Wait for the thread to finish - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - System.out.println("Background service stopped."); - } - - @Override - public boolean isRunning() { - return false; - } -} + private static final Logger logger = LoggerFactory.getLogger(MonitorService.class); + private final AtomicBoolean running = new AtomicBoolean(false); + private final AtomicBoolean initialized = new AtomicBoolean(false); + private final AtomicInteger errorCount = new AtomicInteger(0); + private Thread backgroundThread; + private static final int MAX_ERRORS = 3; + private static final long MONITOR_INTERVAL = 5000; + + @Autowired + private OpenTelemetry openTelemetry; + + @Override + public void start() { + if (openTelemetry == null) { + throw new IllegalStateException("OpenTelemetry not properly initialized"); + } + + if (running.get()) { + logger.warn("Monitor service is already running"); + return; + } + + var otelTracer = openTelemetry.getTracer("MonitorService"); + running.set(true); + initialized.set(true); + + backgroundThread = new Thread(() -> { + while (running.get()) { + Span span = otelTracer.spanBuilder("monitor").startSpan(); + try { + Thread.sleep(MONITOR_INTERVAL); + monitor(); + errorCount.set(0); + } catch (InterruptedException e) { + logger.warn("Monitor thread interrupted", e); + Thread.currentThread().interrupt(); + break; + } catch (Exception e) { + handleMonitorError(span, e); + } finally { + span.end(); + } + } + }); + + backgroundThread.setName("MonitorService-Thread"); + backgroundThread.setDaemon(true); + backgroundThread.start(); + logger.info("Monitor service started successfully"); + } + + private void monitor() { + if (!initialized.get()) { + throw new IllegalStateException("Service not properly initialized"); + } + + if (!running.get()) { + throw new IllegalStateException("Service is not running"); + } + + validateSystemState(); + performMonitoring(); + } + + private void validateSystemState() { + Runtime runtime = Runtime.getRuntime(); + long freeMemory = runtime.freeMemory(); + long totalMemory = runtime.totalMemory(); + double memoryUsage = (double) (totalMemory - freeMemory) / totalMemory; + + if (memoryUsage > 0.9) { + throw new IllegalStateException("System memory usage too high: " + memoryUsage); + } + } + + private void performMonitoring() { + logger.debug("Performing system monitoring..."); + // Add actual monitoring logic here + } + + private void handleMonitorError(Span span, Exception e) { + span.recordException(e); + span.setStatus(StatusCode.ERROR); + logger.error("Monitor error occurred", e); + + int currentErrors = errorCount.incrementAndGet(); + if (currentErrors >= MAX_ERRORS) { + logger.error("Max error threshold reached. Stopping monitor service."); + stop(); + } + } + + @Override + public void stop() { + if (!running.compareAndSet(true, false)) { + return; + } + + if (backgroundThread != null) { + try { + backgroundThread.interrupt(); + backgroundThread.join(MONITOR_INTERVAL); + } catch (InterruptedException e) { + logger. \ No newline at end of file