예제 #1
0
    def amtool_alert_query(self, mess, inhibited=False, silenced=False,
        active=False, unprocessed=False, receiver="", matchers=[]):
        """
          Queries alert in amtool command style
          --inhibited          Show inhibited alerts
          --silenced           Show silenced alerts
          --active             Show active alerts
          --unprocessed        Show unprocessed alerts
          --receiver=RECEIVER  Show alerts matching receiver (Supports regex syntax)

        Args:
          [<matcher-groups>]  Query filter
        """
        if not (inhibited or silenced or active or unprocessed):
            inhibited = True
            silenced = True
            active = True
            unprocessed = True
        self.log.info("matchers {0}".format(matchers))
        helper = AmtoolHelper(
            alertmanager_address=self.config['server_address'])
        filter = helper.get_filters_by_terms(matchers)
        result = helper.get_alerts(
            active=active,
            silenced=silenced,
            inhibited=inhibited,
            unprocessed=unprocessed,
            filter=filter,
            receiver=receiver
        )
        return result
예제 #2
0
 def amtool_status(self, mess, args):
     """Returns alert manager status"""
     self.log.info("Current config {0}".format(self.config))
     self.log.info(
         "Alertmanager @ {0}".format(self.config['server_address']))
     helper = AmtoolHelper(
         alertmanager_address=self.config['server_address'])
     result = helper.get_status()
     return result
예제 #3
0
    def amtool_silence_expire(self, mess, silence_id):
        """
             amtool silence expire silence-id

            expire an alertmanager silence

            Args:
              silence-id  Id of silences to expire
        """
        helper = AmtoolHelper(
            alertmanager_address=self.config['server_address'])
        result = helper.delete_silence(silence_id)
        return "Silence deleted"
예제 #4
0
 def amtool_alert_describe(self, mess, fingerprint):
     """Returns specific silence details"""
     helper = AmtoolHelper(
         alertmanager_address=self.config['server_address'])
     result = helper.get_alert(fingerprint)
     self.send_card(title=result["annotations"]["title"],
                    body=result["annotations"]["description"],
                    #                       thumbnail='https://raw.githubusercontent.com/errbotio/errbot/master/docs/_static/errbot.png',
                    #                       image='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
                    link=result["generatorURL"],
                    fields=result["labels"].items(),
                    color='blue',
                    in_reply_to=mess)
예제 #5
0
    def test_post_silence_suppress(self):
        amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
        start_period = datetime.now(pytz.timezone('Europe/Kiev'))
        end_period = start_period + timedelta(minutes=1)

        alert = amtoolhelper.get_alert('ee5d73c3f0a498f1')
        matchers = amtoolhelper.get_matchers_by_alert(alert, ["name", "role"])

        silence = amtoolhelper.post_silence(matchers=matchers,
                                            starts_at=start_period.isoformat(),
                                            ends_at=end_period.isoformat(),
                                            created_by="Someone",
                                            comment="test silence")
        self.assertIsNotNone(silence)
예제 #6
0
    def test_post_silence_selective(self):
        amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
        start_period = datetime.now(pytz.timezone('Europe/Kiev'))
        end_period = start_period + timedelta(minutes=1)

        alert = amtoolhelper.get_alert('af2442fa7f7ee655')
        matchers = amtoolhelper.get_matchers_by_terms(
            terms=["~StrategyDown2", "instance=i-049a6b9bbbb6fb76b"])

        silence = amtoolhelper.post_silence(matchers=matchers,
                                            starts_at=start_period.isoformat(),
                                            ends_at=end_period.isoformat(),
                                            created_by="Someone",
                                            comment="test silence")
        self.assertIsNotNone(silence)
