├── README └── redis_ /README: -------------------------------------------------------------------------------- 1 | This is a Munin public domain plugin for Redis. 2 | 3 | It tries to extensively cover Redis INFO output, while keeping the 4 | dependencies low (currently, only needs awk, tr, sed, redis-cli and Munin 1.4+). 5 | 6 | It can monitor several Redis instances, remotes or locals to the server 7 | (via network or socket connection). 8 | 9 | To install : just copy the redis_ script to your $MUNIN_LIBDIR 10 | (on Debian, that's /usr/share/munin/plugins/). 11 | 12 | Then create a symbolic link like this: 13 | 14 | ln -s '/usr/share/munin/plugins/redis_' \ 15 | '/etc/munin/plugins/redis_127.0.0.1_6379' 16 | 17 | Or let "munin-node-configure --shell | bash" do it for you. 18 | 19 | To monitor remote servers (or monitor local Redis instances listening 20 | on non-defaults ports), create a symbolic link accordingly, ie. : 21 | /etc/munin/plugins/redis_remoteserverip_remoteserverport 22 | 23 | To monitor local running socket-based redis setups, create a symbolic 24 | link like this: 25 | /etc/munin/plugins/redis_socket_socketpath_with_underscores_filename 26 | 27 | i.e. : 28 | 29 | ln -s '/usr/share/munin/plugins/redis_' \ 30 | '/etc/munin/plugins/redis_socket_var_run_redis_redis.sock' 31 | 32 | It's important to use the word socket as second part after redis_, to signal 33 | the script to use a socket connection. The redis-cli command must have 34 | access to the socket. 35 | The script convert the naming after socket into a socket real path. 36 | 37 | Passwords can be set in a config file ala /etc/munin/plugin-conf.d/redis: 38 | 39 | [redis_*] 40 | env.password secret-password 41 | 42 | and/or 43 | 44 | [redis_remoteserverip_remoteserverport] 45 | env.password another-secret-password 46 | 47 | and/or 48 | 49 | [redis_socket_socketpath] 50 | env.password another-secret-password 51 | -------------------------------------------------------------------------------- /redis_: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # The following code is released in public domain (where applicable). 4 | # http://creativecommons.org/publicdomain/zero/1.0/ 5 | #%# family=auto 6 | #%# capabilities=autoconf suggest 7 | 8 | ip_socket=$(echo $0 | awk -F_ '{ print $2 }') 9 | if [[ $ip_socket = "socket" ]]; then 10 | tmp_var=$(echo $0 | awk -F_ '{ s = ""; for (i = 3; i <= NF; i++) s = s $i "/"; print s }') 11 | port_path=$(echo "/${tmp_var}" | sed 's,/$,,') 12 | else 13 | port_path=$(echo $0 | awk -F_ '{ print $3 }') 14 | fi 15 | 16 | if [ "$ip_socket" = "socket" ]; then 17 | ip_socket="-s"; 18 | else 19 | if [ -z $ip_socket ] ; then 20 | ip_socket="-h 127.0.0.1" 21 | else 22 | ip_socket="-h $ip_socket" 23 | fi 24 | fi 25 | 26 | if [ -z "$port_path" ]; then 27 | port_path="-p 6379" 28 | elif [ "$ip_socket" = "-s" ]; then 29 | port_path="$port_path" 30 | else 31 | port_path="-p $port_path" 32 | fi 33 | 34 | # add the ability to set a password in a respective config file 35 | if [ -z "$password" ]; then 36 | passwd='' # no password was configured 37 | else 38 | passwd="-a $password" 39 | fi 40 | 41 | if [ "$1" = "autoconf" ]; then 42 | redis-cli $ip_socket $port_path $passwd info >/dev/null 2>&1 && echo yes && exit 0 43 | echo no 44 | exit 0 45 | fi 46 | 47 | if [ "$1" = "suggest" ]; then 48 | redis-cli $ip_socket $port_path $passwd info >/dev/null 2>&1 && echo ${ip_socket}_${port_path} 49 | exit 0 50 | fi 51 | 52 | if [ "$ip_socket" = "-s" ]; then 53 | tmp_muninport=$(echo "$port_path" | tr '/' '_') 54 | muninport=$(echo "${tmp_muninport:1}" | tr '.' '_') 55 | else 56 | muninport=$(echo "$port_path" | awk '{ print $2 }') 57 | fi 58 | 59 | if [ "$1" = "config" ]; then 60 | # Expose all possibles graphes according to server's capabilities 61 | redis-cli $ip_socket $port_path $passwd info | awk -v port=${muninport} -F: ' 62 | 63 | /^changes_since_last_save:|^rdb_changes_since_last_save:/ { 64 | print "multigraph redis_changes_since_last_save_"port; 65 | print "graph_title Redis changes since last save Port: "port ; 66 | print "graph_info Number of write operations since last SAVE or BGSAVE"; 67 | print "graph_category redis"; 68 | print "changes.label changes"; 69 | }; 70 | 71 | /^keyspace_hits:/ { 72 | print "multigraph redis_commands_"port; 73 | print "graph_order commands hits misses"; 74 | print "graph_title Redis commands rate Port: "port; 75 | print "graph_category redis"; 76 | print "graph_vlabel commands/s"; 77 | print "graph_info Redis commands per second"; 78 | print "commands.label commands/s"; 79 | print "commands.type COUNTER"; 80 | print "commands.min 0"; 81 | print "hits.label key hits"; 82 | print "hits.type COUNTER"; 83 | print "hits.min 0"; 84 | print "misses.label key misses"; 85 | print "misses.type COUNTER"; 86 | print "misses.min 0"; 87 | }; 88 | 89 | /^total_connections_received:/ { 90 | print "multigraph redis_total_connections_"port; 91 | print "graph_title Redis connections rate Port: "port; 92 | print "graph_category redis"; 93 | print "graph_vlabel connections/s"; 94 | print "graph_info Connections per second to the Redis server"; 95 | print "connections.label connections"; 96 | print "connections.info connections per second"; 97 | print "connections.type COUNTER"; 98 | print "connections.min 0"; 99 | }; 100 | 101 | /^used_memory:/ { 102 | print "multigraph redis_memory_"port; 103 | print "graph_title Redis memory usage "port; 104 | print "graph_category redis"; 105 | print "graph_vlabel mem used"; 106 | print "graph_info Memory allocated by Redis"; 107 | print "graph_args --base 1024 -l 0"; 108 | print "memory.label memory"; 109 | print "maxmemory.label maxmemory"; 110 | print "memory.info Amount of mem used by Redis"; 111 | print "memory.type GAUGE"; 112 | print "memory.min 0"; 113 | }; 114 | 115 | /^connected_clients:/ { 116 | print "multigraph redis_clients_"port; 117 | print "graph_title Redis connected clients port: "port; 118 | print "graph_category redis"; 119 | print "graph_vlabel clients"; 120 | print "graph_info Number of currently connected clients"; 121 | print "clients.label clients"; 122 | print "clients.type GAUGE"; 123 | print "clients.min 0"; 124 | }; 125 | 126 | /^mem_fragmentation_ratio:/ { 127 | print "multigraph redis_fragmentation_"port; 128 | print "graph_title Redis memory fragmentation Port: "port; 129 | print "graph_category redis"; 130 | print "graph_vlabel fragmentation ratio"; 131 | print "graph_info Ratio between Redis RSS usage and allocated memory"; 132 | print "frag.label fragmentation ratio"; 133 | print "frag.type GAUGE"; 134 | print "frag.min 0"; 135 | }; 136 | 137 | /^expired_keys:/ { 138 | print "multigraph redis_expired_keys_"port; 139 | print "graph_title Redis expired keys rate Port: "port; 140 | print "graph_category redis"; 141 | print "graph_vlabel expired keys/s"; 142 | print "graph_info Expired Redis keys per second"; 143 | print "expired.label expired keys"; 144 | print "expired.info expired keys per second"; 145 | print "expired.type COUNTER"; 146 | print "expired.min 0"; 147 | }; 148 | 149 | /^evicted_keys:/ { 150 | print "multigraph redis_evicted_keys_"port; 151 | print "graph_title Redis evicted keys rate Port: "port; 152 | print "graph_category redis"; 153 | print "graph_vlabel evicted keys/s"; 154 | print "graph_info Evicted Redis keys per second"; 155 | print "evicted.label evicted keys"; 156 | print "evicted.info evicted keys per second"; 157 | print "evicted.type COUNTER"; 158 | print "evicted.min 0"; 159 | }; 160 | 161 | /^pubsub_channels:/ { 162 | print "multigraph redis_pubsub_channels_"port; 163 | print "graph_title Redis pubsub channels Port: "port; 164 | print "graph_category redis"; 165 | print "graph_vlabel channels"; 166 | print "graph_info Number of pubsub channels"; 167 | print "channels.label channels"; 168 | print "channels.type GAUGE"; 169 | print "channels.min 0"; 170 | }; 171 | 172 | /^blocked_clients:/ { 173 | print "multigraph redis_blocked_clients_"port; 174 | print "graph_title Redis blocked clients Port: "port; 175 | print "graph_category redis"; 176 | print "graph_vlabel clients"; 177 | print "graph_info Number of blocked clients"; 178 | print "blocked.label clients"; 179 | print "blocked.type GAUGE"; 180 | print "blocked.min 0"; 181 | print "blocked.warning 1"; 182 | }; 183 | 184 | /^db/ { 185 | split($2, where, "=|,"); 186 | dbskeys[$1] = where[2]; 187 | dbsexpires[$1] = where[4]; 188 | }; 189 | 190 | END { 191 | print "multigraph redis_dbs_"port; 192 | print "graph_title Redis dbs Port: "port; 193 | print "graph_category redis"; 194 | print "graph_vlabel keys"; 195 | print "graph_info Number of keys per dbs"; 196 | 197 | for (i in dbskeys) 198 | print i "keys.label " i " keys" 199 | print i "keys.type GAUGE" 200 | print i "keys.min 0" 201 | 202 | for (i in dbsexpires) 203 | print i "expires.label " i " keys with TTL" 204 | print i "expires.type GAUGE" 205 | print i "expires.min 0"; 206 | }; 207 | 208 | ' 209 | exit $? 210 | fi 211 | 212 | redis-cli $ip_socket $port_path $passwd info | awk -v port=${muninport} -F: ' 213 | 214 | /^changes_since_last_save:|^rdb_changes_since_last_save:/ { 215 | print "multigraph redis_changes_since_last_save_"port; 216 | print "changes.value " $2 ; 217 | }; 218 | 219 | /^total_connections_received:/ { 220 | print "multigraph redis_total_connections_"port; 221 | print "connections.value " $2 ; 222 | }; 223 | 224 | /^used_memory:/ { 225 | used_memory=$2; 226 | }; 227 | 228 | /^maxmemory:/ { 229 | max_memory=$2; 230 | }; 231 | 232 | /^connected_clients:/ { 233 | print "multigraph redis_clients_"port; 234 | print "clients.value " $2 ; 235 | }; 236 | 237 | /^mem_fragmentation_ratio:/ { 238 | print "multigraph redis_fragmentation_"port; 239 | print "frag.value " $2 ; 240 | }; 241 | 242 | /^expired_keys:/ { 243 | print "multigraph redis_expired_keys_"port; 244 | print "expired.value " $2 ; 245 | }; 246 | 247 | /^evicted_keys:/ { 248 | print "multigraph redis_evicted_keys_"port; 249 | print "evicted.value " $2 ; 250 | }; 251 | 252 | /^pubsub_channels:/ { 253 | print "multigraph redis_pubsub_channels_"port; 254 | print "channels.value " $2 ; 255 | }; 256 | 257 | /^blocked_clients:/ { 258 | print "multigraph redis_blocked_clients_"port; 259 | print "blocked.value " $2 ; 260 | }; 261 | 262 | /^total_commands_processed:/ { 263 | commands=$2 264 | }; 265 | 266 | /^keyspace_hits:/ { 267 | hits=$2 268 | }; 269 | 270 | /^keyspace_misses:/ { 271 | misses=$2 272 | }; 273 | 274 | /^db/ { 275 | split($2, where, "=|,"); 276 | dbskeys[$1] = where[2]; 277 | dbsexpires[$1] = where[4]; 278 | }; 279 | 280 | END { 281 | print "multigraph redis_commands_"port; 282 | print "commands.value " commands; 283 | print "hits.value " hits; 284 | print "misses.value " misses; 285 | 286 | print "multigraph redis_dbs_"port; 287 | 288 | for (i in dbskeys) 289 | print i "keys.value " dbskeys[i]; 290 | 291 | for (i in dbsexpires) 292 | print i "expires.value " dbsexpires[i]; 293 | 294 | # for memory monitoring 295 | print "multigraph redis_memory_"port; 296 | print "memory.value " used_memory; 297 | print "maxmemory.value " max_memory; 298 | }; 299 | ' 300 | --------------------------------------------------------------------------------