def add_perf_data(self,data): r"""Add performance object into the response Args: data (str or :class:`~naghelp.PerfData`): the perf data string or PerfData object to add to the response. Have a look to `Performance data string syntax <http://nagios-plugins.org/doc/guidelines.html#AEN200>`_. Examples: >>> r = PluginResponse(OK) >>> r.add_begin('Begin\n') >>> r.add_end('End') >>> r.add_perf_data(PerfData('filesystem_/','55','%','95','98','0','100')) >>> r.add_perf_data(PerfData('filesystem_/usr','34','%','95','98','0','100')) >>> r.add_perf_data('cpu_wait=88%;40;60;0;100') >>> r.add_perf_data('cpu_user=12%;80;95;0;100') >>> print r OK|filesystem_/=55%;95;98;0;100 Begin End|filesystem_/usr=34%;95;98;0;100 cpu_wait=88%;40;60;0;100 cpu_user=12%;80;95;0;100 """ naghelp.logger.debug('response -> add_perf_data("%s") %s',data,naghelp.debug_caller()) if not isinstance(data,basestring): data = str(data) self.perf_items.append(data)
def add_perf_data(self,data): r"""Add performance object into the response Args: data (str or :class:`~naghelp.PerfData`): the perf data string or PerfData object to add to the response. Have a look to `Performance data string syntax <http://nagios-plugins.org/doc/guidelines.html#AEN200>`_. Examples: >>> r = PluginResponse(OK) >>> r.add_begin('Begin\n') >>> r.add_end('End') >>> r.add_perf_data(PerfData('filesystem_/','55','%','95','98','0','100')) >>> r.add_perf_data(PerfData('filesystem_/usr','34','%','95','98','0','100')) >>> r.add_perf_data('cpu_wait=88%;40;60;0;100') >>> r.add_perf_data('cpu_user=12%;80;95;0;100') >>> print r OK|filesystem_/=55%;95;98;0;100 Begin End| filesystem_/usr=34%;95;98;0;100 cpu_wait=88%;40;60;0;100 cpu_user=12%;80;95;0;100 """ naghelp.logger.debug('response -> add_perf_data("%s") %s',data,naghelp.debug_caller()) if not isinstance(data,basestring): data = str(data) self.perf_items.append(data)
def add_many(self,lst,*args,**kwargs): """Add several level messages NOT having a same level This works like :meth:`add_list` except that instead of giving a list of messages one have to specify a list of tuples (level,message). By this way, one can give a level to each message into the list. If a message is empty in the list, it is not added. Args: lst (list): A list of (level,message) tuples to add in levels messages section. args (list): if additional arguments are given, messages in ``lst`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are given, messages in ``lst`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> print r.get_current_level() OK >>> logs = ''' ... Power 0 is critical ... Power 1 is OK ... Power 2 is degraded ... Power 3 is failed ... Power 4 is OK ... Power 5 is degraded ... ''' >>> from textops import * >>> errors = [ (CRITICAL if error|haspatterni('critical|failed') else WARNING,error) ... for error in logs | grepv('OK') ] >>> print errors #doctest: +NORMALIZE_WHITESPACE [(WARNING, ''), (CRITICAL, 'Power 0 is critical'), (WARNING, 'Power 2 is degraded'), (CRITICAL, 'Power 3 is failed'), (WARNING, 'Power 5 is degraded')] >>> r.add_many(errors) >>> print r.get_current_level() CRITICAL >>> print r #doctest: +NORMALIZE_WHITESPACE STATUS : CRITICAL:2, WARNING:2 ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- Power 0 is critical Power 3 is failed <BLANKLINE> ----( WARNING )----------------------------------------------------------------- Power 2 is degraded Power 5 is degraded <BLANKLINE> <BLANKLINE> """ naghelp.logger.debug('response -> add_many(...) %s',naghelp.debug_caller()) for i,(level,msg) in enumerate(lst): naghelp.logger.debug('response -> [%s] (%s,"%s")',i,level,msg) if msg: self.add(level, msg,*args,**kwargs)
def add(self,level,msg,*args,**kwargs): r"""Add a message in levels messages section and sets the response level at the same time Use this method each time your plugin detects a WARNING or a CRITICAL error. You can also use this method to add a message saying there is an UNKNOWN or OK state somewhere. You can use this method several times and at any time until the :meth:`send` is used. This method updates the calculated ResponseLevel. When the response is rendered, the added messages are splitted into sub-section Args: level (ResponseLevel): the message level (Will affect the final response level) msg (str): the message to add in levels messages section. args (list): if additional arguments are given, ``msg`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are given, ``msg`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> print r.get_current_level() OK >>> r.add(CRITICAL,'The system crashed') >>> r.add(WARNING,'Found some almost full file system') >>> r.add(UNKNOWN,'Cannot find FAN %s status',0) >>> r.add(OK,'Power {power_id} is ON',power_id=1) >>> print r.get_current_level() CRITICAL >>> print r #doctest: +NORMALIZE_WHITESPACE STATUS : CRITICAL:1, WARNING:1, UNKNOWN:1, OK:1 ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- The system crashed <BLANKLINE> ----( WARNING )----------------------------------------------------------------- Found some almost full file system <BLANKLINE> ----( UNKNOWN )----------------------------------------------------------------- Cannot find FAN 0 status <BLANKLINE> ----( OK )---------------------------------------------------------------------- Power 1 is ON <BLANKLINE> <BLANKLINE> """ if not kwargs.get('no_debug'): naghelp.logger.debug('response -> add(%s,"%s") %s',level,msg,naghelp.debug_caller()) if isinstance(level,ResponseLevel): self.level_msgs[level].append(self._reformat_msg(msg,*args,**kwargs)) self.set_level(level) else: raise Exception('A response level must be an instance of ResponseLevel, Found level=%s (%s).' % (level,type(level)))
def add_end(self,msg,*args,**kwargs): r"""Add a message in end section You can use this method several times and at any time until the :meth:`send` is used. The messages will be displayed in end section in the same order as they have been added. This method does not change the calculated ResponseLevel. Args: msg (str): the message to add in end section. args (list): if additional arguments are given, ``msg`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are give, ``msg`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> r.add_end('='*40) >>> r.add_end('{hostname:^40}', hostname='MyHost') >>> r.add_end('='*40) >>> r.add_end('Date : %s, Time : %s','2105-12-18','14:55:11') >>> r.add_end('\n') >>> r.add(CRITICAL,'This is critical !') >>> print r #doctest: +NORMALIZE_WHITESPACE This is critical ! <BLANKLINE> ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- This is critical ! <BLANKLINE> <BLANKLINE> ======================================== MyHost ======================================== Date : 2105-12-18, Time : 14:55:11 """ naghelp.logger.debug('response -> add_more("%s") %s',msg,naghelp.debug_caller()) if isinstance(msg,(list,tuple)): msg = '\n'.join(msg) elif not isinstance(msg,basestring): msg = str(msg) if args: msg = msg % args if kwargs: msg = msg.format(**kwargs) self.end_msgs.append(msg)
def add_end(self,msg,*args,**kwargs): r"""Add a message in end section You can use this method several times and at any time until the :meth:`send` is used. The messages will be displayed in end section in the same order as they have been added. This method does not change the calculated ResponseLevel. Args: msg (str): the message to add in end section. args (list): if additional arguments are given, ``msg`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are give, ``msg`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> r.add_end('='*40) >>> r.add_end('{hostname:^40}', hostname='MyHost') >>> r.add_end('='*40) >>> r.add_end('Date : %s, Time : %s','2105-12-18','14:55:11') >>> r.add_end('\n') >>> r.add(CRITICAL,'This is critical !') >>> print r #doctest: +NORMALIZE_WHITESPACE This is critical ! <BLANKLINE> ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- This is critical ! <BLANKLINE> <BLANKLINE> ======================================== MyHost ======================================== Date : 2105-12-18, Time : 14:55:11 """ naghelp.logger.debug('response -> add_end("%s") %s',msg,naghelp.debug_caller()) self.end_msgs.append(self._reformat_msg(msg, *args, **kwargs))
def add_more(self,msg,*args,**kwargs): r"""Add a message in "more messages" section (aka "Additionnal informations") You can use this method several times and at any time until the :meth:`send` is used. The messages will be displayed in the section in the same order as they have been added. This method does not change the calculated ResponseLevel. Args: msg (str): the message to add in end section. args (list): if additional arguments are given, ``msg`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are give, ``msg`` will be formatted with :meth:`str.format` Note: The "Additionnal informations" section title will be added automatically if the section is not empty. Examples: >>> r = PluginResponse(OK) >>> r.add(CRITICAL,'This is critical !') >>> r.add_more('Date : %s, Time : %s','2105-12-18','14:55:11') >>> print r #doctest: +NORMALIZE_WHITESPACE This is critical ! ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- This is critical ! <BLANKLINE> ==========================[ Additionnal informations ]========================== Date : 2105-12-18, Time : 14:55:11 """ if not kwargs.get('no_debug'): naghelp.logger.debug('response -> add_more("%s") %s',msg,naghelp.debug_caller()) if msg: self.more_msgs.append(self._reformat_msg(msg,*args,**kwargs))
def add_comment(self,level,msg,*args,**kwargs): r"""Add a comment in levels messages section and sets the response level at the same time it works like :meth:`add` except that the message is not counted into the synopsis Args: level (ResponseLevel): the message level (Will affect the final response level) msg (str): the message to add in levels messages section. args (list): if additionnal arguments are given, ``msg`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are given, ``msg`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> print r.get_current_level() OK >>> r.add_comment(CRITICAL,'Here are some errors') >>> r.add(CRITICAL,'error 1') >>> r.add(CRITICAL,'error 2') >>> print r #doctest: +NORMALIZE_WHITESPACE STATUS : CRITICAL:2 ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- Here are some errors error 1 error 2 <BLANKLINE> <BLANKLINE> """ naghelp.logger.debug('response -> add_comment(%s,"%s") %s',level,msg,naghelp.debug_caller()) if isinstance(level,ResponseLevel): self.level_msgs[level].append(LevelComment(self._reformat_msg(msg,*args,**kwargs))) else: raise Exception('A response level must be an instance of ResponseLevel, Found level=%s (%s).' % (level,type(level)))
def add_elif(self,*add_ifs,**kwargs): r"""Multi-conditionnal message add This works like :meth:`add_if` except that it accepts multiple tests. Like python ``elif``, the method stops on first True test and send corresponding message. If you want to build the equivalent of a *default* message, just use ``True`` as the last test. Args: add_ifs (list): list of tuple (test,level,message). kwargs (dict): if named arguments are given, messages will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> print r.get_current_level() OK >>> logs = ''' ... Power 0 is critical ... Power 1 is OK ... Power 2 is degraded ... Power 3 is failed ... Power 4 is OK ... Power 5 is degraded ... Power 6 is smoking ... ''' >>> from textops import * >>> for log in logs | rmblank(): ... r.add_elif( (log|haspattern('critical|failed'), CRITICAL, log), ... (log|haspattern('degraded|warning'), WARNING, log), ... (log|haspattern('OK'), OK, log), ... (True, UNKNOWN, log) ) >>> print r.get_current_level() CRITICAL >>> print r #doctest: +NORMALIZE_WHITESPACE STATUS : CRITICAL:2, WARNING:2, UNKNOWN:1, OK:2 ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- Power 0 is critical Power 3 is failed <BLANKLINE> ----( WARNING )----------------------------------------------------------------- Power 2 is degraded Power 5 is degraded <BLANKLINE> ----( UNKNOWN )----------------------------------------------------------------- Power 6 is smoking <BLANKLINE> ----( OK )---------------------------------------------------------------------- Power 1 is OK Power 4 is OK <BLANKLINE> <BLANKLINE> """ naghelp.logger.debug('response -> add_elif(...) %s',naghelp.debug_caller()) for i,(test,level,msg) in enumerate(add_ifs): naghelp.logger.debug('response -> [%s] (%s,%s,"%s")',i,test,level,msg) if msg is None: msg = test if isinstance(level,ResponseLevel): if test: self.add(level,msg,**kwargs) self.set_level(level) break else: raise Exception('A response level must be an instance of ResponseLevel, Found level=%s (%s).' % (level,type(level)))
def add_if(self, test, level, msg=None, header=None,footer=None, *args,**kwargs): r"""Test than add a message in levels messages section and sets the response level at the same time This works like :meth:`add` except that it is conditionnal : ``test`` must be True. If no message is given, the value of ``test`` is used. Args: test (any): the message is added to the response only if bool(test) is True. level (ResponseLevel): the message level (Will affect the final response level) msg (str): the message to add in levels messages section. If no message is given, the value of test is used. header (str): Displayed before the message as a level comment if not None (Default : None) footer (str): Displayed after the message as a level comment if not None (Default : None) args (list): if additional arguments are given, ``msg`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are given, ``msg`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> print r.get_current_level() OK >>> logs = ''' ... Power 0 is critical ... Power 1 is OK ... Power 2 is degraded ... Power 3 is failed ... Power 4 is OK ... Power 5 is degraded ... ''' >>> from textops import * >>> nb_criticals = logs | grepc('critical|failed') >>> print nb_criticals 2 >>> warnings = logs | grep('degraded|warning').tostr() >>> print warnings Power 2 is degraded Power 5 is degraded >>> unknowns = logs | grep('unknown').tostr() >>> print unknowns <BLANKLINE> >>> r.add_if(nb_criticals,CRITICAL,'{n} power(s) are critical',n=nb_criticals) >>> r.add_if(warnings,WARNING) >>> r.add_if(unknowns,UNKNOWN) >>> print r.get_current_level() CRITICAL >>> print r #doctest: +NORMALIZE_WHITESPACE STATUS : CRITICAL:1, WARNING:1 ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- 2 power(s) are critical <BLANKLINE> ----( WARNING )----------------------------------------------------------------- Power 2 is degraded Power 5 is degraded <BLANKLINE> <BLANKLINE> """ naghelp.logger.debug('response -> add_if(%s,%s,"%s") %s',test,level,msg,naghelp.debug_caller()) if msg is None: msg = test if isinstance(level,ResponseLevel): if test: if header is not None: self.add_comment(level, header,*args,**kwargs) self.add(level,msg,*args,**kwargs) if footer is not None: self.add_comment(level, footer,*args,**kwargs) self.set_level(level) else: raise Exception('A response level must be an instance of ResponseLevel, Found level=%s (%s).' % (level,type(level)))
def add_list(self,level,msg_list,header=None,footer=None,*args,**kwargs): """Add several level messages having a same level Sometimes, you may have to specify a list of faulty parts in the response : this can be done by this method in a single line. If a message is empty in the list, it is not added. Args: level (ResponseLevel): the message level (Will affect the final response level) msg_list (list): the messages list to add in levels messages section. header (str): Displayed before the message as a level comment if not None (Default : None) one can use ``{_len}`` in the comment to get list count. footer (str): Displayed after the message as a level comment if not None (Default : None) one can use ``{_len}`` in the comment to get list count. args (list): if additional arguments are given, messages in ``msg_list`` will be formatted with ``%`` (old-style python string formatting) kwargs (dict): if named arguments are given, messages in ``msg_list`` will be formatted with :meth:`str.format` Examples: >>> r = PluginResponse(OK) >>> print r.get_current_level() OK >>> logs = ''' ... Power 0 is critical ... Power 1 is OK ... Power 2 is degraded ... Power 3 is failed ... Power 4 is OK ... Power 5 is degraded ... ''' >>> from textops import grep >>> criticals = logs >> grep('critical|failed') >>> warnings = logs >> grep('degraded|warning') >>> print criticals ['Power 0 is critical', 'Power 3 is failed'] >>> print warnings ['Power 2 is degraded', 'Power 5 is degraded'] >>> r.add_list(CRITICAL,criticals) >>> r.add_list(WARNING,warnings) >>> print r.get_current_level() CRITICAL >>> print r #doctest: +NORMALIZE_WHITESPACE STATUS : CRITICAL:2, WARNING:2 ==================================[ STATUS ]================================== <BLANKLINE> ----( CRITICAL )---------------------------------------------------------------- Power 0 is critical Power 3 is failed <BLANKLINE> ----( WARNING )----------------------------------------------------------------- Power 2 is degraded Power 5 is degraded <BLANKLINE> <BLANKLINE> >>> r = PluginResponse() >>> r.add_list(WARNING,['Power warning1','Power warning2'],'{_len} Power warnings:','Power warnings : {_len}') >>> r.add_list(WARNING,['CPU warning1','CPU warning2'],'{_len} CPU warnings:','CPU warnings : {_len}') >>> print r STATUS : WARNING:4 ==================================[ STATUS ]================================== <BLANKLINE> ----( WARNING )----------------------------------------------------------------- 2 Power warnings: Power warning1 Power warning2 Power warnings : 2 2 CPU warnings: CPU warning1 CPU warning2 CPU warnings : 2 <BLANKLINE> <BLANKLINE> """ have_added=False kwargs['_len'] = len(msg_list) naghelp.logger.debug('response -> add_list(...) %s',naghelp.debug_caller()) for i,msg in enumerate(msg_list): naghelp.logger.debug('response -> [%s] %s',i,msg) if msg: if not have_added and header is not None: self.add_comment(level, header,*args,**kwargs) self.add(level, msg,no_debug=True,*args,**kwargs) have_added = True if have_added and footer is not None: self.add_comment(level, footer,*args,**kwargs)