예제 #7
0
    def amtool_silence_query(self, mess, expired=None, within=None, matchers=[]):
        """
          Amtool has a simplified prometheus query syntax The non-option section of arguments constructs a list of "Matcher Groups"
          that will be used to filter your query. The following examples will attempt to show this behaviour in action:

          amtool silence query alertname=foo node=bar

          This query will match all silences with the alertname=foo and node=bar label
          value pairs set.

          amtool silence query foo node=bar

          If alertname is omitted and the first argument does not contain a '=' or a
          '=~' then it will be assumed to be the value of the alertname pair.

          amtool silence query 'alertname=~foo.*'

          As well as direct equality, regex matching is also supported. The '=~' syntax
          (similar to prometheus) is used to represent a regex match. Regex matching
          can be used in combination with a direct match.

          In addition to filtering by silence labels, one can also query for silences that are due to expire soon
          with the "--within" parameter. In the event that you want to preemptively act upon expiring silences by
          either fixing them or extending them. For example:

          amtool silence query --within 8h

          returns all the silences due to expire within the next 8 hours. This syntax can also be combined with the label based
          filtering above for more flexibility.

          The "--expired" parameter returns only expired silences. Used in combination with "--within=TIME", amtool returns
          the silences that expired within the preceding duration.

          amtool silence query --within 2h --expired

returns all silences that expired within the preceeding 2 hours.

      --expired        Show expired silences instead of active
      --within=WITHIN  Show silences that will expire or have expired within a duration
        """
        helper = AmtoolHelper(
            alertmanager_address=self.config['server_address'])
        filters = helper.get_filters_by_terms(matchers)
        self.log.info("Expired {0} within {1} filtered {2}".format(expired, within, filters))
        result = helper.get_silences(filter=filters, expired=expired, within=within)
        return {"silences": result}
예제 #8
0
    def test_post_silence_add(self):
        amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
        start_period = datetime.now().utcnow()

        cal = pdt.Calendar()
        diff = cal.parseDT("1h", sourceTime=datetime.min)[0] - datetime.min
        end_period = start_period + diff

        utc = pytz.UTC
        start_period = utc.localize(start_period)
        end_period = utc.localize(end_period)

        parsed_matchers = amtoolhelper.get_matchers_by_terms(
            ["instance=i-049a6b9bbbb6fb76b"])
        silence = amtoolhelper.post_silence(matchers=parsed_matchers,
                                            starts_at=start_period.isoformat(),
                                            ends_at=end_period.isoformat(),
                                            created_by="errbot",
                                            comment="test comment")
        self.assertIsNotNone(silence)
예제 #9
0
    def amtool_suppress(self, mess, author="errbot", comment="", weeks=0, days=0, hours=0, minutes=0, criteria=[]):
        """Puts exact suppress match on alert"""
        helper = AmtoolHelper(
            alertmanager_address=self.config['server_address'])

        start_period = datetime.now(pytz.timezone(self.config['time_zone']))
        if weeks+days+hours+minutes == 0:
            hours = 1
        end_period = start_period + timedelta(minutes=minutes, hours=hours,
                                              days=days, weeks=weeks)
        self.log.info("Suppressing {0}->{1}".format(start_period, end_period))
        fingerprint = criteria.pop(0)
        self.log.info("Getting alert by fingerprint {0}".format(fingerprint))
        alert = helper.get_alert(fingerprint)
        matchers = helper.get_matchers_by_alert(alert, include_terms=criteria)
        self.log.info("Matchers {0}".format(matchers))
        result = helper.post_silence(
            matchers=matchers,
            starts_at=start_period.isoformat(),
            ends_at=end_period.isoformat(),
            created_by=author,
            comment=comment
        )
        self.send_card(title="Alert suppressed until {0}".format(end_period),
                    body="Alert created by {0} with description '{1}'. To cancel  !amtool silence expire {2}".format(author, comment, result.silence_id),
                    #                       thumbnail='https://raw.githubusercontent.com/errbotio/errbot/master/docs/_static/errbot.png',
                    #                       image='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
                    # link=result["generatorURL"],
                    fields=helper.convert_matchers_to_tuples(matchers),
                    color='blue',
                    in_reply_to=mess)
예제 #10
0
 def amtool_brief(self, mess, args):
     """Returns brief on alerts"""
     helper = AmtoolHelper(
         alertmanager_address=self.config['server_address'])
     result = helper.get_alerts()
     return result
