Skip to content

Instantly share code, notes, and snippets.

@gbzarelli
Last active August 26, 2025 13:34
Show Gist options
  • Select an option

  • Save gbzarelli/d9a37ea90bc5437f224744281c34e80b to your computer and use it in GitHub Desktop.

Select an option

Save gbzarelli/d9a37ea90bc5437f224744281c34e80b to your computer and use it in GitHub Desktop.
Monitoramento de Registros Pendentes e Atrasos usando Redis e Micrometer #helpdev-blog
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class StatusDelayMonitorService {
private static final String HASH_NAME = "registros_pendentes";
private static final long LIMITE_ATRASO_MS = 3_600_000; // 1 hora
private final Counter atrasoCounter;
private final HashOperations<String, String, String> hashOps;
@Autowired
public StatusDelayMonitorService(RedisTemplate<String, String> redisTemplate, MeterRegistry meterRegistry) {
this.hashOps = redisTemplate.opsForHash();
this.atrasoCounter = Counter.builder("registro.atrasos")
.description("Eventos que excederam tempo máximo aguardando status B")
.register(meterRegistry);
// Gauge que retorna o tamanho diretamente do Redis, sem variável intermediária
Gauge.builder("registros.pendentes", this, s -> s.getPendentesCount())
.description("Quantidade de registros pendentes em tempo real aguardando status B")
.register(meterRegistry);
}
// 1. Registrar chegada com status A
public void onStatusA(String registroId) {
hashOps.put(HASH_NAME, registroId, String.valueOf(System.currentTimeMillis()));
}
// 2. Remover ao chegar status B
public void onStatusB(String registroId) {
hashOps.delete(HASH_NAME, registroId);
}
// 3. Verificação periódica de atrasos
@Scheduled(fixedRate = 60_000)
public void verificarAtrasos() {
long now = System.currentTimeMillis();
Map<String, String> registros = hashOps.entries(HASH_NAME);
for (Map.Entry<String, String> entry : registros.entrySet()) {
String id = entry.getKey();
long timestamp = Long.parseLong(entry.getValue());
if ((now - timestamp) > LIMITE_ATRASO_MS) {
// Esta métrica será utilizada pelo sistema de monitoramento para disparar alarmes de atraso.
atrasoCounter.increment();
// Opcional: hashOps.delete(HASH_NAME, id);
}
}
}
// Micrometer chama este método para atualizar a Gauge
public int getPendentesCount() {
return (int) hashOps.size(HASH_NAME);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment