<commit_before>import logging

logger = logging.getLogger(__name__)

import nymms
from nymms import results
from nymms.daemon import NymmsDaemon
from nymms.resources import Monitor
from nymms.utils import commands
from nymms.config.yaml_config import load_config, EmptyConfig
from nymms.exceptions import MissingCommandContext


class Probe(NymmsDaemon):
    def get_private_context(self, private_context_file):
        if not private_context_file:
            return None
        try:
            return load_config(private_context_file)[1]
        except (IOError, EmptyConfig) as e:
            logger.exception("Unable to open private context file: %s",
                             private_context_file)
            return None

    # TODO: This calls on _state_backend but setting up of the _state_backend
    #       needs to be handled in the subclass.  Not sure how I should handle
    #       this, but I really like the idea of these being base class
    #       methods since in reality all reactors should have some sort of
    #       state backend, even if its a no-op
    def get_state(self, task_id):
        return self._state_backend.get_state(task_id)

    def get_task(self, **kwargs):
        raise NotImplementedError

    def resubmit_task(self, task, delay):
        raise NotImplementedError

    def submit_result(self, result):
        raise NotImplementedError

    def execute_task(self, task, timeout):
        log_prefix = "%s - " % (task.id,)
        monitor = Monitor.registry[task.context['monitor']['name']]
        command = monitor.command.command_string
        current_attempt = int(task.attempt) + 1
        logger.debug(log_prefix + "attempt %d, executing: %s", current_attempt,
                     command)
        result = results.Result(task.id, timestamp=task.created,
                                task_context=task.context)
        try:
            output = monitor.execute(task.context, timeout,
                                     self._private_context)
            result.output = output
            result.state = results.OK
        except commands.CommandException as e:
            if isinstance(e, commands.CommandFailure):
                result.state = e.return_code
                result.output = e.output
            if isinstance(e, commands.CommandTimeout):
                result.state = results.UNKNOWN
                result.output = ("Command timed out after %d seconds." % 
                                 timeout)
        except MissingCommandContext as e:
            result.state = results.UNKNOWN
            result.output = str(e)
        return result

    def handle_task(self, task, **kwargs):
        log_prefix = "%s - " % (task.id,)
        previous_state = self.get_state(task.id)
        # check if the timeout is defined on the task first, if not then
        # go with what was passed into handle_task via run
        timeout = task.context.get('monitor_timeout',
                                   kwargs.get('monitor_timeout'))
        max_retries = task.context.get('max_retries',
                                       kwargs.get('max_retries'))
        last_attempt = int(task.attempt)
        current_attempt = last_attempt + 1
        result = self.execute_task(task, timeout)
        result.state_type = results.HARD
        # Trying to emulate this:
        # http://nagios.sourceforge.net/docs/3_0/statetypes.html
        if result.state == results.OK:
            if (previous_state and not previous_state.state == results.OK and
                previous_state.state_type == results.SOFT):
                    result.state_type = results.SOFT
        else:
            logger.debug(log_prefix + "current_attempt: %d, max_retries: %d", <commit_msg>Catch all exceptions from command execution<commit_after>import logging

logger = logging.getLogger(__name__)

import nymms
from nymms import results
from nymms.daemon import NymmsDaemon
from nymms.resources import Monitor
from nymms.utils import commands
from nymms.config.yaml_config import load_config, EmptyConfig
from nymms.exceptions import MissingCommandContext


class Probe(NymmsDaemon):
    def get_private_context(self, private_context_file):
        if not private_context_file:
            return None
        try:
            return load_config(private_context_file)[1]
        except (IOError, EmptyConfig) as e:
            logger.exception("Unable to open private context file: %s",
                             private_context_file)
            return None

    # TODO: This calls on _state_backend but setting up of the _state_backend
    #       needs to be handled in the subclass.  Not sure how I should handle
    #       this, but I really like the idea of these being base class
    #       methods since in reality all reactors should have some sort of
    #       state backend, even if its a no-op
    def get_state(self, task_id):
        return self._state_backend.get_state(task_id)

    def get_task(self, **kwargs):
        raise NotImplementedError

    def resubmit_task(self, task, delay):
        raise NotImplementedError

    def submit_result(self, result):
        raise NotImplementedError

    def execute_task(self, task, timeout):
        log_prefix = "%s - " % (task.id,)
        monitor = Monitor.registry[task.context['monitor']['name']]
        command = monitor.command.command_string
        current_attempt = int(task.attempt) + 1
        logger.debug(log_prefix + "attempt %d, executing: %s", current_attempt,
                     command)
        result = results.Result(task.id, timestamp=task.created,
                                task_context=task.context)
        try:
            output = monitor.execute(task.context, timeout,
                                     self._private_context)
            result.output = output
            result.state = results.OK
        except commands.CommandException as e:
            if isinstance(e, commands.CommandFailure):
                result.state = e.return_code
                result.output = e.output
            if isinstance(e, commands.CommandTimeout):
                result.state = results.UNKNOWN
                result.output = ("Command timed out after %d seconds." % 
                                 timeout)
        except Exception as e:
            result.state = results.UNKNOWN
            result.output = str(e)
        return result

    def handle_task(self, task, **kwargs):
        log_prefix = "%s - " % (task.id,)
        previous_state = self.get_state(task.id)
        # check if the timeout is defined on the task first, if not then
        # go with what was passed into handle_task via run
        timeout = task.context.get('monitor_timeout',
                                   kwargs.get('monitor_timeout'))
        max_retries = task.context.get('max_retries',
                                       kwargs.get('max_retries'))
        last_attempt = int(task.attempt)
        current_attempt = last_attempt + 1
        result = self.execute_task(task, timeout)
        result.state_type = results.HARD
        # Trying to emulate this:
        # http://nagios.sourceforge.net/docs/3_0/statetypes.html
        if result.state == results.OK:
            if (previous_state and not previous_state.state == results.OK and
                previous_state.state_type == results.SOFT):
                    result.state_type = results.SOFT
        else:
            logger.debug(log_prefix + "current_attempt: %d, max_retries: %d", 
{'fraction_non_alphanumeric': 0.07751731486414491, 'fraction_numerical': 0.0013319126265316996, 'mean_word_length': 2.0952184666117066, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4852185', 'n_tokens_mistral': 2017, 'n_tokens_neox': 1937, 'n_words': 553}