예제 #11
0
 def test_get_status(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     amtoolhelper.get_status()
예제 #12
0
 def amtool_silence_describe(self, mess, silence_id):
     """Returns specific silence details"""
     helper = AmtoolHelper(
         alertmanager_address=self.config['server_address'])
     result = helper.get_silence(silence_id)
     return result
예제 #13
0
 def amtool_receivers(self, mess, args):
     """Returns current receivers list"""
     helper = AmtoolHelper(
         alertmanager_address=self.config['server_address'])
     result = helper.get_receivers()
     return result
예제 #14
0
 def test_get_alerts(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     alerts = amtoolhelper.get_alerts()
     self.assertIsNotNone(alerts)
예제 #15
0
 def amtool_silences(self, mess, args):
     """Returns current silences list"""
     helper = AmtoolHelper(
         alertmanager_address=self.config['server_address'])
     result = helper.get_silences()
     return {"silences": result}
예제 #16
0
 def test_get_alert(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     alert = amtoolhelper.get_alert('af2442fa7f7ee655')
     self.assertIsNotNone(alert)
예제 #17
0
 def test_get_alerts_with_filter(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     filter = amtoolhelper.get_filters_by_terms(["env=live"])
     alerts = amtoolhelper.get_alerts(filter=filter)
     self.assertIsNotNone(alerts)
예제 #18
0
 def test_get_silences(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     silences = amtoolhelper.get_silences(filter=[])
     self.assertIsNotNone(silences)
예제 #19
0
    def amtool_silence_add(self, mess, author, duration, start, end, comment,
        matchers):
        """
            usage: !amtool silence add [<flags>] [<matcher-groups>...]

            Add a new alertmanager silence

                Amtool uses a simplified Prometheus syntax to represent silences. The
                non-option section of arguments constructs a list of "Matcher Groups"
                that will be used to create a number of silences. The following examples
                will attempt to show this behaviour in action:

                !amtool silence add alertname=foo node=bar

                    This statement will add a silence that matches alerts with the
                    alertname=foo and node=bar label value pairs set.

                !amtool silence add foo node=bar

                    If alertname is omitted and the first argument does not contain a '=' or a
                    '=~' then it will be assumed to be the value of the alertname pair.

                !amtool silence add 'alertname=~foo.*'

                    As well as direct equality, regex matching is also supported. The '=~' syntax
                    (similar to Prometheus) is used to represent a regex match. Regex matching
                    can be used in combination with a direct match.

              --author="slavko"  Username for CreatedBy field
              --duration="1h"    Duration of silence
              --start=START      Set when the silence should start. RFC3339 format 2006-01-02T15:04:05-07:00
              --end=END          Set when the silence should end (overwrites duration). RFC3339 format 2006-01-02T15:04:05-07:00
              --comment=COMMENT  A comment to help describe the silence

        """
        helper = AmtoolHelper(
            alertmanager_address=self.config['server_address'])
        if start is not None:
            start_period = dateparser.parse(start)
        else:
            start_period = datetime.now().utcnow()

        if end is not None:
            end_period = dateparser.parse(end)
        else:
            cal = pdt.Calendar()
            diff = cal.parseDT(duration, sourceTime=datetime.min)[
                       0] - datetime.min
            end_period = start_period + diff

        utc = pytz.UTC

        start_period = utc.localize(start_period)
        end_period = utc.localize(end_period)

        parsed_matchers = helper.get_matchers_by_terms(matchers)
        self.log.info("Suppressing {0}->{1}".format(start_period, end_period))
        self.log.info("Matchers {0}".format(parsed_matchers))
        result = helper.post_silence(
            matchers=parsed_matchers,
            starts_at=start_period.isoformat(),
            ends_at=end_period.isoformat(),
            created_by=author,
            comment=comment
        )
        self.log.info("Added {0}".format(result))
        self.send_card(title="Silence added until {0}".format(end_period),
                    body="Alert created by {0} with description '{1}'. To cancel  !amtool silence expire {2}".format(author, comment, result.silence_id),
                    #                       thumbnail='https://raw.githubusercontent.com/errbotio/errbot/master/docs/_static/errbot.png',
                    #                       image='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
                    # link=result["generatorURL"],
                    fields=helper.convert_matchers_to_tuples(parsed_matchers),
                    color='blue',
                    in_reply_to=mess)
예제 #20
0
 def test_post_silence_selective(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     parsed_matchers = amtoolhelper.get_matchers_by_terms(["instance=222"])
     tuples = amtoolhelper.convert_matchers_to_tuples(parsed_matchers)
예제 #21
0
 def test_expired_within_silences(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     silences = amtoolhelper.get_silences(filter=[],
                                          expired=True,
                                          within="1h")
     self.assertIsNotNone(silences)
예제 #22
0
 def test_get_silence(self):
     amtoolhelper = AmtoolHelper(alertmanager_address=ALERTMANAGER_HOST)
     silence = amtoolhelper.get_silence(
         silence_id="bb788860-35d2-48e7-9062-f082c77d202d")
     self.assertIsNotNone(silence)