Beispiel #1
0
    def expand(self):
        # Map of Prometheus labels to Promgen objects
        LABEL_MAPPING = [
            ('project', Project),
            ('service', Service),
        ]
        routable = {}
        data = json.loads(self.body)

        data.setdefault('commonLabels', {})
        data.setdefault('commonAnnotations', {})
        # Set our link back to Promgen for processed notifications
        # The original externalURL can still be visible from the alerts page
        data['externalURL'] = resolve_domain(self.get_absolute_url())

        # Look through our labels and find the object from Promgen's DB
        # If we find an object in Promgen, add an annotation with a direct link
        for label, klass in LABEL_MAPPING:
            if label not in data['commonLabels']:
                logger.debug('Missing label %s', label)
                continue

            # Should only find a single value, but I think filter is a little
            # bit more forgiving than get in terms of throwing errors
            for obj in klass.objects.filter(name=data['commonLabels'][label]):
                logger.debug('Found %s %s', label, obj)
                routable[label] = obj
                data['commonAnnotations'][label] = resolve_domain(obj)

        return routable, data
Beispiel #2
0
    def expand(self):
        # Map of Prometheus labels to Promgen objects
        LABEL_MAPPING = [
            ('project', Project),
            ('service', Service),
        ]
        routable = {}
        data = self.json()

        data.setdefault('commonLabels', {})
        data.setdefault('commonAnnotations', {})

        # Look through our labels and find the object from Promgen's DB
        # If we find an object in Promgen, add an annotation with a direct link
        for label, klass in LABEL_MAPPING:
            if label not in data['commonLabels']:
                logger.debug('Missing label %s', label)
                continue

            # Should only find a single value, but I think filter is a little
            # bit more forgiving than get in terms of throwing errors
            for obj in klass.objects.filter(name=data['commonLabels'][label]):
                logger.debug('Found %s %s', label, obj)
                routable[label] = obj
                data['commonAnnotations'][label] = resolve_domain(obj)

        return routable, data
Beispiel #3
0
    def expand(self, data):
        '''
        Look through our alert and expand any objects we find

        This is responsible for looking through our alerts and finding any
        supported labels (like Projects and Services) that we can expand into
        an annotation
        '''
        output = {}

        data.setdefault('commonLabels', {})
        data.setdefault('commonAnnotations', {})

        # Look through our labels and find the object from Promgen's DB
        # If we find an object in Promgen, add an annotation with a direct link
        for label, klass in self.MAPPING:
            if label not in data['commonLabels']:
                logger.debug('Missing label %s', label)
                continue

            # Should only find a single value, but I think filter is a little
            # bit more forgiving than get in terms of throwing errors
            for obj in klass.objects.filter(name=data['commonLabels'][label]):
                logger.debug('Found %s %s', label, obj)
                output[label] = obj
                data['commonAnnotations'][label] = resolve_domain(obj)
        return output
Beispiel #4
0
 def annotations(self):
     _annotations = {
         obj.name: obj.value
         for obj in self.ruleannotation_set.all()
     }
     # Skip when pk is not set, such as when test rendering a rule
     if self.pk and 'rule' not in _annotations:
         _annotations['rule'] = resolve_domain('rule-edit', pk=self.pk)
     return _annotations
Beispiel #5
0
    def post(self, request, pk):
        if pk == 0:
            rule = models.Rule()
            rule.set_object(request.POST['content_type'],
                            request.POST['object_id'])
        else:
            rule = get_object_or_404(models.Rule, id=pk)

        query = macro.rulemacro(rule, request.POST['query'])
        # Since our rules affect all servers we use Promgen's proxy-query to test our rule
        # against all the servers at once
        url = resolve_domain('proxy-query')

        logger.debug('Querying %s with %s', url, query)
        start = time.time()
        result = util.get(url, {'query': query}).json()
        duration = datetime.timedelta(seconds=(time.time() - start))

        context = {
            'status': result['status'],
            'duration': duration,
            'query': query
        }
        context['data'] = result.get('data', {})

        context['errors'] = {}

        metrics = context['data'].get('result', [])
        if metrics:
            context['collapse'] = len(metrics) > 5
            for row in metrics:
                if 'service' not in row['metric'] and \
                        'project' not in row['metric']:
                    context['errors'][
                        'routing'] = 'Some metrics are missing service and project labels so Promgen will be unable to route message'
                    context['status'] = 'warning'
        else:
            context['status'] = 'info'
            context['errors'][
                'no_results'] = 'No Results. May need to remove conditional check (> < ==) to verity'

        # Place this at the bottom to have a query error show up as danger
        if result['status'] != 'success':
            context['status'] = 'danger'
            context['errors']['Query'] = result['error']

        return JsonResponse({
            request.POST['target']:
            render_to_string('promgen/ajax_clause_check.html', context)
        })
Beispiel #6
0
    def send(self, data):
        '''
        Send out an alert

        This handles looping through the alerts from Alert Manager and checks
        to see if there are any notification senders configured for the
        combination of project/service and sender type.

        See tests/examples/alertmanager.json for an example payload
        '''
        sent = 0
        alerts = data.pop('alerts', [])
        for alert in alerts:
            alert.setdefault('annotations', {})
            output = {}

            # Look through our labels and find the object from Promgen's DB
            # If we find an object in Promgen, add an annotation with a direct link
            for label, klass in self.MAPPING:
                if label not in alert['labels']:
                    logger.debug('Missing label %s', label)
                    continue
                # Should only find a single value, but I think filter is a little
                # bit more forgiving than get in terms of throwing errors
                for obj in klass.objects.filter(name=alert['labels'][label]):
                    logger.debug('Found %s %s', label, obj)
                    output[label] = obj
                    alert['annotations'][label] = resolve_domain(obj)

            for label, obj in output.items():
                for sender in obj.notifiers.filter(sender=self.__module__):
                    logger.debug('Sending to %s', sender)
                    if self.__send(sender.value, alert, data):
                        sent += 1
        if sent == 0:
            logger.debug('No senders configured for project or service')
        return sent
Beispiel #7
0
 def to_representation(self, obj):
     return shortcuts.resolve_domain(obj.get_absolute_url())
Beispiel #8
0
 def get__html(self, obj):
     return shortcuts.resolve_domain('shard-detail', obj.id)
Beispiel #9
0
 def get__shard(self, obj):
     return shortcuts.resolve_domain('api:shard-detail', obj.service.shard.name)
Beispiel #10
0
 def get__service(self, obj):
     return shortcuts.resolve_domain('api:service-detail', obj.service.name)
Beispiel #11
0
 def get__projects(self, obj):
     return shortcuts.resolve_domain('api:service-projects', obj.name)
Beispiel #12
0
 def get__services(self, obj):
     return shortcuts.resolve_domain('api:shard-services', obj.name)