<s> from collections import defaultdict <EOL> import re <EOL> import requests <EOL> from checks import AgentCheck <EOL> DEFAULT_MAX_METRICS = <NUM_LIT> <EOL> PATH = "<STR_LIT:path>" <EOL> ALIAS = "<STR_LIT>" <EOL> TYPE = "<STR_LIT:type>" <EOL> TAGS = "<STR_LIT>" <EOL> GAUGE = "<STR_LIT>" <EOL> RATE = "<STR_LIT>" <EOL> DEFAULT_TYPE = GAUGE <EOL> SUPPORTED_TYPES = { <EOL> GAUGE : AgentCheck . gauge , <EOL> RATE : AgentCheck . rate , <EOL> } <EOL> METRIC_NAMESPACE = "<STR_LIT>" <EOL> DEFAULT_GAUGE_MEMSTAT_METRICS = [ <EOL> "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , <EOL> ] <EOL> DEFAULT_RATE_MEMSTAT_METRICS = [ <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , <EOL> ] <EOL> DEFAULT_METRICS = [ { PATH : "<STR_LIT>" % path , TYPE : GAUGE } for path in DEFAULT_GAUGE_MEMSTAT_METRICS ] + [ { PATH : "<STR_LIT>" % path , TYPE : RATE } for path in DEFAULT_RATE_MEMSTAT_METRICS ] <EOL> class GoExpvar ( AgentCheck ) : <EOL> def __init__ ( self , name , init_config , agentConfig , instances = None ) : <EOL> AgentCheck . __init__ ( self , name , init_config , agentConfig , instances ) <EOL> self . _last_gc_count = defaultdict ( int ) <EOL> def _get_data ( self , url ) : <EOL> r = requests . get ( url ) <EOL> r . raise_for_status ( ) <EOL> return r . json ( ) <EOL> def _load ( self , instance ) : <EOL> url = instance . get ( '<STR_LIT>' ) <EOL> if not url : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> tags = instance . get ( '<STR_LIT>' , [ ] ) <EOL> tags . append ( "<STR_LIT>" % url ) <EOL> data = self . _get_data ( url ) <EOL> metrics = DEFAULT_METRICS + instance . get ( "<STR_LIT>" , [ ] ) <EOL> max_metrics = instance . get ( "<STR_LIT>" , DEFAULT_MAX_METRICS ) <EOL> return data , tags , metrics , max_metrics , url <EOL> def get_gc_collection_histogram ( self , data , tags , url ) : <EOL> num_gc = data . get ( "<STR_LIT>" , { } ) . get ( "<STR_LIT>" ) <EOL> pause_hist = data . get ( "<STR_LIT>" , { } ) . get ( "<STR_LIT>" ) <EOL> last_gc_count = self . _last_gc_count [ url ] <EOL> if last_gc_count == num_gc : <EOL> return <EOL> start = last_gc_count % <NUM_LIT> <EOL> end = ( num_gc + <NUM_LIT:255> ) % <NUM_LIT> + <NUM_LIT:1> <EOL> if start < end : <EOL> values = pause_hist [ start : end ] <EOL> else : <EOL> values = pause_hist [ start : ] + pause_hist [ : end ] <EOL> self . _last_gc_count [ url ] = num_gc <EOL> for value in values : <EOL> self . histogram ( <EOL> self . normalize ( "<STR_LIT>" , METRIC_NAMESPACE , fix_case = True ) , <EOL> value , tags = tags ) <EOL> def check ( self , instance ) : <EOL> data , tags , metrics , max_metrics , url = self . _load ( instance ) <EOL> self . get_gc_collection_histogram ( data , tags , url ) <EOL> self . parse_expvar_data ( data , tags , metrics , max_metrics ) <EOL> def parse_expvar_data ( self , data , tags , metrics , max_metrics ) : <EOL> '''<STR_LIT>''' <EOL> count = <NUM_LIT:0> <EOL> for metric in metrics : <EOL> path = metric . get ( PATH ) <EOL> metric_type = metric . get ( TYPE , DEFAULT_TYPE ) <EOL> metric_tags = list ( metric . get ( TAGS , [ ] ) ) <EOL> metric_tags += tags <EOL> alias = metric . get ( ALIAS ) <EOL> if not path : <EOL> self . warning ( "<STR_LIT>" % metric ) <EOL> continue <EOL> if metric_type not in SUPPORTED_TYPES : <EOL> self . warning ( "<STR_LIT>" % metric_type ) <EOL> continue <EOL> keys = path . split ( "<STR_LIT:/>" ) <EOL> values = self . deep_get ( data , keys ) <EOL> if len ( values ) == <NUM_LIT:0> : <EOL> self . warning ( "<STR_LIT>" % path ) <EOL> continue <EOL> tag_by_path = alias is not None <EOL> for traversed_path , value in values : <EOL> actual_path = "<STR_LIT:.>" . join ( traversed_path ) <EOL> if tag_by_path : <EOL> metric_tags . append ( "<STR_LIT>" % actual_path ) <EOL> metric_name = alias or self . normalize ( actual_path , METRIC_NAMESPACE , fix_case = True ) <EOL> try : <EOL> float ( value ) <EOL> except ValueError : <EOL> self . log . warning ( "<STR_LIT>" % ( path , value ) ) <EOL> continue <EOL> if count >= max_metrics : <EOL> self . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return <EOL> SUPPORTED_TYPES [ metric_type ] ( self , metric_name , value , metric_tags ) <EOL> count += <NUM_LIT:1> <EOL> def deep_get ( self , content , keys , traversed_path = None ) : <EOL> '''<STR_LIT>''' <EOL> if traversed_path is None : <EOL> traversed_path = [ ] <EOL> if keys == [ ] : <EOL> return [ ( traversed_path , content ) ] <EOL> key = keys [ <NUM_LIT:0> ] <EOL> regex = "<STR_LIT>" . join ( [ "<STR_LIT>" , key , "<STR_LIT:$>" ] ) <EOL> try : <EOL> key_rex = re . compile ( regex ) <EOL> except Exception : <EOL> self . warning ( "<STR_LIT>" % regex ) <EOL> return [ ] <EOL> results = [ ] <EOL> for new_key , new_content in self . items ( content ) : <EOL> if key_rex . match ( new_key ) : <EOL> results . extend ( self . deep_get ( new_content , keys [ <NUM_LIT:1> : ] , traversed_path + [ str ( new_key ) ] ) ) <EOL> return results <EOL> def items ( self , object ) : <EOL> if isinstance ( object , list ) : <EOL> for new_key , new_content in enumerate ( object ) : <EOL> yield str ( new_key ) , new_content <EOL> elif isinstance ( object , dict ) : <EOL> for new_key , new_content in object . iteritems ( ) : <EOL> yield str ( new_key ) , new_content <EOL> else : <EOL> self . log . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" ) </s>
