| 
							
								 | 
							
							#!/usr/bin/env python
 | 
						
						
						
						
							 | 
							
								 | 
							
							# -*- coding: utf-8 -*-
 | 
						
						
						
						
							 | 
							
								 | 
							
							import os
 | 
						
						
						
						
							 | 
							
								 | 
							
							import time
 | 
						
						
						
						
							 | 
							
								 | 
							
							import argparse
 | 
						
						
						
						
							 | 
							
								 | 
							
							import redis
 | 
						
						
						
						
							 | 
							
								 | 
							
							from redis.exceptions import ConnectionError
 | 
						
						
						
						
							 | 
							
								 | 
							
							from rq import use_redis, Queue, Worker
 | 
						
						
						
						
							 | 
							
								 | 
							
							from rq.utils import gettermsize, make_colorizer
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							red = make_colorizer('darkred')
 | 
						
						
						
						
							 | 
							
								 | 
							
							green = make_colorizer('darkgreen')
 | 
						
						
						
						
							 | 
							
								 | 
							
							yellow = make_colorizer('darkyellow')
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def pad(s, pad_to_length):
 | 
						
						
						
						
							 | 
							
								 | 
							
							    """Pads the given string to the given length."""
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return ('%-' + '%ds' % pad_to_length) % (s,)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def get_scale(x):
 | 
						
						
						
						
							 | 
							
								 | 
							
							    """Finds the lowest scale where x <= scale."""
 | 
						
						
						
						
							 | 
							
								 | 
							
							    scales = [20, 50, 100, 200, 400, 600, 800, 1000]
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for scale in scales:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if x <= scale:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return scale
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return x
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def state_symbol(state):
 | 
						
						
						
						
							 | 
							
								 | 
							
							    symbols = {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        'busy': red(u'\u25CF'),
 | 
						
						
						
						
							 | 
							
								 | 
							
							        'idle': green(u'\u25CB'),
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    try:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return symbols[state]
 | 
						
						
						
						
							 | 
							
								 | 
							
							    except KeyError:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return state
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def show_queues(args):
 | 
						
						
						
						
							 | 
							
								 | 
							
							    while True:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if len(args.queues):
 | 
						
						
						
						
							 | 
							
								 | 
							
							            qs = map(Queue, args.queues)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            qs = Queue.all()
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        num_jobs = 0
 | 
						
						
						
						
							 | 
							
								 | 
							
							        termwidth, _ = gettermsize()
 | 
						
						
						
						
							 | 
							
								 | 
							
							        chartwidth = min(20, termwidth - 20)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        max_count = 0
 | 
						
						
						
						
							 | 
							
								 | 
							
							        counts = dict()
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for q in qs:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            count = q.count
 | 
						
						
						
						
							 | 
							
								 | 
							
							            counts[q] = count
 | 
						
						
						
						
							 | 
							
								 | 
							
							            max_count = max(max_count, count)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        scale = get_scale(max_count)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        ratio = chartwidth * 1.0 / scale
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if args.interval:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            os.system('clear')
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for q in qs:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            count = counts[q]
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if not args.raw:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                chart = green('|' + '█' * int(ratio * count))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                line = '%-12s %s %d' % (q.name, chart, count)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                line = '%-12s %d' % (q.name, count)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            print(line)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            num_jobs += count
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        # Print summary when not in raw mode
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if not args.raw:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            print('%d queues, %d jobs total' % (len(qs), num_jobs))
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if args.interval:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            time.sleep(args.interval)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            break
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def show_workers(args):
 | 
						
						
						
						
							 | 
							
								 | 
							
							    while True:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        qs = Queue.all()
 | 
						
						
						
						
							 | 
							
								 | 
							
							        ws = Worker.all()
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if args.interval:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            os.system('clear')
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        queues = {qname: [] for qname in qs}
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for w in ws:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for q in w.queues:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if not q in queues:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    queues[q] = []
 | 
						
						
						
						
							 | 
							
								 | 
							
							                queues[q].append(w)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if args.by_queue:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            max_qname = max(map(lambda q: len(q.name), queues.keys())) if queues else 0
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for q in queues:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if queues[q]:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    queues_str = ", ".join(sorted(map(lambda w: '%s (%s)' % (w.name, state_symbol(w.state)), queues[q])))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                else:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    queues_str = '–'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                print '%s %s' % (pad(q.name + ':', max_qname + 1), queues_str)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for w in ws:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                print '%s %s: %s' % (w.name, state_symbol(w.state), ', '.join(w.queue_names()))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        print '%d workers, %d queues' % (len(ws), len(queues))
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if args.interval:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            time.sleep(args.interval)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
								 | 
							
							            break
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def parse_args():
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parser = argparse.ArgumentParser(description='RQ command-line monitor.')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parser.add_argument('--host', '-H', default='localhost', help='The Redis hostname (default: localhost)')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parser.add_argument('--port', '-p', type=int, default=6379, help='The Redis portnumber (default: 6379)')
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parent_parser = argparse.ArgumentParser(add_help=False)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parent_parser.add_argument('--interval', '-i', metavar='N', type=float, default=0, help='Updates stats every N seconds (default: don\'t poll)')
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    subparsers = parser.add_subparsers()
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    queues_p = subparsers.add_parser('queues', parents=[parent_parser], help='Show queue info')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    queues_p.add_argument('--raw', '-r', action='store_true', default=False, help='Print only the raw numbers, no bar charts')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    queues_p.add_argument('queues', nargs='*', help='The queues to poll')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    queues_p.set_defaults(func=show_queues)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    workers_p = subparsers.add_parser('workers', parents=[parent_parser], help='Show worker activity')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    workers_p.add_argument('--by-queue', '-Q', dest='by_queue', default=False, action='store_true', help='Shows workers by queue')
 | 
						
						
						
						
							 | 
							
								 | 
							
							    workers_p.set_defaults(func=show_workers)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return parser.parse_args()
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							def main():
 | 
						
						
						
						
							 | 
							
								 | 
							
							    args = parse_args()
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    # Setup connection to Redis
 | 
						
						
						
						
							 | 
							
								 | 
							
							    redis_conn = redis.Redis(host=args.host, port=args.port)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    use_redis(redis_conn)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    try:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        args.func(args)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    except ConnectionError as e:
 | 
						
						
						
						
							 | 
							
								 | 
							
							        print(e)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							if __name__ == '__main__':
 | 
						
						
						
						
							 | 
							
								 | 
							
							    main()
 |