Description
Feature request to add a prometheus collector in jedis
Add a implementation of Collector in src/main/java/redis/clients/jedis/metrics
package or utils maybe
Basically a 1:1 clone of what HikariCP ships with here
Using this all
- Jedispool instances behind a JedisCluster object created for a redis cluster ( 6 pools for 6 node cluster )
- Jedispool instances for a standalone redis master instance ( 1 pool for a single redis instance )
can be instrumented using a simple line of code RedisCollector.getCollector().track(myjedisClusterOrPool)
Why as part of jedis and not as left upto user in there code.
-
In my opinion shipping it with jedis will add value to the library as it provides visibility to the user about the metrics as an inbuilt rather than having to instrument it separately.
-
As and when we add more metrics we can keep adding gauges/histogram/counter to the same collector . And the user wont even know these metrics are automatically available in the same registry . As soon as you upgrade your jedis library dependency metric is available. If I create it as a separate project then a pull request needs to be raised on that project , that project will have to upgrade jedis version , add those new metrics . All that
-
Prometheus is one of the most common timeseries in the industry with a simple to implement interface .
Why not do this in jedis ?
- Need to add io.prometheus as a dependency
- jedis wants to be light weight and not be opinionated about any other tool like prometheus
Sample code
import io.prometheus.client.Collector;
import io.prometheus.client.GaugeMetricFamily;
import io.prometheus.client.CollectorRegistry;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import static java.util.Collections.singletonList;
public class RedisCollector extends Collector {
private static final List<String> LABEL_NAMES = singletonList("host");
private static Map<String, JedisPool> poolStatsMap = new ConcurrentHashMap<>();
private static RedisCollector redisCollector;
public static RedisCollector getCollector() {
if (redisCollector == null) {
redisCollector = new RedisCollector().register();
}
return redisCollector;
}
public static RedisCollector getCollector(CollectorRegistry registry) {
if (redisCollector == null) {
redisCollector = new RedisCollector();
registry.register(redisCollector);
}
return redisCollector;
}
@Override
public List<MetricFamilySamples> collect() {
return Arrays.asList(
createGauge("jedis_pool_num_active", "Jedis Pool Active connections", JedisPool::getNumActive),
createGauge("jedis_pool_idle_connections", "Jedis Pool Idle connections", JedisPool::getNumIdle),
createGauge("jedis_pool_num_waiters", "Jedis Pool Waiting connections", JedisPool::getNumWaiters)
);
}
public void track(JedisCluster cluster) {
poolStatsMap = cluster.getClusterNodes();
}
public void track(String poolName, JedisPool pool) {
poolStatsMap.put(poolName, pool);
private GaugeMetricFamily createGauge(String metric, String help,
Function<JedisPool, Integer> driverFunction) {
GaugeMetricFamily metricFamily = new GaugeMetricFamily(metric, help, LABEL_NAMES);
poolStatsMap.forEach((poolName, pool) -> metricFamily.addMetric(singletonList(poolName), driverFunction.apply(pool)));
return metricFamily;
}
}
Sample metrics
jedis_cluster_num_active{host="127.0.0.1:7006",} 0.0
jedis_cluster_num_active{host="127.0.0.1:7004",} 0.0
jedis_cluster_num_active{host="127.0.0.1:7005",} 0.0
jedis_cluster_num_active{host="127.0.0.1:7002",} 0.0
jedis_cluster_num_active{host="127.0.0.1:7003",} 0.0
jedis_cluster_num_active{host="127.0.0.1:7001",} 1.0
jedis_cluster_idle_connections{host="127.0.0.1:7006",} 50.0
jedis_cluster_idle_connections{host="127.0.0.1:7004",} 50.0
jedis_cluster_idle_connections{host="127.0.0.1:7005",} 50.0
jedis_cluster_idle_connections{host="127.0.0.1:7002",} 50.0
jedis_cluster_idle_connections{host="127.0.0.1:7003",} 50.0
jedis_cluster_idle_connections{host="127.0.0.1:7001",} 50.0
jedis_cluster_num_waiters{host="127.0.0.1:7006",} 0.0
jedis_cluster_num_waiters{host="127.0.0.1:7004",} 0.0
jedis_cluster_num_waiters{host="127.0.0.1:7005",} 0.0
jedis_cluster_num_waiters{host="127.0.0.1:7002",} 0.0
jedis_cluster_num_waiters{host="127.0.0.1:7003",} 0.0
jedis_cluster_num_waiters{host="127.0.0.1:7001",} 0.0
I would really like to contribute.
Thanks for your consideration .