From 85c7347899275b5a0b5fb5e695e3069300702750 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 15 Oct 2020 11:52:21 -0400 Subject: [PATCH] Add a command for dumping Redis SLOWLOG output. --- .../textsecuregcm/WhisperServerService.java | 2 + .../redis/FaultTolerantRedisCluster.java | 4 ++ .../workers/GetRedisSlowlogCommand.java | 54 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/workers/GetRedisSlowlogCommand.java diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index e803bc585..34838d15f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -155,6 +155,7 @@ import org.whispersystems.textsecuregcm.websocket.ProvisioningConnectListener; import org.whispersystems.textsecuregcm.websocket.WebSocketAccountAuthenticator; import org.whispersystems.textsecuregcm.workers.CertificateCommand; import org.whispersystems.textsecuregcm.workers.DeleteUserCommand; +import org.whispersystems.textsecuregcm.workers.GetRedisSlowlogCommand; import org.whispersystems.textsecuregcm.workers.VacuumCommand; import org.whispersystems.textsecuregcm.workers.ZkParamsCommand; import org.whispersystems.websocket.WebSocketResourceProviderFactory; @@ -189,6 +190,7 @@ public class WhisperServerService extends Application("accountdb", "accountsdb.xml") { @Override diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/redis/FaultTolerantRedisCluster.java b/service/src/main/java/org/whispersystems/textsecuregcm/redis/FaultTolerantRedisCluster.java index 408635cb2..89eb3cebb 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/redis/FaultTolerantRedisCluster.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/redis/FaultTolerantRedisCluster.java @@ -101,6 +101,10 @@ public class FaultTolerantRedisCluster { clusterClient.shutdown(); } + public String getName() { + return name; + } + public void useCluster(final Consumer> consumer) { useConnection(stringConnection, consumer); } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/workers/GetRedisSlowlogCommand.java b/service/src/main/java/org/whispersystems/textsecuregcm/workers/GetRedisSlowlogCommand.java new file mode 100644 index 000000000..2e7a877a6 --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/workers/GetRedisSlowlogCommand.java @@ -0,0 +1,54 @@ +package org.whispersystems.textsecuregcm.workers; + +import io.dropwizard.cli.ConfiguredCommand; +import io.dropwizard.setup.Bootstrap; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import org.whispersystems.textsecuregcm.WhisperServerConfiguration; +import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster; +import org.whispersystems.textsecuregcm.util.SystemMapper; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GetRedisSlowlogCommand extends ConfiguredCommand { + + public GetRedisSlowlogCommand() { + super("redisslowlog", "Dump a JSON blob describing slow Redis operations"); + } + + @Override + public void configure(final Subparser subparser) { + super.configure(subparser); + + subparser.addArgument("-n", "--entries") + .dest("entries") + .type(Integer.class) + .required(false) + .setDefault(128) + .help("The maximum number of SLOWLOG entries to retrieve per cluster node"); + } + + @Override + protected void run(final Bootstrap bootstrap, final Namespace namespace, final WhisperServerConfiguration config) throws Exception { + final int entries = namespace.getInt("entries"); + + final FaultTolerantRedisCluster cacheCluster = new FaultTolerantRedisCluster("main_cache_cluster", config.getCacheClusterConfiguration()); + final FaultTolerantRedisCluster messagesCacheCluster = new FaultTolerantRedisCluster("messages_cluster", config.getMessageCacheConfiguration().getRedisClusterConfiguration()); + final FaultTolerantRedisCluster metricsCluster = new FaultTolerantRedisCluster("metrics_cluster", config.getMetricsClusterConfiguration()); + + final Map> slowlogsByUri = new HashMap<>(); + + for (final FaultTolerantRedisCluster cluster : List.of(cacheCluster, messagesCacheCluster, metricsCluster)) { + cluster.useCluster(connection -> connection.sync() + .masters() + .commands() + .slowlogGet(entries) + .asMap() + .forEach((node, slowlogs) -> slowlogsByUri.put(node.getUri().toString(), slowlogs))); + } + + SystemMapper.getMapper().writeValue(System.out, slowlogsByUri); + } +}