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() {

Reply via email to