Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -1,77 +1,110 @@
package org.springframework.samples.petclinic.errors;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import java.util.InvalidPropertiesFormatException;
import java.util.Objects;

@Component
public class MonitorService implements SmartLifecycle {

private boolean running = false;
private Thread backgroundThread;
@Autowired
private OpenTelemetry openTelemetry;
private static final Logger logger = LoggerFactory.getLogger(MonitorService.class);
private static final String MONITOR_NAME = "MonitorService";
private static final long MONITORING_INTERVAL = 5000;

@Override
public void start() {
var otelTracer = openTelemetry.getTracer("MonitorService");
private boolean running = false;
private Thread backgroundThread;

running = true;
backgroundThread = new Thread(() -> {
while (running) {
@Autowired
private OpenTelemetry openTelemetry;

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Span span = otelTracer.spanBuilder("monitor").startSpan();
@Override
public void start() {
if (openTelemetry == null) {
logger.error("OpenTelemetry instance not initialized");
throw new IllegalStateException("OpenTelemetry instance not initialized");
}

try {
var otelTracer = openTelemetry.getTracer(MONITOR_NAME);
running = true;
backgroundThread = new Thread(() -> {
while (running) {
try {
Thread.sleep(MONITORING_INTERVAL);
} catch (InterruptedException e) {
logger.warn("Monitoring thread interrupted", e);
Thread.currentThread().interrupt();
break;
}

System.out.println("Background service is running...");
monitor();
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR);
} finally {
span.end();
}
}
});
Span span = otelTracer.spanBuilder("monitor")
.setAttribute("service.name", MONITOR_NAME)
.setAttribute("monitoring.interval", MONITORING_INTERVAL)
.startSpan();

// Start the background thread
backgroundThread.start();
System.out.println("Background service started.");
}
try {
validateMonitoringState();
logger.debug("Background service is running...");
monitor();
span.setStatus(StatusCode.OK);
} catch (InvalidPropertiesFormatException e) {
logger.error("Invalid properties in monitoring", e);
span.recordException(e);
span.setStatus(StatusCode.ERROR, "Invalid properties format");
} catch (IllegalStateException e) {
logger.error("Monitoring state error", e);
span.recordException(e);
span.setStatus(StatusCode.ERROR, "Monitor failure");
} catch (Exception e) {
logger.error("Unexpected error during monitoring", e);
span.recordException(e);
span.setStatus(StatusCode.ERROR, "Unexpected monitoring error");
} finally {
span.end();
}
}
});

private void monitor() throws InvalidPropertiesFormatException {
Utils.throwException(IllegalStateException.class,"monitor failure");
}
backgroundThread.setName("MonitorService-Thread");
backgroundThread.start();
logger.info("Background service started");
}

private void validateMonitoringState() {
Objects.requireNonNull(openTelemetry, "OpenTelemetry must not be null");
if (!running) {
throw new IllegalStateException("Monitor service is not running");
}
}

private void monitor() throws InvalidPropertiesFormatException {
Span span = Span.current();
span.setAttributes(
Attributes.of(
AttributeKey.stringKey("monitor.status"), "active",
AttributeKey.longKey("monitor.timestamp"), System.currentTimeMillis()
)
);
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;
}
}
@Override
public void stop() {
running = false;
if (backgroundThread != null) {
try {
backgroundThread.interrupt();
backgroundThread.join(MONITORING_INTERVAL);
logger.info("Background service stopped gracefully");
} catch (InterruptedException e) {
logger.warn("Interrupted while stopping background service", e);
Thread.
11 changes: 11 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,14 @@ logging.level.org.springframework=INFO

# Maximum time static resources should be cached
spring.web.resources.cache.cachecontrol.max-age=12h

# OpenTelemetry Configuration
otel.service.name=petclinic-service
otel.traces.exporter=otlp
otel.metrics.exporter=otlp
otel.logs.exporter=otlp
otel.exporter.otlp.endpoint=http://localhost:4317
otel.resource.attributes.environment=production
otel.resource.attributes.deployment.region=us-west
otel.resource.attributes.service.version=1.0.0
otel.resource.attributes.service.instance.id=${random.uuid}
Loading