Merge branch 'slowlog' of git://github.com/ivowiblo/jedis into slowlog
Conflicts: src/main/java/redis/clients/jedis/BinaryClient.java src/main/java/redis/clients/jedis/BinaryJedis.java src/main/java/redis/clients/jedis/Jedis.java src/main/java/redis/clients/jedis/Protocol.java
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -25,143 +25,141 @@ public final class Protocol {
|
|||||||
public static final byte COLON_BYTE = ':';
|
public static final byte COLON_BYTE = ':';
|
||||||
|
|
||||||
private Protocol() {
|
private Protocol() {
|
||||||
// this prevent the class from instantiation
|
// this prevent the class from instantiation
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendCommand(final RedisOutputStream os,
|
public static void sendCommand(final RedisOutputStream os,
|
||||||
final Command command,
|
final Command command, final byte[]... args) {
|
||||||
final byte[]... args) {
|
sendCommand(os, command.raw, args);
|
||||||
sendCommand(os, command.raw, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendCommand(final RedisOutputStream os,
|
private static void sendCommand(final RedisOutputStream os,
|
||||||
final byte[] command,
|
final byte[] command, final byte[]... args) {
|
||||||
final byte[]... args) {
|
try {
|
||||||
try {
|
os.write(ASTERISK_BYTE);
|
||||||
os.write(ASTERISK_BYTE);
|
os.writeIntCrLf(args.length + 1);
|
||||||
os.writeIntCrLf(args.length + 1);
|
os.write(DOLLAR_BYTE);
|
||||||
os.write(DOLLAR_BYTE);
|
os.writeIntCrLf(command.length);
|
||||||
os.writeIntCrLf(command.length);
|
os.write(command);
|
||||||
os.write(command);
|
os.writeCrLf();
|
||||||
os.writeCrLf();
|
|
||||||
|
|
||||||
for (final byte[] arg : args) {
|
for (final byte[] arg : args) {
|
||||||
os.write(DOLLAR_BYTE);
|
os.write(DOLLAR_BYTE);
|
||||||
os.writeIntCrLf(arg.length);
|
os.writeIntCrLf(arg.length);
|
||||||
os.write(arg);
|
os.write(arg);
|
||||||
os.writeCrLf();
|
os.writeCrLf();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new JedisConnectionException(e);
|
throw new JedisConnectionException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processError(final RedisInputStream is) {
|
private static void processError(final RedisInputStream is) {
|
||||||
String message = is.readLine();
|
String message = is.readLine();
|
||||||
throw new JedisDataException(message);
|
throw new JedisDataException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object process(final RedisInputStream is) {
|
private static Object process(final RedisInputStream is) {
|
||||||
try {
|
try {
|
||||||
byte b = is.readByte();
|
byte b = is.readByte();
|
||||||
if (b == MINUS_BYTE) {
|
if (b == MINUS_BYTE) {
|
||||||
processError(is);
|
processError(is);
|
||||||
} else if (b == ASTERISK_BYTE) {
|
} else if (b == ASTERISK_BYTE) {
|
||||||
return processMultiBulkReply(is);
|
return processMultiBulkReply(is);
|
||||||
} else if (b == COLON_BYTE) {
|
} else if (b == COLON_BYTE) {
|
||||||
return processInteger(is);
|
return processInteger(is);
|
||||||
} else if (b == DOLLAR_BYTE) {
|
} else if (b == DOLLAR_BYTE) {
|
||||||
return processBulkReply(is);
|
return processBulkReply(is);
|
||||||
} else if (b == PLUS_BYTE) {
|
} else if (b == PLUS_BYTE) {
|
||||||
return processStatusCodeReply(is);
|
return processStatusCodeReply(is);
|
||||||
} else {
|
} else {
|
||||||
throw new JedisConnectionException("Unknown reply: " + (char) b);
|
throw new JedisConnectionException("Unknown reply: " + (char) b);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new JedisConnectionException(e);
|
throw new JedisConnectionException(e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] processStatusCodeReply(final RedisInputStream is) {
|
private static byte[] processStatusCodeReply(final RedisInputStream is) {
|
||||||
return SafeEncoder.encode(is.readLine());
|
return SafeEncoder.encode(is.readLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] processBulkReply(final RedisInputStream is) {
|
private static byte[] processBulkReply(final RedisInputStream is) {
|
||||||
int len = Integer.parseInt(is.readLine());
|
int len = Integer.parseInt(is.readLine());
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
byte[] read = new byte[len];
|
byte[] read = new byte[len];
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
try {
|
try {
|
||||||
while (offset < len) {
|
while (offset < len) {
|
||||||
offset += is.read(read, offset, (len - offset));
|
offset += is.read(read, offset, (len - offset));
|
||||||
}
|
}
|
||||||
// read 2 more bytes for the command delimiter
|
// read 2 more bytes for the command delimiter
|
||||||
is.readByte();
|
is.readByte();
|
||||||
is.readByte();
|
is.readByte();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new JedisConnectionException(e);
|
throw new JedisConnectionException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Long processInteger(final RedisInputStream is) {
|
private static Long processInteger(final RedisInputStream is) {
|
||||||
String num = is.readLine();
|
String num = is.readLine();
|
||||||
return Long.valueOf(num);
|
return Long.valueOf(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Object> processMultiBulkReply(final RedisInputStream is) {
|
private static List<Object> processMultiBulkReply(final RedisInputStream is) {
|
||||||
int num = Integer.parseInt(is.readLine());
|
int num = Integer.parseInt(is.readLine());
|
||||||
if (num == -1) {
|
if (num == -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
List<Object> ret = new ArrayList<Object>(num);
|
List<Object> ret = new ArrayList<Object>(num);
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
try{
|
try {
|
||||||
ret.add(process(is));
|
ret.add(process(is));
|
||||||
}catch(JedisDataException e){
|
} catch (JedisDataException e) {
|
||||||
ret.add(e);
|
ret.add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object read(final RedisInputStream is) {
|
public static Object read(final RedisInputStream is) {
|
||||||
return process(is);
|
return process(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] toByteArray(final int value) {
|
public static final byte[] toByteArray(final int value) {
|
||||||
return SafeEncoder.encode(String.valueOf(value));
|
return SafeEncoder.encode(String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] toByteArray(final long value) {
|
public static final byte[] toByteArray(final long value) {
|
||||||
return SafeEncoder.encode(String.valueOf(value));
|
return SafeEncoder.encode(String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] toByteArray(final double value) {
|
public static final byte[] toByteArray(final double value) {
|
||||||
return SafeEncoder.encode(String.valueOf(value));
|
return SafeEncoder.encode(String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Command {
|
public static enum Command {
|
||||||
PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT;
|
PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG;
|
||||||
|
|
||||||
public final byte[] raw;
|
public final byte[] raw;
|
||||||
|
|
||||||
Command() {
|
Command() {
|
||||||
raw = SafeEncoder.encode(this.name());
|
raw = SafeEncoder.encode(this.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Keyword {
|
public static enum Keyword {
|
||||||
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, FLUSH, EXISTS, LOAD, KILL;
|
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, RESET, FLUSH, EXISTS, LOAD, KILL, LEN;
|
||||||
public final byte[] raw;
|
public final byte[] raw;
|
||||||
|
|
||||||
Keyword() {
|
Keyword() {
|
||||||
raw = SafeEncoder.encode(this.name().toLowerCase());
|
raw = SafeEncoder.encode(this.name().toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
src/main/java/redis/clients/util/Slowlog.java
Normal file
53
src/main/java/redis/clients/util/Slowlog.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package redis.clients.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Slowlog {
|
||||||
|
private final long id;
|
||||||
|
private final long timeStamp;
|
||||||
|
private final long executionTime;
|
||||||
|
private final List<String> args;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static List<Slowlog> from(List<Object> nestedMultiBulkReply){
|
||||||
|
List<Slowlog> logs = new ArrayList<Slowlog>(nestedMultiBulkReply.size());
|
||||||
|
for(Object obj : nestedMultiBulkReply){
|
||||||
|
List<Object> properties = (List<Object>)obj;
|
||||||
|
logs.add(new Slowlog(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
return logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Slowlog(List<Object> properties) {
|
||||||
|
super();
|
||||||
|
this.id = (Long)properties.get(0);
|
||||||
|
this.timeStamp = (Long)properties.get(1);
|
||||||
|
this.executionTime = (Long)properties.get(2);
|
||||||
|
|
||||||
|
List<byte[]> bargs = (List<byte[]>)properties.get(3);
|
||||||
|
this.args = new ArrayList<String>(bargs.size());
|
||||||
|
|
||||||
|
for(byte[] barg:bargs){
|
||||||
|
this.args.add(SafeEncoder.encode(barg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeStamp() {
|
||||||
|
return timeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getExecutionTime() {
|
||||||
|
return executionTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package redis.clients.jedis.tests.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import redis.clients.util.Slowlog;
|
||||||
|
|
||||||
|
public class SlowlogCommandsTest extends JedisCommandTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void slowlog() {
|
||||||
|
//do something
|
||||||
|
jedis.set("foo", "bar");
|
||||||
|
jedis.set("foo2", "bar2");
|
||||||
|
|
||||||
|
List<Slowlog> reducedLog = jedis.slowlogGet(1);
|
||||||
|
assertEquals(1, reducedLog.size());
|
||||||
|
|
||||||
|
Slowlog log = reducedLog.get(0);
|
||||||
|
assertTrue(log.getId() > 0);
|
||||||
|
assertTrue(log.getTimeStamp() > 0);
|
||||||
|
assertTrue(log.getExecutionTime() > 0);
|
||||||
|
assertNotNull(log.getArgs());
|
||||||
|
|
||||||
|
List<byte[]> breducedLog = jedis.slowlogGetBinary(1);
|
||||||
|
assertEquals(1, breducedLog.size());
|
||||||
|
|
||||||
|
List<Slowlog> log1 = jedis.slowlogGet();
|
||||||
|
List<byte[]> blog1 = jedis.slowlogGetBinary();
|
||||||
|
|
||||||
|
assertNotNull(log1);
|
||||||
|
assertNotNull(blog1);
|
||||||
|
|
||||||
|
long len1 = jedis.slowlogLen();
|
||||||
|
|
||||||
|
jedis.slowlogReset();
|
||||||
|
|
||||||
|
List<Slowlog> log2 = jedis.slowlogGet();
|
||||||
|
List<byte[]> blog2 = jedis.slowlogGetBinary();
|
||||||
|
long len2 = jedis.slowlogLen();
|
||||||
|
|
||||||
|
assertTrue(len1 > len2);
|
||||||
|
assertTrue(log1.size() > log2.size());
|
||||||
|
assertTrue(blog1.size() > blog2.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user