<s> """<STR_LIT>""" <EOL> from __future__ import unicode_literals <EOL> import redis <EOL> from importlib import import_module <EOL> from collections import OrderedDict <EOL> from datetime import datetime , timedelta <EOL> from django . template . defaultfilters import slugify <EOL> from . settings import app_settings , GRANULARITIES <EOL> from . templatetags import redis_metrics_filters as template_tags <EOL> def dedupe ( items ) : <EOL> """<STR_LIT>""" <EOL> seen = set ( ) <EOL> for item in items : <EOL> if item not in seen : <EOL> yield item <EOL> seen . add ( item ) <EOL> class R ( object ) : <EOL> def __init__ ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> self . _categories_key = kwargs . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . _metric_slugs_key = kwargs . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . _gauge_slugs_key = kwargs . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . connection_class = kwargs . pop ( '<STR_LIT>' , app_settings . CONNECTION_CLASS ) <EOL> if self . connection_class : <EOL> package , module = self . connection_class . rsplit ( '<STR_LIT:.>' , <NUM_LIT:1> ) <EOL> self . r = getattr ( import_module ( package ) , module ) ( ) <EOL> else : <EOL> self . host = kwargs . pop ( '<STR_LIT:host>' , app_settings . HOST ) <EOL> self . port = kwargs . pop ( '<STR_LIT:port>' , app_settings . PORT ) <EOL> self . db = kwargs . pop ( '<STR_LIT>' , app_settings . DB ) <EOL> self . password = kwargs . pop ( '<STR_LIT:password>' , app_settings . PASSWORD ) <EOL> self . socket_timeout = kwargs . pop ( <EOL> '<STR_LIT>' , <EOL> app_settings . SOCKET_TIMEOUT <EOL> ) <EOL> self . connection_pool = kwargs . pop ( <EOL> '<STR_LIT>' , <EOL> app_settings . SOCKET_CONNECTION_POOL <EOL> ) <EOL> self . r = redis . StrictRedis ( <EOL> host = self . host , <EOL> port = self . port , <EOL> db = self . db , <EOL> password = self . password , <EOL> socket_timeout = self . socket_timeout , <EOL> connection_pool = self . connection_pool , <EOL> decode_responses = True <EOL> ) <EOL> def _date_range ( self , granularity , since , to = None ) : <EOL> """<STR_LIT>""" <EOL> if since is None : <EOL> since = datetime . utcnow ( ) - timedelta ( days = <NUM_LIT:7> ) <EOL> if to is None : <EOL> to = datetime . utcnow ( ) <EOL> elapsed = ( to - since ) <EOL> if granularity == "<STR_LIT>" : <EOL> units = elapsed . total_seconds ( ) <EOL> units = <NUM_LIT> if units > <NUM_LIT> else units <EOL> elif granularity == "<STR_LIT>" : <EOL> units = elapsed . total_seconds ( ) / <NUM_LIT> <EOL> units = <NUM_LIT> if units > <NUM_LIT> else units <EOL> elif granularity == "<STR_LIT>" : <EOL> granularity = "<STR_LIT>" <EOL> units = elapsed . total_seconds ( ) / <NUM_LIT> <EOL> units = <NUM_LIT> if units > <NUM_LIT> else units <EOL> else : <EOL> granularity = "<STR_LIT>" <EOL> units = elapsed . days + <NUM_LIT:1> <EOL> return ( to - timedelta ( ** { granularity : u } ) for u in range ( int ( units ) ) ) <EOL> def categories ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . r . smembers ( self . _categories_key ) <EOL> def _category_key ( self , category ) : <EOL> return u"<STR_LIT>" . format ( category ) <EOL> def _category_slugs ( self , category ) : <EOL> """<STR_LIT>""" <EOL> key = self . _category_key ( category ) <EOL> slugs = self . r . smembers ( key ) <EOL> return slugs <EOL> def _categorize ( self , slug , category ) : <EOL> """<STR_LIT>""" <EOL> key = self . _category_key ( category ) <EOL> self . r . sadd ( key , slug ) <EOL> self . r . sadd ( self . _categories_key , category ) <EOL> def _granularities ( self ) : <EOL> """<STR_LIT>""" <EOL> keep = False <EOL> for g in GRANULARITIES : <EOL> if g == app_settings . MIN_GRANULARITY and not keep : <EOL> keep = True <EOL> elif g == app_settings . MAX_GRANULARITY and keep : <EOL> keep = False <EOL> yield g <EOL> if keep : <EOL> yield g <EOL> def _metric_key_patterns ( self ) : <EOL> """<STR_LIT>""" <EOL> return { <EOL> "<STR_LIT>" : { "<STR_LIT:key>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> "<STR_LIT>" : { "<STR_LIT:key>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> "<STR_LIT>" : { "<STR_LIT:key>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> "<STR_LIT>" : { "<STR_LIT:key>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT:key>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" . format ( '<STR_LIT>' if app_settings . MONDAY_FIRST_DAY_OF_WEEK else '<STR_LIT>' ) <EOL> } , <EOL> "<STR_LIT>" : { "<STR_LIT:key>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> "<STR_LIT>" : { "<STR_LIT:key>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> } <EOL> def _build_key_patterns ( self , slug , date ) : <EOL> """<STR_LIT>""" <EOL> patts = OrderedDict ( ) <EOL> metric_key_patterns = self . _metric_key_patterns ( ) <EOL> for g in self . _granularities ( ) : <EOL> date_string = date . strftime ( metric_key_patterns [ g ] [ "<STR_LIT>" ] ) <EOL> patts [ g ] = metric_key_patterns [ g ] [ "<STR_LIT:key>" ] . format ( slug , date_string ) <EOL> return patts <EOL> def _build_keys ( self , slug , date = None , granularity = '<STR_LIT:all>' ) : <EOL> """<STR_LIT>""" <EOL> slug = slugify ( slug ) <EOL> if date is None : <EOL> date = datetime . utcnow ( ) <EOL> patts = self . _build_key_patterns ( slug , date ) <EOL> if granularity == "<STR_LIT:all>" : <EOL> return list ( patts . values ( ) ) <EOL> return [ patts [ granularity ] ] <EOL> def metric_slugs ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . r . smembers ( self . _metric_slugs_key ) <EOL> def metric_slugs_by_category ( self ) : <EOL> """<STR_LIT>""" <EOL> result = { } <EOL> categories = self . r . smembers ( self . _categories_key ) <EOL> for category in categories : <EOL> result [ category ] = self . _category_slugs ( category ) <EOL> categorized_metrics = set ( [ <EOL> slug for sublist in result . values ( ) for slug in sublist <EOL> ] ) <EOL> f = lambda slug : slug not in categorized_metrics <EOL> uncategorized = list ( set ( filter ( f , self . metric_slugs ( ) ) ) ) <EOL> if len ( uncategorized ) > <NUM_LIT:0> : <EOL> result [ '<STR_LIT>' ] = uncategorized <EOL> return result <EOL> def delete_metric ( self , slug ) : <EOL> """<STR_LIT>""" <EOL> prefix = "<STR_LIT>" . format ( slug ) <EOL> keys = self . r . keys ( prefix ) <EOL> self . r . delete ( * keys ) <EOL> self . r . srem ( self . _metric_slugs_key , slug ) <EOL> def set_metric ( self , slug , value , category = None , expire = None , date = None ) : <EOL> """<STR_LIT>""" <EOL> keys = self . _build_keys ( slug , date = date ) <EOL> self . r . sadd ( self . _metric_slugs_key , slug ) <EOL> data = { } <EOL> for k in keys : <EOL> data [ k ] = value <EOL> self . r . mset ( data ) <EOL> if category : <EOL> self . _categorize ( slug , category ) <EOL> if expire : <EOL> for k in keys : <EOL> self . r . expire ( k , expire ) <EOL> def metric ( self , slug , num = <NUM_LIT:1> , category = None , expire = None , date = None ) : <EOL> """<STR_LIT>""" <EOL> self . r . sadd ( self . _metric_slugs_key , slug ) <EOL> if category : <EOL> self . _categorize ( slug , category ) <EOL> keys = self . _build_keys ( slug , date = date ) <EOL> pipe = self . r . pipeline ( ) <EOL> for key in keys : <EOL> pipe . incr ( key , num ) <EOL> if expire : <EOL> pipe . expire ( key , expire ) <EOL> pipe . execute ( ) <EOL> def get_metric ( self , slug ) : <EOL> """<STR_LIT>""" <EOL> results = OrderedDict ( ) <EOL> granularities = self . _granularities ( ) <EOL> keys = self . _build_keys ( slug ) <EOL> for granularity , key in zip ( granularities , keys ) : <EOL> results [ granularity ] = self . r . get ( key ) <EOL> return results <EOL> def get_metrics ( self , slug_list ) : <EOL> """<STR_LIT>""" <EOL> keys = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> key_mapping = { gran : key for gran , key in zip ( GRANULARITIES , keys ) } <EOL> keys = [ key_mapping [ gran ] for gran in self . _granularities ( ) ] <EOL> results = [ ] <EOL> for slug in slug_list : <EOL> metrics = self . r . mget ( * self . _build_keys ( slug ) ) <EOL> if any ( metrics ) : <EOL> results . append ( ( slug , dict ( zip ( keys , metrics ) ) ) ) <EOL> return results <EOL> def get_category_metrics ( self , category ) : <EOL> """<STR_LIT>""" <EOL> slug_list = self . _category_slugs ( category ) <EOL> return self . get_metrics ( slug_list ) <EOL> def delete_category ( self , category ) : <EOL> """<STR_LIT>""" <EOL> category_key = self . _category_key ( category ) <EOL> self . r . delete ( category_key ) <EOL> self . r . srem ( self . _categories_key , category ) <EOL> def reset_category ( self , category , metric_slugs ) : <EOL> """<STR_LIT>""" <EOL> key = self . _category_key ( category ) <EOL> if len ( metric_slugs ) == <NUM_LIT:0> : <EOL> self . delete_category ( category ) <EOL> else : <EOL> self . r . sadd ( key , * metric_slugs ) <EOL> self . r . sadd ( self . _categories_key , category ) <EOL> def get_metric_history ( self , slugs , since = None , to = None , granularity = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if not type ( slugs ) == list : <EOL> slugs = [ slugs ] <EOL> keys = [ ] <EOL> for slug in slugs : <EOL> for date in self . _date_range ( granularity , since , to ) : <EOL> keys += self . _build_keys ( slug , date , granularity ) <EOL> keys = list ( dedupe ( keys ) ) <EOL> results = [ <NUM_LIT:0> if v is None else v for v in self . r . mget ( keys ) ] <EOL> results = zip ( keys , results ) <EOL> return sorted ( results , key = lambda t : t [ <NUM_LIT:0> ] ) <EOL> def get_metric_history_as_columns ( self , slugs , since = None , <EOL> granularity = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> history = self . get_metric_history ( slugs , since , granularity = granularity ) <EOL> _history = [ ] <EOL> periods = [ '<STR_LIT>' ] <EOL> for s in slugs : <EOL> column = [ s ] <EOL> for key , value in history : <EOL> if template_tags . metric_slug ( key ) == s : <EOL> column . append ( value ) <EOL> period = template_tags . strip_metric_prefix ( key ) <EOL> if period not in periods : <EOL> periods . append ( period ) <EOL> _history . append ( column ) <EOL> _history . insert ( <NUM_LIT:0> , periods ) <EOL> return list ( zip ( * _history ) ) <EOL> def get_metric_history_chart_data ( self , slugs , since = None , granularity = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> slugs = sorted ( slugs ) <EOL> history = self . get_metric_history ( slugs , since , granularity = granularity ) <EOL> periods = [ ] <EOL> data = OrderedDict ( ) <EOL> for k , v in history : <EOL> period = template_tags . strip_metric_prefix ( k ) <EOL> if period not in periods : <EOL> periods . append ( period ) <EOL> slug = template_tags . metric_slug ( k ) <EOL> if slug not in data : <EOL> data [ slug ] = [ ] <EOL> data [ slug ] . append ( v ) <EOL> metrics = { '<STR_LIT>' : periods , '<STR_LIT:data>' : [ ] } <EOL> for slug , values in data . items ( ) : <EOL> metrics [ '<STR_LIT:data>' ] . append ( { <EOL> '<STR_LIT>' : slug , <EOL> '<STR_LIT>' : values <EOL> } ) <EOL> return metrics <EOL> def gauge_slugs ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . r . smembers ( self . _gauge_slugs_key ) <EOL> def _gauge_key ( self , slug ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" . format ( slugify ( slug ) ) <EOL> def gauge ( self , slug , current_value ) : <EOL> """<STR_LIT>""" <EOL> k = self . _gauge_key ( slug ) <EOL> self . r . sadd ( self . _gauge_slugs_key , slug ) <EOL> self . r . set ( k , current_value ) <EOL> def get_gauge ( self , slug ) : <EOL> k = self . _gauge_key ( slug ) <EOL> return self . r . get ( k ) <EOL> def delete_gauge ( self , slug ) : <EOL> """<STR_LIT>""" <EOL> key = self . _gauge_key ( slug ) <EOL> self . r . delete ( key ) <EOL> self . r . srem ( self . _gauge_slugs_key , slug ) </s>
