<s> import datetime <EOL> import redis <EOL> class RedisMonitor ( object ) : <EOL> def __init__ ( self , prefix = '<STR_LIT>' , redis_obj = None , redis_host = '<STR_LIT:localhost>' , <EOL> redis_port = <NUM_LIT> , redis_db = <NUM_LIT:0> <EOL> ) : <EOL> assert prefix and '<STR_LIT:U+0020>' not in prefix , '<STR_LIT>' <EOL> self . prefix = prefix <EOL> if redis_obj is None : <EOL> redis_obj = redis . Redis ( <EOL> host = redis_host , port = redis_port , db = redis_db <EOL> ) <EOL> self . r = redis_obj <EOL> def _hash_and_slot ( self , dt = None ) : <EOL> dt = dt or datetime . datetime . utcnow ( ) <EOL> hash = dt . strftime ( '<STR_LIT>' ) <EOL> slot = '<STR_LIT>' % ( <EOL> dt . minute , dt . second / <NUM_LIT:10> <EOL> ) <EOL> return ( '<STR_LIT>' % ( self . prefix , hash ) , slot ) <EOL> def _calculate_start ( self , hours , minutes , seconds , now = None ) : <EOL> now = now or datetime . datetime . utcnow ( ) <EOL> delta = ( <NUM_LIT> * <NUM_LIT> * hours ) + ( <NUM_LIT> * minutes ) + seconds <EOL> return now - datetime . timedelta ( seconds = delta ) <EOL> def record_hit ( self ) : <EOL> self . record_hits ( <NUM_LIT:1> ) <EOL> def record_hits ( self , num_hits ) : <EOL> hash , slot = self . _hash_and_slot ( ) <EOL> self . r . hincrby ( hash , slot , num_hits ) <EOL> def record_hit_with_weight ( self , weight ) : <EOL> self . record_hits_with_total_weight ( <NUM_LIT:1> , weight ) <EOL> def record_hits_with_total_weight ( self , num_hits , total_weight ) : <EOL> hash , slot = self . _hash_and_slot ( ) <EOL> self . r . hincrby ( hash , slot , num_hits ) <EOL> self . r . hincrby ( hash , slot + '<STR_LIT:w>' , total_weight ) <EOL> def get_recent_hits ( self , hours = <NUM_LIT:0> , minutes = <NUM_LIT:0> , seconds = <NUM_LIT:0> ) : <EOL> gathered = self . get_recent_hits_and_weights ( hours , minutes , seconds ) <EOL> for date , hits , weight in gathered : <EOL> yield date , hits <EOL> def get_recent_hits_and_weights ( <EOL> self , hours = <NUM_LIT:0> , minutes = <NUM_LIT:0> , seconds = <NUM_LIT:0> <EOL> ) : <EOL> start = self . _calculate_start ( hours , minutes , seconds ) <EOL> start = start . replace ( <EOL> second = ( start . second / <NUM_LIT:10> ) * <NUM_LIT:10> , microsecond = <NUM_LIT:0> <EOL> ) <EOL> preloaded_hashes = { } <EOL> gathered = [ ] <EOL> current = start <EOL> now = datetime . datetime . utcnow ( ) . replace ( <EOL> second = ( start . second / <NUM_LIT:10> ) * <NUM_LIT:10> , microsecond = <NUM_LIT:0> <EOL> ) <EOL> while current < now : <EOL> hash , slot = self . _hash_and_slot ( current ) <EOL> if hash not in preloaded_hashes : <EOL> preloaded_hashes [ hash ] = self . r . hgetall ( hash ) <EOL> hits = int ( preloaded_hashes [ hash ] . get ( slot , <NUM_LIT:0> ) ) <EOL> weight = int ( preloaded_hashes [ hash ] . get ( slot + '<STR_LIT:w>' , <NUM_LIT:0> ) ) <EOL> gathered . append ( ( current , hits , weight ) ) <EOL> current += datetime . timedelta ( seconds = <NUM_LIT:10> ) <EOL> return gathered <EOL> def get_recent_hits_per_second ( self , hours = <NUM_LIT:0> , minutes = <NUM_LIT:0> , seconds = <NUM_LIT:0> ) : <EOL> gathered = self . get_recent_hits ( hours , minutes , seconds ) <EOL> for date , hits in gathered : <EOL> yield date , hits / <NUM_LIT> <EOL> def get_recent_avg_weights ( self , hours = <NUM_LIT:0> , minutes = <NUM_LIT:0> , seconds = <NUM_LIT:0> ) : <EOL> gathered = self . get_recent_hits_and_weights ( hours , minutes , seconds ) <EOL> for date , hits , weight in gathered : <EOL> if weight == <NUM_LIT:0> or hits == <NUM_LIT:0> : <EOL> yield date , <NUM_LIT:0> <EOL> else : <EOL> yield date , float ( weight ) / hits <EOL> class RedisMonitorTotalsOnly ( RedisMonitor ) : <EOL> def record_hits_with_total_weight ( self , num_hits , total_weight ) : <EOL> hash = '<STR_LIT>' % self . prefix <EOL> self . r . hincrby ( hash , '<STR_LIT>' , num_hits ) <EOL> self . r . hincrby ( hash , '<STR_LIT>' , total_weight ) <EOL> def get_recent_hits_and_weights ( self , * args , ** kwargs ) : <EOL> raise NotImplemented , '<STR_LIT>' <EOL> def get_totals ( self ) : <EOL> hash = '<STR_LIT>' % self . prefix <EOL> return self . r . hgetall ( hash ) or { } <EOL> def get_instance ( prefix ) : <EOL> from django . conf import settings <EOL> from django . core import signals <EOL> host = getattr ( settings , '<STR_LIT>' , '<STR_LIT:localhost>' ) <EOL> port = getattr ( settings , '<STR_LIT>' , <NUM_LIT> ) <EOL> db = getattr ( settings , '<STR_LIT>' , <NUM_LIT:0> ) <EOL> only_track_totals = getattr ( <EOL> settings , '<STR_LIT>' , False <EOL> ) <EOL> if only_track_totals : <EOL> klass = RedisMonitorTotalsOnly <EOL> else : <EOL> klass = RedisMonitor <EOL> obj = klass ( prefix , redis_host = host , redis_port = port , redis_db = db ) <EOL> signals . request_finished . connect ( <EOL> lambda ** kwargs : obj . r . connection . disconnect ( ) <EOL> ) <EOL> return obj </s>
