Skip to content

Commit c2dc8ce

Browse files
committed
Add utility methods and Redis debug/monitoring features
Introduced `newHashMap` in `MapUtils` for simplified map creation. Enhanced `Redis` class with debug utilities (`getDebugInfo`, `getKeyspaceStats`, etc.) and a command monitoring feature. Improved error handling and logging for better diagnostics.
1 parent 6bf1e66 commit c2dc8ce

2 files changed

Lines changed: 152 additions & 5 deletions

File tree

src/main/java/io/github/intisy/utils/custom/external/Redis.java

Lines changed: 136 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22

33
import io.github.intisy.simple.logger.EmptyLogger;
44
import io.github.intisy.simple.logger.SimpleLogger;
5-
import redis.clients.jedis.JedisPubSub;
5+
import io.github.intisy.utils.utils.MapUtils;
6+
import redis.clients.jedis.*;
67
import redis.embedded.RedisServer;
7-
import redis.clients.jedis.Jedis;
8-
import redis.clients.jedis.JedisPool;
9-
import redis.clients.jedis.JedisPoolConfig;
108
import redis.clients.jedis.exceptions.JedisConnectionException;
119

1210
import java.io.IOException;
1311
import java.net.ServerSocket;
1412
import java.util.HashMap;
1513
import java.util.List;
1614
import java.util.Map;
15+
import java.util.Set;
1716
import java.util.concurrent.CopyOnWriteArrayList;
1817

1918
@SuppressWarnings("unused")
@@ -661,4 +660,136 @@ public void subscribe(String channel, MessageListener messageListener) {
661660
.add(messageListener);
662661
}
663662
}
664-
}
663+
664+
public Map<String, String> getDebugInfo() {
665+
if (useMockFallback) {
666+
Map<String, String> mockInfo = new HashMap<>();
667+
mockInfo.put("type", "mock");
668+
mockInfo.put("status", mockRedis.isRunning() ? "running" : "stopped");
669+
mockInfo.put("dataStoreSize", String.valueOf(mockRedis.dataStore.size()));
670+
mockInfo.put("subscribersCount", String.valueOf(mockRedis.subscribers.size()));
671+
return mockInfo;
672+
}
673+
674+
if (!isConnected()) {
675+
Map<String, String> disconnectedInfo = new HashMap<>();
676+
disconnectedInfo.put("status", "disconnected");
677+
disconnectedInfo.put("host", host);
678+
disconnectedInfo.put("port", String.valueOf(port));
679+
return disconnectedInfo;
680+
}
681+
682+
try (Jedis jedis = jedisPool.getResource()) {
683+
Map<String, String> info = new HashMap<>();
684+
info.put("type", useEmbedded ? "embedded" : "external");
685+
info.put("status", "connected");
686+
info.put("host", host);
687+
info.put("port", String.valueOf(port));
688+
info.put("clientList", getClientList());
689+
info.put("dbSize", String.valueOf(jedis.dbSize()));
690+
info.put("serverInfo", jedis.info());
691+
info.put("activeListeners", String.valueOf(dataListeners.size()));
692+
return info;
693+
} catch (Exception e) {
694+
logger.error("Error getting debug info", e);
695+
return MapUtils.newHashMap("error", e.getMessage());
696+
}
697+
}
698+
699+
public String getClientList() {
700+
if (useMockFallback) {
701+
return "Mock Redis - no real clients";
702+
}
703+
704+
if (!isConnected()) {
705+
return "Not connected to Redis server";
706+
}
707+
708+
try (Jedis jedis = jedisPool.getResource()) {
709+
return jedis.clientList();
710+
} catch (Exception e) {
711+
logger.error("Error getting client list", e);
712+
return "Error: " + e.getMessage();
713+
}
714+
}
715+
716+
public void printDebugStatus() {
717+
Map<String, String> debugInfo = getDebugInfo();
718+
logger.note("=== Redis Debug Status ===");
719+
debugInfo.forEach((key, value) -> {
720+
if (key.equals("serverInfo")) {
721+
logger.note("Server Info:");
722+
String[] infoLines = value.split("\n");
723+
for (String line : infoLines) {
724+
if (!line.trim().isEmpty()) {
725+
logger.note(" " + line);
726+
}
727+
}
728+
} else {
729+
logger.note(key + ": " + value);
730+
}
731+
});
732+
logger.note("======================");
733+
}
734+
735+
public Map<String, Long> getKeyspaceStats() {
736+
if (useMockFallback) {
737+
return MapUtils.newHashMap("total_keys", (long) mockRedis.dataStore.size());
738+
}
739+
740+
if (!isConnected()) {
741+
return MapUtils.newHashMap("error", -1L);
742+
}
743+
744+
try (Jedis jedis = jedisPool.getResource()) {
745+
Map<String, Long> stats = new HashMap<>();
746+
stats.put("total_keys", jedis.dbSize());
747+
748+
// Get key patterns statistics
749+
Set<String> keys = jedis.keys("*");
750+
stats.put("string_keys", keys.stream()
751+
.filter(k -> jedis.type(k).equals("string"))
752+
.count());
753+
stats.put("list_keys", keys.stream()
754+
.filter(k -> jedis.type(k).equals("list"))
755+
.count());
756+
stats.put("set_keys", keys.stream()
757+
.filter(k -> jedis.type(k).equals("set"))
758+
.count());
759+
stats.put("hash_keys", keys.stream()
760+
.filter(k -> jedis.type(k).equals("hash"))
761+
.count());
762+
763+
return stats;
764+
} catch (Exception e) {
765+
logger.error("Error getting keyspace stats", e);
766+
return MapUtils.newHashMap("error", -1L);
767+
}
768+
}
769+
770+
public void monitorCommands() {
771+
if (useMockFallback) {
772+
logger.note("Command monitoring not available in mock mode");
773+
return;
774+
}
775+
776+
if (!isConnected()) {
777+
logger.error("Not connected to Redis server. Cannot monitor commands.");
778+
return;
779+
}
780+
781+
new Thread(() -> {
782+
try (Jedis jedis = jedisPool.getResource()) {
783+
logger.note("Starting Redis command monitor...");
784+
jedis.monitor(new JedisMonitor() {
785+
@Override
786+
public void onCommand(String command) {
787+
logger.note("Redis Command: " + command);
788+
}
789+
});
790+
} catch (Exception e) {
791+
logger.error("Error in command monitor", e);
792+
}
793+
}, "Redis-Monitor").start();
794+
}
795+
}

src/main/java/io/github/intisy/utils/utils/MapUtils.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.intisy.utils.utils;
22

3+
import java.util.HashMap;
34
import java.util.LinkedHashMap;
45

56
/**
@@ -21,4 +22,19 @@ public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Object... keysAndValue
2122
}
2223
return map;
2324
}
25+
26+
public static <K, V> HashMap<K, V> newHashMap(Object... keysAndValues) {
27+
if (keysAndValues.length % 2 != 0) {
28+
throw new IllegalArgumentException("Must provide key-value pairs.");
29+
}
30+
HashMap<K, V> map = new HashMap<>();
31+
for (int i = 0; i < keysAndValues.length; i += 2) {
32+
@SuppressWarnings("unchecked")
33+
K key = (K) keysAndValues[i];
34+
@SuppressWarnings("unchecked")
35+
V value = (V) keysAndValues[i + 1];
36+
map.put(key, value);
37+
}
38+
return map;
39+
}
2440
}

0 commit comments

Comments
 (0)