コード例 #1
0
 def _iter_status_items(self):
     """Iterator over status information dicts extracted from files"""
     for job_spec_file in self.files:
         pid_file = job_spec_file.pid_file
         if pid_file.exists():
             process_exists = pid_file.process.exists()
             if process_exists is None:
                 error = PIDAccessError(
                     "{} No access to PID {}!".format(
                         pid_file.name, pid_file.pid
                     )
                 )
                 self.logger.warning(format_exception(error))
                 continue
             if process_exists:
                 status = JobSpecStatus.ACTIVE
             else:
                 status = JobSpecStatus.STALLED
         else:
             status = JobSpecStatus.STALLED
         item = OrderedDict()
         item["name"] = job_spec_file.name
         item["status"] = status
         item["job_spec"] = job_spec_file.job_spec
         item["_job_spec_file"] = job_spec_file
         yield item
コード例 #2
0
ファイル: base.py プロジェクト: unhaggle/django-cronman
 def warning(self, exception, silent=False):
     """Handles exception as warning"""
     message = format_exception(exception)
     if not silent:
         self.logger.warning(message)
         system_name = platform.node()
         self.slack.post("[{host}] {message}".format(host=system_name,
                                                     message=message))
     return message + "\n"  # to be printed on stdout
コード例 #3
0
ファイル: scheduler.py プロジェクト: unhaggle/django-cronman
 def on_error(self, error):
     """Method is used to notify Cronitor just after an exception is caught
     on cron scheduler `run`. Works if `CRONMAN_CRON_SCHEDULER_CRONITOR_ID`
     setting is provided, else does nothing.
     """
     if self.cronitor_id:
         message = format_exception(error)
         self.logger.error(message)
         self.cronitor.fail(self.cronitor_id, msg=message)
コード例 #4
0
 def on_error(self, job_spec, cron_job_class, args, kwargs, error):
     """Notifies monitor services when job failed"""
     cronitor_id = self.cronitor_id or cron_job_class.cronitor_id
     message = format_exception(error)
     self.logger.error(message)
     self.sentry.capture_exception(error)
     if cronitor_id and cron_job_class.cronitor_ping_fail:
         self.cronitor.fail(cronitor_id, msg=message)
     if self.debug:
         traceback.print_exc(file=sys.stderr)
コード例 #5
0
 def _ping(self, cronitor_id, end_point, msg):
     """Sends a request to Cronitor web API"""
     if not self.enabled:
         self.logger.warning(
             "Cronitor request ignored (disabled in settings).")
         return
     url = self.url.format(cronitor_id=cronitor_id, end_point=end_point)
     params = {"msg": msg} if msg else None
     try:
         response = requests.head(url, params=params, timeout=10)
         response.raise_for_status()
     except requests.RequestException as error:
         # Catch all network and HTTP errors raised by `requests`
         self.logger.warning("Cronitor request failed: {} {}".format(
             url, format_exception(error)))
コード例 #6
0
 def parse_job_spec_with_class(job_spec=None):
     """Converts a string (job spec) into quadruple
     (name, args, kwargs, cron_job_class).
     Raises CronWorkerInvalidParams if string cannot be parsed or
     there is no cron job class for given specification.
     """
     if job_spec:
         try:
             name, args, kwargs = parse_job_spec(job_spec)
             cron_job_class = cron_job_registry.get(name)
         except (ValueError, CronJobNotRegistered) as error:
             raise CronWorkerInvalidParams(format_exception(error))
     else:
         name = args = kwargs = cron_job_class = None
     return name, args, kwargs, cron_job_class
コード例 #7
0
 def parse_job_spec_or_pid(job_spec_or_pid=None):
     """Converts a string (job spec or integer - PID) into quadruple
     (name, args, kwargs, pid).
     Raises CronWorkerInvalidParams if string cannot be parsed.
     """
     if job_spec_or_pid:
         if re.match(r"\d+", job_spec_or_pid):
             pid = int(job_spec_or_pid)
             name = args = kwargs = None
         else:
             pid = None
             try:
                 name, args, kwargs = parse_job_spec(job_spec_or_pid)
             except ValueError as error:
                 raise CronWorkerInvalidParams(format_exception(error))
     else:
         name = args = kwargs = pid = None
     return name, args, kwargs, pid
コード例 #8
0
    def post(self, message, channel=None):
        """Posts a message to Slack channel"""
        if not self.enabled:
            self.logger.warning(
                "Slack request ignored (disabled in settings).")
            return
        if not (self.url and self.token):
            raise ImproperlyConfigured(
                "CRONMAN_SLACK_URL and CRONMAN_SLACK_TOKEN are required by "
                "Slack integration. Please provide values for these settings "
                "or disable Slack integration (CRONMAN_SLACK_ENABLED = False)."
            )
        channel_url = "{}?{}".format(
            self.url,
            urlencode((
                ("token", self.token),
                ("channel", "#{}".format(channel or self.default_channel)),
            )),
        )
        # prepare message
        message = self._prepare_message(message)

        try:
            # We need to split message into packages because of
            # openssl/urllib3 error. We are going for 12000 chars here
            # as tests showed that this is properly sent to Slack
            chunked_message = chunks(message, 12000)
            for chunk in chunked_message:
                # Sending data of type unicode behaves badly:
                # it'll get automatically encoded to some random encoding
                # you don't get to choose. All data should be encoded
                # manually by the user before it's passed to requests.
                encoded_chunk = chunk.encode("utf-8")
                response = requests.post(channel_url,
                                         data=encoded_chunk,
                                         timeout=7)
                response.raise_for_status()
        except Exception as error:
            # Catch all network and HTTP errors raised by `requests`
            self.logger.error("Slack request failed: {}".format(
                format_exception(error)))
コード例 #9
0
 def _iter_status_items(self):
     """Iterator over status information dicts extracted from files"""
     for pid_file in self.files:
         pid = pid_file.pid
         process_exists = pid_file.process.exists()
         if process_exists is None:
             error = PIDAccessError(
                 "{} No access to PID {}!".format(pid_file.name, pid)
             )
             self.logger.warning(format_exception(error))
             continue
         if process_exists:
             status = PIDStatus.ALIVE
         else:
             status = PIDStatus.DEAD
         item = OrderedDict()
         item["name"] = pid_file.name
         item["status"] = status
         item["pid"] = pid
         item["_pid_file"] = pid_file
         yield item