5 Commits

Author SHA1 Message Date
2cf5dff011 v1.0.1: Handle TTL and clear key 2024-02-04 10:42:12 +01:00
30e1bf70d9 Minor fixes so this compile 2024-02-04 10:40:25 +01:00
yo
f1c53077a4 Handle disconnect at doStop 2024-02-03 22:52:46 +01:00
yo
5a4b3cb38a Add clearKey and assignTtl 2024-02-03 22:38:36 +01:00
yo
5487e2dd71 Support TTL setting in 'lookup_set_value(lookup_table, key, value, ttl)' 2024-02-03 22:19:50 +01:00
4 changed files with 68 additions and 15 deletions

View File

@ -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
--------------- ---------------

View File

@ -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.1</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>

View File

@ -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.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>

View File

@ -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,26 +150,72 @@ 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 = this.commands.setex(trimmedKey, ttlSec, value.toString());
if (!result.equals("OK")) { if (!result.equals("OK")) {
LOG.warn("Redis SET key <{}> to value <{}> returned {}", key, value, result); LOG.warn("Redis SETEX 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 SETEX key <{}> to value <{}> with TTL <{}> returned an exception: {}", key, value, ttlSec, e);
redisSetRequestErrors.mark(); redisSetRequestErrors.mark();
return LookupResult.empty(); return LookupResult.withError();
} finally {
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();
}
}
public LookupResult assignTtl(Object key, Long ttlSec) {
final Timer.Context time = redisSetRequestTimer.time();
final String trimmedKey = StringUtils.trimToNull(key.toString());
try {
final Boolean result = this.commands.expire(trimmedKey, ttlSec);
if (!result) {
LOG.warn("Redis EXPIRE key <{}> to <{}> returned {}", key, ttlSec, result);
redisSetRequestErrors.mark();
return LookupResult.withError();
}
final String value = this.commands.get(trimmedKey);
return LookupResult.single(value.toString());
} catch (Exception e) {
LOG.error("Redis EXPIRE key <{}> to <{}> returned {}", key, ttlSec, e);
redisSetRequestErrors.mark();
return LookupResult.withError();
} finally { } finally {
time.stop(); time.stop();
} }
@ -181,7 +228,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);