Skip to content

Instantly share code, notes, and snippets.

@zircote
Last active December 20, 2015 16:29
Show Gist options
  • Save zircote/6161466 to your computer and use it in GitHub Desktop.
Save zircote/6161466 to your computer and use it in GitHub Desktop.
redis statsd collection
#!/usr/bin/env python
import redis
import statsd
import time
import argparse
import logging
import sys
import os
#: redis info keys
DEFAULT_REDIS_PORT = 6379
DEFAULT_REDIS_HOST = "localhost"
GAUGES = [
'used_memory',
'used_memory_lua',
'used_memory_rss',
'mem_fragmentation_ratio',
'pubsub_channels',
'pubsub_patterns',
'rdb_saves',
'rdb_changes_since_last_save',
'aof_last_rewrite_time_sec',
'aof_last_rewrite_time_sec',
'blocked_clients',
'aof_rewrites',
'client_biggest_input_buf',
'client_longest_output_list',
'connected_clients',
'connected_slaves',
'evicted_keys',
'expired_keys',
'latest_fork_usec',
'instantaneous_ops_per_sec',
'rdb_last_bgsave_time_sec',
'rdb_changes_since_last_save',
'rdb_current_bgsave_time_sec',
'total_commands_processed',
'total_connections_received',
'rejected_connections',
'used_memory_peak',
'used_cpu_sys',
'used_cpu_sys_children',
'used_cpu_user',
'used_cpu_user_children',
'keyspace_read_hits',
'keyspace_read_misses',
'keyspace_write_hits',
'keyspace_write_misses',
]
parser = argparse.ArgumentParser('A python script to monitor and submit statistics to a statsd endpoint')
parser.add_argument("-s", "--server", type=str, default='localhost:6379',
help="the server(s) ',' delimited to collect stats from example:[test.com:6379,test.com]")
parser.add_argument("--namespace-service", help="the service namespace key for statsd",
default='redis', type=str)
parser.add_argument("-v", "--verbose", help="print the statsd namespaces being monitored", action="store_true")
parser.add_argument("-f", "--frequency", help="frequency to collect statistics in seconds [1]", default=1, type=int)
parser.add_argument("--statsd-host", help="statsd server address", default=DEFAULT_REDIS_HOST, type=str)
parser.add_argument("--statsd-port", help="statsd server port", default=8125, type=int)
parser.add_argument("--statsd-sample-rate", help="statsd sample rate", default=1, type=int)
parser.add_argument("--detach", help="detach process and run in background", action="store_true")
parser.add_argument("-l", "--loglevel", help="enable debugging", choices=('DEBUG', 'INFO', 'ERROR', 'CRITICAL', 'FATAL'),
default="INFO")
parser.add_argument("--namespace-format", default="{host}.{service_name}.{port}", type=str,
help="the namespace key format")
args = parser.parse_args()
'''Script Entry point
'''
def main():
REDIS_SERVERS = dict()
logging.basicConfig(level=args.loglevel)
for server in args.server.split(','):
if server.find(':') > 0:
server, port = server.split(':')
else:
port = str(DEFAULT_REDIS_PORT)
ns = args.namespace_format.format(host=server.replace('.', '_'), port=port, service_name=args.namespace_service)
logging.info("ADDING redis host [%s] to statsd monitoring" % ns)
REDIS_SERVERS[ns] = redis.StrictRedis(host=server, port=int(port))
statsd.Connection.set_defaults(host=args.statsd_host, port=args.statsd_port, sample_rate=args.statsd_sample_rate)
logging.debug("starting redis statsd monitoring with arguments: [%s]" % args)
while True:
for _server in REDIS_SERVERS:
try:
info = REDIS_SERVERS[_server].info()
log_gauges(_server, info)
except redis.RedisError as e:
logging.error(e)
time.sleep(args.frequency)
'''statsd redis host info parsing and logging
:param ns: the toplevel namespace to log the data into
:param info: the redis info dict
'''
def log_gauges(ns, info):
g = statsd.Gauge(ns)
for n in GAUGES:
if n in info:
g.send(n, info[n])
for key in info:
if key[0:2] == 'db':
g.send('%s.expires' % key, info[key]['expires'])
g.send('%s.keys' % key, info[key]['keys'])
if __name__ == "__main__":
try:
if args.detach and os.fork():
sys.exit()
main()
except OSError, e:
raise Exception("%s [%d]" % (e.strerror, e.errno))
@zircote
Copy link
Author

zircote commented Aug 6, 2013

./redis-stats --server localhost:6379,localhost:6380 -v -f 5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment