AwsMetricsService.java — polls CloudWatch every 60s, pushes via WebSocket
@Service @Slf4j @RequiredArgsConstructor
public class AwsMetricsService {
private final CloudWatchClient cloudWatchClient;
private final SimpMessagingTemplate broker; // pushes to /topic/alerts
private final Map<String, Double> thresholds = new ConcurrentHashMap<>();
// Called every 60s by Spring's @Scheduled task executor
@Scheduled(fixedDelay = 60_000)
public void pollAndEvaluate() {
SERVICES.forEach(svc -> {
List<MetricDataPoint> pts = getMetrics(svc, "1h");
pts.stream()
.filter(p -> p.getAverage() > thresholds.getOrDefault(svc, 80.0))
.findFirst()
.ifPresent(p -> fireAlert(svc, p.getAverage()));
});
}
private void fireAlert(String svc, double value) {
Map<String, Object> payload = Map.of(
"service", svc, "value", value,
"severity", value > 90 ? "CRITICAL" : "WARNING",
"firedAt", Instant.now().toString()
);
broker.convertAndSend("/topic/alerts", payload); // pushed to all WebSocket clients
log.warn("ALERT {} → CPU {}", svc, value);
}
}