Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
e1f6e0ad60 | |||
e77d4d915d | |||
0a0748172e | |||
8febd14eb6 | |||
2cf5dff011 | |||
30e1bf70d9 | |||
f1c53077a4 | |||
5a4b3cb38a | |||
5487e2dd71 |
10
README.md
10
README.md
@ -30,8 +30,14 @@ Usage
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
* Create data adapter, cache (or not), lookup table
|
* Create data adapter, cache (or not), lookup table
|
||||||
* Use 'lookup_set_value(lookup_table, key, value)' to create or update key in redis
|
* Use 'lookup_set_value(lookup_table, key, value, [ttl])' to create or update key in redis
|
||||||
* Use 'lookup(lookup_table, key)' to get key
|
* Use 'lookup_value(lookup_table, key)' to get key value
|
||||||
|
* Use 'lookup_clear_key(lookup_table, key)' to remove key
|
||||||
|
* Use 'lookup_has_value(lookup_table, key)' to test key existence
|
||||||
|
* Use 'lookup_assign_ttl(lookup_table, key, ttl)' to change TTL of existing key
|
||||||
|
|
||||||
|
By default keys will be created in Redis with the default TTL defined at data adapter creation time
|
||||||
|
|
||||||
|
|
||||||
Getting started
|
Getting started
|
||||||
---------------
|
---------------
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<groupId>in.nosd.redis</groupId>
|
<groupId>in.nosd.redis</groupId>
|
||||||
<artifactId>graylog-plugin-redis-lookup</artifactId>
|
<artifactId>graylog-plugin-redis-lookup</artifactId>
|
||||||
<name>${project.artifactId}</name>
|
<name>${project.artifactId}</name>
|
||||||
<version>1.0.0</version>
|
<version>1.0.2</version>
|
||||||
<description>Graylog ${project.artifactId} plugin.</description>
|
<description>Graylog ${project.artifactId} plugin.</description>
|
||||||
<url>https://www.graylog.org</url>
|
<url>https://www.graylog.org</url>
|
||||||
<developers>
|
<developers>
|
||||||
|
2
pom.xml
2
pom.xml
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<groupId>in.nosd.redis</groupId>
|
<groupId>in.nosd.redis</groupId>
|
||||||
<artifactId>graylog-plugin-redis-lookup</artifactId>
|
<artifactId>graylog-plugin-redis-lookup</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.2</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>${project.artifactId}</name>
|
<name>${project.artifactId}</name>
|
||||||
|
@ -68,6 +68,7 @@ public class RedisLookupDataAdapter extends LookupDataAdapter {
|
|||||||
private final Config config;
|
private final Config config;
|
||||||
private final RedisClient client;
|
private final RedisClient client;
|
||||||
private RedisCommands<String, String> commands;
|
private RedisCommands<String, String> commands;
|
||||||
|
private StatefulRedisConnection<String, String> connection;
|
||||||
private final Timer redisGetRequestTimer;
|
private final Timer redisGetRequestTimer;
|
||||||
private final Meter redisGetRequestErrors;
|
private final Meter redisGetRequestErrors;
|
||||||
private final Timer redisSetRequestTimer;
|
private final Timer redisSetRequestTimer;
|
||||||
@ -99,19 +100,19 @@ public class RedisLookupDataAdapter extends LookupDataAdapter {
|
|||||||
this.redisSetRequestErrors = metricRegistry.meter(MetricRegistry.name(getClass(), "redisSetRequestErrors"));
|
this.redisSetRequestErrors = metricRegistry.meter(MetricRegistry.name(getClass(), "redisSetRequestErrors"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add code to initialise Redis connection
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStart() throws Exception {
|
protected void doStart() throws Exception {
|
||||||
StatefulRedisConnection<String, String> connection = this.client.connect();
|
connection = this.client.connect();
|
||||||
this.commands = connection.sync();
|
this.commands = connection.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add code to close Redis connection
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception {
|
protected void doStop() throws Exception {
|
||||||
|
connection.close();
|
||||||
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the refresh interval for this data adapter. Use {@link Duration#ZERO} if refresh should be disabled.
|
||||||
@Override
|
@Override
|
||||||
public Duration refreshInterval() {
|
public Duration refreshInterval() {
|
||||||
return REFRESH_INTERVAL_DURATION;
|
return REFRESH_INTERVAL_DURATION;
|
||||||
@ -134,7 +135,7 @@ public class RedisLookupDataAdapter extends LookupDataAdapter {
|
|||||||
try {
|
try {
|
||||||
final String value = this.commands.get(trimmedKey);
|
final String value = this.commands.get(trimmedKey);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
LOG.warn("Redis GET request for key <{}> returned null, key do not exists.", trimmedKey);
|
LOG.debug("Redis GET request for key <{}> returned null, key do not exists.", trimmedKey);
|
||||||
redisGetRequestErrors.mark();
|
redisGetRequestErrors.mark();
|
||||||
return LookupResult.empty();
|
return LookupResult.empty();
|
||||||
}
|
}
|
||||||
@ -149,31 +150,115 @@ public class RedisLookupDataAdapter extends LookupDataAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is deprecated, see setValue
|
// This is deprecated, see setValue
|
||||||
@Override
|
@Deprecated
|
||||||
public void set(Object key, Object value) {
|
public void set(Object key, Object value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LookupResult setValue(Object key, Object value) {
|
public LookupResult setValue(Object key, Object value) {
|
||||||
|
return setValueWithTtl(key, value, this.config.redisKeyTTL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public LookupResult setValueWithTtl(Object key, Object value, Long ttlSec) {
|
||||||
final Timer.Context time = redisSetRequestTimer.time();
|
final Timer.Context time = redisSetRequestTimer.time();
|
||||||
|
final String trimmedKey = StringUtils.trimToNull(key.toString());
|
||||||
try {
|
try {
|
||||||
final String result = this.commands.setex(key.toString(), this.config.redisKeyTTL(), value.toString());
|
final String result;
|
||||||
|
if (ttlSec > 0 ) {
|
||||||
|
result = this.commands.setex(trimmedKey, ttlSec, value.toString());
|
||||||
|
} else {
|
||||||
|
result = this.commands.set(trimmedKey, value.toString());
|
||||||
|
}
|
||||||
if (!result.equals("OK")) {
|
if (!result.equals("OK")) {
|
||||||
LOG.warn("Redis SET key <{}> to value <{}> returned {}", key, value, result);
|
LOG.warn("Redis SET(EX) key <{}> to value <{}> with TTL <{}> returned {}", key, value, ttlSec, result);
|
||||||
redisSetRequestErrors.mark();
|
redisSetRequestErrors.mark();
|
||||||
return LookupResult.empty();
|
return LookupResult.empty();
|
||||||
}
|
}
|
||||||
return LookupResult.single(value.toString());
|
return LookupResult.single(value.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Redis SET key <{}> to value <{}> returned an exception: {}", key, value, e);
|
LOG.error("Redis SET(EX) key <{}> to value <{}> with TTL <{}> returned an exception: {}", key, value, ttlSec, e);
|
||||||
redisSetRequestErrors.mark();
|
redisSetRequestErrors.mark();
|
||||||
return LookupResult.empty();
|
return LookupResult.withError();
|
||||||
} finally {
|
} finally {
|
||||||
time.stop();
|
time.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearKey(Object key) {
|
||||||
|
final Timer.Context time = redisSetRequestTimer.time();
|
||||||
|
final String trimmedKey = StringUtils.trimToNull(key.toString());
|
||||||
|
try {
|
||||||
|
final Long result = this.commands.del(key.toString());
|
||||||
|
if (result != 1) {
|
||||||
|
LOG.debug("Redis DEL key <{}> returned {}", key, result);
|
||||||
|
redisSetRequestErrors.mark();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Redis DEL key <{}> returned {}", key, e);
|
||||||
|
redisSetRequestErrors.mark();
|
||||||
|
return;
|
||||||
|
} finally {
|
||||||
|
time.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LookupResult setExpire(String key, Long ttl) {
|
||||||
|
try {
|
||||||
|
final Boolean result = this.commands.expire(key, ttl);
|
||||||
|
if (!result) {
|
||||||
|
LOG.warn("Redis EXPIRE key <{}> to <{}> returned {}", key, ttl, result);
|
||||||
|
return LookupResult.withError();
|
||||||
|
}
|
||||||
|
final String value = this.commands.get(key);
|
||||||
|
return LookupResult.single(value.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Redis EXPIRE key <{}> to <{}> returned {}", key, ttl, e);
|
||||||
|
return LookupResult.withError(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LookupResult setPersist(String key) {
|
||||||
|
try {
|
||||||
|
final Boolean result = this.commands.persist(key);
|
||||||
|
if (!result) {
|
||||||
|
LOG.warn("Redis PERSIST key <{}> returned {}", key, result);
|
||||||
|
return LookupResult.withError();
|
||||||
|
}
|
||||||
|
final String value = this.commands.get(key);
|
||||||
|
return LookupResult.single(value.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Redis PERSIST key <{}> returned {}", key, e);
|
||||||
|
return LookupResult.withError(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TTL -1 = never expire
|
||||||
|
public LookupResult assignTtl(Object key, Long ttlSec) {
|
||||||
|
final Timer.Context time = redisSetRequestTimer.time();
|
||||||
|
final String trimmedKey = StringUtils.trimToNull(key.toString());
|
||||||
|
try {
|
||||||
|
if (ttlSec > 0) {
|
||||||
|
return setExpire(trimmedKey, ttlSec);
|
||||||
|
} else {
|
||||||
|
return setPersist(trimmedKey);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("assignTtl <{}> to key <{}> returned {}", ttlSec, trimmedKey, e);
|
||||||
|
redisSetRequestErrors.mark();
|
||||||
|
return LookupResult.withError();
|
||||||
|
} finally {
|
||||||
|
time.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LookupResult setStringList(Object key, List<String> listValue) {
|
||||||
|
return LookupResult.empty();
|
||||||
|
}
|
||||||
|
|
||||||
public interface Factory extends LookupDataAdapter.Factory2<RedisLookupDataAdapter> {
|
public interface Factory extends LookupDataAdapter.Factory2<RedisLookupDataAdapter> {
|
||||||
@Override
|
@Override
|
||||||
RedisLookupDataAdapter create(@Assisted("dto") DataAdapterDto dto);
|
RedisLookupDataAdapter create(@Assisted("dto") DataAdapterDto dto);
|
||||||
@ -181,7 +266,7 @@ public class RedisLookupDataAdapter extends LookupDataAdapter {
|
|||||||
@Override
|
@Override
|
||||||
Descriptor getDescriptor();
|
Descriptor getDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Descriptor extends LookupDataAdapter.Descriptor<Config> {
|
public static class Descriptor extends LookupDataAdapter.Descriptor<Config> {
|
||||||
public Descriptor() {
|
public Descriptor() {
|
||||||
super(NAME, Config.class);
|
super(NAME, Config.class);
|
||||||
@ -194,7 +279,7 @@ public class RedisLookupDataAdapter extends LookupDataAdapter {
|
|||||||
.redisHost("127.0.0.1")
|
.redisHost("127.0.0.1")
|
||||||
.redisPort(6379)
|
.redisPort(6379)
|
||||||
.redisDB(0)
|
.redisDB(0)
|
||||||
.redisKeyTTL(86400)
|
.redisKeyTTL(-1)
|
||||||
.redisUsername("")
|
.redisUsername("")
|
||||||
.redisPassword("")
|
.redisPassword("")
|
||||||
.build();
|
.build();
|
||||||
|
@ -76,7 +76,7 @@ public class RedisLookupPluginFunction extends LookupTableFunction<GenericLookup
|
|||||||
public FunctionDescriptor<GenericLookupResult> descriptor() {
|
public FunctionDescriptor<GenericLookupResult> descriptor() {
|
||||||
return FunctionDescriptor.<GenericLookupResult>builder()
|
return FunctionDescriptor.<GenericLookupResult>builder()
|
||||||
.name(NAME)
|
.name(NAME)
|
||||||
.description("Match a key into Redis instance and return value")
|
.description("Match a key into Redis instance and return value. Do not use, prefer standard 'lookup_*' functions")
|
||||||
.params(keyParam)
|
.params(keyParam)
|
||||||
.returnType(GenericLookupResult.class)
|
.returnType(GenericLookupResult.class)
|
||||||
.build();
|
.build();
|
||||||
|
@ -82,7 +82,7 @@ class RedisLookupAdapterFieldSet extends React.Component {
|
|||||||
label="Redis key TTL"
|
label="Redis key TTL"
|
||||||
required
|
required
|
||||||
onChange={this.props.handleFormEvent}
|
onChange={this.props.handleFormEvent}
|
||||||
help={this.props.validationMessage('redis_ttl', 'Redis key TTL in seconds')}
|
help={this.props.validationMessage('redis_ttl', 'Redis key TTL in seconds. Set -1 to not expire keys')}
|
||||||
bsStyle={this.props.validationState('redis_ttl')}
|
bsStyle={this.props.validationState('redis_ttl')}
|
||||||
value={config.redis_ttl}
|
value={config.redis_ttl}
|
||||||
labelClassName="col-sm-3"
|
labelClassName="col-sm-3"
|
||||||
|
Reference in New Issue
Block a user