<s> from collections import defaultdict <EOL> import time <EOL> import psutil <EOL> from checks import AgentCheck <EOL> from config import _is_affirmative <EOL> from utils . platform import Platform <EOL> DEFAULT_AD_CACHE_DURATION = <NUM_LIT> <EOL> DEFAULT_PID_CACHE_DURATION = <NUM_LIT> <EOL> ATTR_TO_METRIC = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> class ProcessCheck ( AgentCheck ) : <EOL> def __init__ ( self , name , init_config , agentConfig , instances = None ) : <EOL> AgentCheck . __init__ ( self , name , init_config , agentConfig , instances ) <EOL> self . last_ad_cache_ts = <NUM_LIT:0> <EOL> self . ad_cache = set ( ) <EOL> self . access_denied_cache_duration = int ( <EOL> init_config . get ( <EOL> '<STR_LIT>' , <EOL> DEFAULT_AD_CACHE_DURATION <EOL> ) <EOL> ) <EOL> self . last_pid_cache_ts = { } <EOL> self . pid_cache = { } <EOL> self . pid_cache_duration = int ( <EOL> init_config . get ( <EOL> '<STR_LIT>' , <EOL> DEFAULT_PID_CACHE_DURATION <EOL> ) <EOL> ) <EOL> def should_refresh_ad_cache ( self ) : <EOL> now = time . time ( ) <EOL> return now - self . last_ad_cache_ts > self . access_denied_cache_duration <EOL> def should_refresh_pid_cache ( self , name ) : <EOL> now = time . time ( ) <EOL> return now - self . last_pid_cache_ts . get ( name , <NUM_LIT:0> ) > self . pid_cache_duration <EOL> def find_pids ( self , name , search_string , exact_match , ignore_ad = True , <EOL> refresh_ad_cache = True ) : <EOL> """<STR_LIT>""" <EOL> if not self . should_refresh_pid_cache ( name ) : <EOL> return self . pid_cache [ name ] <EOL> ad_error_logger = self . log . debug <EOL> if not ignore_ad : <EOL> ad_error_logger = self . log . error <EOL> refresh_ad_cache = self . should_refresh_ad_cache ( ) <EOL> matching_pids = set ( ) <EOL> for proc in psutil . process_iter ( ) : <EOL> if not refresh_ad_cache and proc . pid in self . ad_cache : <EOL> continue <EOL> found = False <EOL> for string in search_string : <EOL> try : <EOL> if string == '<STR_LIT>' : <EOL> found = True <EOL> if exact_match : <EOL> if proc . name ( ) == string : <EOL> found = True <EOL> else : <EOL> cmdline = proc . cmdline ( ) <EOL> if string in '<STR_LIT:U+0020>' . join ( cmdline ) : <EOL> found = True <EOL> except psutil . NoSuchProcess : <EOL> self . log . warning ( '<STR_LIT>' ) <EOL> except psutil . AccessDenied , e : <EOL> ad_error_logger ( '<STR_LIT>' , proc . pid ) <EOL> ad_error_logger ( '<STR_LIT>' , e ) <EOL> if refresh_ad_cache : <EOL> self . ad_cache . add ( proc . pid ) <EOL> if not ignore_ad : <EOL> raise <EOL> else : <EOL> if refresh_ad_cache : <EOL> self . ad_cache . discard ( proc . pid ) <EOL> if found : <EOL> matching_pids . add ( proc . pid ) <EOL> break <EOL> self . pid_cache [ name ] = matching_pids <EOL> self . last_pid_cache_ts [ name ] = time . time ( ) <EOL> return matching_pids <EOL> def psutil_wrapper ( self , process , method , accessors , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if accessors is None : <EOL> result = None <EOL> else : <EOL> result = { } <EOL> if method == '<STR_LIT>' and ( Platform . is_win32 ( ) or Platform . is_solaris ( ) ) : <EOL> return result <EOL> elif method == '<STR_LIT>' and not Platform . is_unix ( ) : <EOL> return result <EOL> try : <EOL> res = getattr ( process , method ) ( * args , ** kwargs ) <EOL> if accessors is None : <EOL> result = res <EOL> else : <EOL> for acc in accessors : <EOL> try : <EOL> result [ acc ] = getattr ( res , acc ) <EOL> except AttributeError : <EOL> self . log . debug ( "<STR_LIT>" , method , acc ) <EOL> except ( NotImplementedError , AttributeError ) : <EOL> self . log . debug ( "<STR_LIT>" , method ) <EOL> except psutil . AccessDenied : <EOL> self . log . debug ( "<STR_LIT>" , method ) <EOL> except psutil . NoSuchProcess : <EOL> self . warning ( "<STR_LIT>" . format ( process . pid ) ) <EOL> return result <EOL> def get_process_state ( self , name , pids , cpu_check_interval ) : <EOL> st = defaultdict ( list ) <EOL> for pid in pids : <EOL> st [ '<STR_LIT>' ] . append ( pid ) <EOL> try : <EOL> p = psutil . Process ( pid ) <EOL> except psutil . NoSuchProcess : <EOL> self . warning ( '<STR_LIT>' % pid ) <EOL> self . last_pid_cache_ts [ name ] = <NUM_LIT:0> <EOL> continue <EOL> meminfo = self . psutil_wrapper ( p , '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> st [ '<STR_LIT>' ] . append ( meminfo . get ( '<STR_LIT>' ) ) <EOL> st [ '<STR_LIT>' ] . append ( meminfo . get ( '<STR_LIT>' ) ) <EOL> shared_mem = self . psutil_wrapper ( p , '<STR_LIT>' , [ '<STR_LIT>' ] ) . get ( '<STR_LIT>' ) <EOL> if shared_mem is not None and meminfo . get ( '<STR_LIT>' ) is not None : <EOL> st [ '<STR_LIT>' ] . append ( meminfo [ '<STR_LIT>' ] - shared_mem ) <EOL> else : <EOL> st [ '<STR_LIT>' ] . append ( None ) <EOL> ctxinfo = self . psutil_wrapper ( p , '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> st [ '<STR_LIT>' ] . append ( ctxinfo . get ( '<STR_LIT>' ) ) <EOL> st [ '<STR_LIT>' ] . append ( ctxinfo . get ( '<STR_LIT>' ) ) <EOL> st [ '<STR_LIT>' ] . append ( self . psutil_wrapper ( p , '<STR_LIT>' , None ) ) <EOL> st [ '<STR_LIT>' ] . append ( self . psutil_wrapper ( p , '<STR_LIT>' , None , cpu_check_interval ) ) <EOL> st [ '<STR_LIT>' ] . append ( self . psutil_wrapper ( p , '<STR_LIT>' , None ) ) <EOL> ioinfo = self . psutil_wrapper ( p , '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> st [ '<STR_LIT>' ] . append ( ioinfo . get ( '<STR_LIT>' ) ) <EOL> st [ '<STR_LIT>' ] . append ( ioinfo . get ( '<STR_LIT>' ) ) <EOL> st [ '<STR_LIT>' ] . append ( ioinfo . get ( '<STR_LIT>' ) ) <EOL> st [ '<STR_LIT>' ] . append ( ioinfo . get ( '<STR_LIT>' ) ) <EOL> return st <EOL> def check ( self , instance ) : <EOL> name = instance . get ( '<STR_LIT:name>' , None ) <EOL> tags = instance . get ( '<STR_LIT>' , [ ] ) <EOL> exact_match = _is_affirmative ( instance . get ( '<STR_LIT>' , True ) ) <EOL> search_string = instance . get ( '<STR_LIT>' , None ) <EOL> ignore_ad = _is_affirmative ( instance . get ( '<STR_LIT>' , True ) ) <EOL> cpu_check_interval = instance . get ( '<STR_LIT>' , <NUM_LIT:0.1> ) <EOL> if not isinstance ( search_string , list ) : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> if "<STR_LIT>" in search_string : <EOL> self . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if name is None : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> if search_string is None : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> if not isinstance ( cpu_check_interval , ( int , long , float ) ) : <EOL> self . warning ( "<STR_LIT>" ) <EOL> cpu_check_interval = <NUM_LIT:0.1> <EOL> pids = self . find_pids ( <EOL> name , <EOL> search_string , <EOL> exact_match , <EOL> ignore_ad = ignore_ad <EOL> ) <EOL> proc_state = self . get_process_state ( name , pids , cpu_check_interval ) <EOL> tags . extend ( [ '<STR_LIT>' % name , name ] ) <EOL> self . log . debug ( '<STR_LIT>' , name ) <EOL> self . gauge ( '<STR_LIT>' , len ( pids ) , tags = tags ) <EOL> for attr , mname in ATTR_TO_METRIC . iteritems ( ) : <EOL> vals = [ x for x in proc_state [ attr ] if x is not None ] <EOL> if vals : <EOL> self . gauge ( '<STR_LIT>' % mname , sum ( vals ) , tags = tags ) <EOL> self . _process_service_check ( name , len ( pids ) , instance . get ( '<STR_LIT>' , None ) ) <EOL> def _process_service_check ( self , name , nb_procs , bounds ) : <EOL> '''<STR_LIT>''' <EOL> tag = [ "<STR_LIT>" % name ] <EOL> status = AgentCheck . OK <EOL> message_str = "<STR_LIT>" <EOL> status_str = { <EOL> AgentCheck . OK : "<STR_LIT:OK>" , <EOL> AgentCheck . WARNING : "<STR_LIT>" , <EOL> AgentCheck . CRITICAL : "<STR_LIT>" <EOL> } <EOL> if not bounds and nb_procs < <NUM_LIT:1> : <EOL> status = AgentCheck . CRITICAL <EOL> elif bounds : <EOL> warning = bounds . get ( '<STR_LIT>' , [ <NUM_LIT:1> , float ( '<STR_LIT>' ) ] ) <EOL> critical = bounds . get ( '<STR_LIT>' , [ <NUM_LIT:1> , float ( '<STR_LIT>' ) ] ) <EOL> if warning [ <NUM_LIT:1> ] < nb_procs or nb_procs < warning [ <NUM_LIT:0> ] : <EOL> status = AgentCheck . WARNING <EOL> if critical [ <NUM_LIT:1> ] < nb_procs or nb_procs < critical [ <NUM_LIT:0> ] : <EOL> status = AgentCheck . CRITICAL <EOL> self . service_check ( <EOL> "<STR_LIT>" , <EOL> status , <EOL> tags = tag , <EOL> message = message_str % ( status_str [ status ] , nb_procs , name ) <EOL> ) </s>
