Added more sensors from the `redis-cli info stats` command
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/dc04ab27 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/dc04ab27 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/dc04ab27 Branch: refs/heads/0.5.0 Commit: dc04ab27150c392ee417af27134eb885269fb1e3 Parents: 657047f Author: Andrew Kennedy <[email protected]> Authored: Tue Apr 23 00:34:33 2013 +0100 Committer: Andrew Kennedy <[email protected]> Committed: Wed Apr 24 13:25:45 2013 +0100 ---------------------------------------------------------------------- .../entity/nosql/redis/RedisClusterImpl.java | 15 +++- .../entity/nosql/redis/RedisShardImpl.java | 4 +- .../entity/nosql/redis/RedisSlaveImpl.java | 4 +- .../brooklyn/entity/nosql/redis/RedisStore.java | 8 +++ .../entity/nosql/redis/RedisStoreDriver.java | 3 +- .../entity/nosql/redis/RedisStoreImpl.java | 73 +++++++++++++++----- .../entity/nosql/redis/RedisStoreSshDriver.java | 2 +- 7 files changed, 81 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisClusterImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisClusterImpl.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisClusterImpl.java index 6a5e6ff..eda1614 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisClusterImpl.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisClusterImpl.java @@ -23,13 +23,13 @@ public class RedisClusterImpl extends AbstractEntity implements RedisCluster { public RedisClusterImpl() { this(MutableMap.of(), null); } - public RedisClusterImpl(Map properties) { + public RedisClusterImpl(Map<?, ?> properties) { this(properties, null); } public RedisClusterImpl(Entity parent) { this(MutableMap.of(), parent); } - public RedisClusterImpl(Map properties, Entity parent) { + public RedisClusterImpl(Map<?, ?> properties, Entity parent) { super(properties, parent); } @@ -43,7 +43,7 @@ public class RedisClusterImpl extends AbstractEntity implements RedisCluster { .configure(DynamicCluster.MEMBER_SPEC, EntitySpecs.spec(RedisSlave.class).configure(RedisSlave.MASTER, master))); slaves.start(locations); - setAttribute(Startable.SERVICE_UP, true); + setAttribute(Startable.SERVICE_UP, calculateServiceUp()); } @Override @@ -58,4 +58,13 @@ public class RedisClusterImpl extends AbstractEntity implements RedisCluster { public void restart() { throw new UnsupportedOperationException(); } + + protected boolean calculateServiceUp() { + boolean up = false; + for (Entity member : slaves.getMembers()) { + if (Boolean.TRUE.equals(member.getAttribute(SERVICE_UP))) up = true; + } + return up; + } + } http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisShardImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisShardImpl.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisShardImpl.java index 0eee09f..8b03903 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisShardImpl.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisShardImpl.java @@ -10,13 +10,13 @@ public class RedisShardImpl extends AbstractEntity implements RedisShard { public RedisShardImpl() { this(MutableMap.of(), null); } - public RedisShardImpl(Map properties) { + public RedisShardImpl(Map<?, ?> properties) { this(properties, null); } public RedisShardImpl(Entity parent) { this(MutableMap.of(), parent); } - public RedisShardImpl(Map properties, Entity parent) { + public RedisShardImpl(Map<?, ?> properties, Entity parent) { super(properties, parent); } } http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisSlaveImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisSlaveImpl.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisSlaveImpl.java index c0718b9..e205fb2 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisSlaveImpl.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisSlaveImpl.java @@ -15,13 +15,13 @@ public class RedisSlaveImpl extends RedisStoreImpl implements RedisSlave { public RedisSlaveImpl() { this(MutableMap.of(), null); } - public RedisSlaveImpl(Map properties) { + public RedisSlaveImpl(Map<?, ?> properties) { this(properties, null); } public RedisSlaveImpl(Entity parent) { this(MutableMap.of(), parent); } - public RedisSlaveImpl(Map properties, Entity parent) { + public RedisSlaveImpl(Map<?, ?> properties, Entity parent) { super(properties, parent); } http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStore.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStore.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStore.java index 3717ffc..a972c5a 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStore.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStore.java @@ -39,6 +39,14 @@ public interface RedisStore extends SoftwareProcess, DataStore { AttributeSensor<Integer> UPTIME = new BasicAttributeSensor<Integer>(Integer.class, "redis.uptime", "Redis uptime in seconds"); + // See http://redis.io/commands/info for details of all information available + AttributeSensor<Integer> TOTAL_CONNECTIONS_RECEIVED = new BasicAttributeSensor<Integer>(Integer.class, "redis.connections.received.total", "Total number of connections accepted by the server"); + AttributeSensor<Integer> TOTAL_COMMANDS_PROCESSED = new BasicAttributeSensor<Integer>(Integer.class, "redis.commands.processed.total", "Total number of commands processed by the server"); + AttributeSensor<Integer> EXPIRED_KEYS = new BasicAttributeSensor<Integer>(Integer.class, "redis.keys.expired", "Total number of key expiration events"); + AttributeSensor<Integer> EVICTED_KEYS = new BasicAttributeSensor<Integer>(Integer.class, "redis.keys.evicted", "Number of evicted keys due to maxmemory limit"); + AttributeSensor<Integer> KEYSPACE_HITS = new BasicAttributeSensor<Integer>(Integer.class, "redis.keyspace.hits", "Number of successful lookup of keys in the main dictionary"); + AttributeSensor<Integer> KEYSPACE_MISSES = new BasicAttributeSensor<Integer>(Integer.class, "redis.keyspace.misses", "Number of failed lookup of keys in the main dictionary"); + String getAddress(); Integer getRedisPort(); http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreDriver.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreDriver.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreDriver.java index c0d57b4..d8a1610 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreDriver.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreDriver.java @@ -3,6 +3,7 @@ package brooklyn.entity.nosql.redis; import brooklyn.entity.basic.SoftwareProcessDriver; public interface RedisStoreDriver extends SoftwareProcessDriver { - + String getRunDir(); + } http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreImpl.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreImpl.java index ac8b5aa..a47c0ac 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreImpl.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreImpl.java @@ -11,6 +11,7 @@ import brooklyn.entity.Entity; import brooklyn.entity.basic.SoftwareProcessImpl; import brooklyn.event.feed.ssh.SshFeed; import brooklyn.event.feed.ssh.SshPollConfig; +import brooklyn.event.feed.ssh.SshPollValue; import brooklyn.event.feed.ssh.SshValueFunctions; import brooklyn.location.Location; import brooklyn.location.MachineLocation; @@ -26,8 +27,6 @@ import com.google.common.collect.Iterables; /** * An entity that represents a Redis key-value store service. - * - * TODO add sensors with Redis statistics using INFO command */ public class RedisStoreImpl extends SoftwareProcessImpl implements RedisStore { protected static final Logger LOG = LoggerFactory.getLogger(RedisStore.class); @@ -37,16 +36,16 @@ public class RedisStoreImpl extends SoftwareProcessImpl implements RedisStore { public RedisStoreImpl() { this(MutableMap.of(), null); } - public RedisStoreImpl(Map properties) { + public RedisStoreImpl(Map<?, ?> properties) { this(properties, null); } public RedisStoreImpl(Entity parent) { this(MutableMap.of(), parent); } - public RedisStoreImpl(Map properties, Entity parent) { + public RedisStoreImpl(Map<?, ?> properties, Entity parent) { super(properties, parent); } - + @Override protected void connectSensors() { super.connectSensors(); @@ -57,29 +56,65 @@ public class RedisStoreImpl extends SoftwareProcessImpl implements RedisStore { Optional<Location> location = Iterables.tryFind(getLocations(), Predicates.instanceOf(SshMachineLocation.class)); if (!location.isPresent()) throw new IllegalStateException("Could not find SshMachineLocation in list of locations"); SshMachineLocation machine = (SshMachineLocation) location.get(); + String statsCommand = getDriver().getRunDir() + "/bin/redis-cli info stats"; sshFeed = SshFeed.builder() .entity(this) .machine(machine) .poll(new SshPollConfig<Integer>(UPTIME) - .command(getDriver().getRunDir() + "/bin/redis-cli info") + .command(getDriver().getRunDir() + "/bin/redis-cli info server") + .onError(Functions.constant(-1)) + .onSuccess(infoFunction("uptime_in_seconds"))) + .poll(new SshPollConfig<Integer>(TOTAL_CONNECTIONS_RECEIVED) + .command(statsCommand) + .onError(Functions.constant(-1)) + .onSuccess(infoFunction("total_connections_received"))) + .poll(new SshPollConfig<Integer>(TOTAL_COMMANDS_PROCESSED) + .command(statsCommand) + .onError(Functions.constant(-1)) + .onSuccess(infoFunction("total_commands_processed"))) + .poll(new SshPollConfig<Integer>(EXPIRED_KEYS) + .command(statsCommand) + .onError(Functions.constant(-1)) + .onSuccess(infoFunction("expired_keys"))) + .poll(new SshPollConfig<Integer>(EVICTED_KEYS) + .command(statsCommand) .onError(Functions.constant(-1)) - .onSuccess(Functions.compose(new Function<String, Integer>(){ - @Override - public Integer apply(@Nullable String input) { - Optional<String> line = Iterables.tryFind(Splitter.on('\n').split(input), Predicates.containsPattern("uptime_in_seconds:")); - if (line.isPresent()) { - String data = line.get().trim(); - int colon = data.indexOf(":"); - return Integer.parseInt(data.substring(colon + 1)); - } else { - throw new IllegalStateException(); - } - } - }, SshValueFunctions.stdout()))) + .onSuccess(infoFunction("evicted_keys"))) + .poll(new SshPollConfig<Integer>(KEYSPACE_HITS) + .command(statsCommand) + .onError(Functions.constant(-1)) + .onSuccess(infoFunction("keyspace_hits"))) + .poll(new SshPollConfig<Integer>(KEYSPACE_MISSES) + .command(statsCommand) + .onError(Functions.constant(-1)) + .onSuccess(infoFunction("keyspace_misses"))) .build(); } + /** + * Create a {@link Function} to retrieve a particular field value from a {@code redis-cli info} + * command. + * + * @param field the info field to retrieve and convert + * @return a new function that converts a {@link SshPollValue} to an {@link Integer} + */ + private static Function<SshPollValue, Integer> infoFunction(final String field) { + return Functions.compose(new Function<String, Integer>() { + @Override + public Integer apply(@Nullable String input) { + Optional<String> line = Iterables.tryFind(Splitter.on('\n').split(input), Predicates.containsPattern(field + ":")); + if (line.isPresent()) { + String data = line.get().trim(); + int colon = data.indexOf(":"); + return Integer.parseInt(data.substring(colon + 1)); + } else { + throw new IllegalStateException("Data for field "+field+" not found: "+input); + } + } + }, SshValueFunctions.stdout()); + } + @Override public void disconnectSensors() { super.disconnectSensors(); http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/dc04ab27/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java index 9b17057..16dc0d9 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java @@ -71,7 +71,7 @@ public class RedisStoreSshDriver extends AbstractSoftwareProcessSshDriver implem .body.append("./bin/redis-server redis.conf") .execute(); } - + @Override public boolean isRunning() {
