Пример #1
0
    def test_macro(self, mock_signals):
        self.project = models.Project.objects.create(name='Project 1',
                                                     service=self.service)
        clause = 'up{%s}' % macro.EXCLUSION_MACRO

        rules = {
            'common': {
                'assert': 'up{service!~"Service 1"}'
            },
            'service': {
                'assert': 'up{service="Service 1",project!~"Project 1"}'
            },
            'project': {
                'assert': 'up{service="Service 1",project="Project 1",}'
            },
        }

        common_rule = models.Rule.create(name='Common',
                                         clause=clause,
                                         duration='1s',
                                         obj=self.service.default())
        rules['common']['model'] = models.Rule.objects.get(pk=common_rule.pk)
        service_rule = common_rule.copy_to('service', self.service.id)
        rules['service']['model'] = models.Rule.objects.get(pk=service_rule.pk)
        project_rule = service_rule.copy_to('project', self.project.id)
        rules['project']['model'] = models.Rule.objects.get(pk=project_rule.pk)

        for k, r in rules.items():
            self.assertEquals(macro.rulemacro(r['model'].clause, r['model']),
                              r['assert'], 'Expansion wrong for %s' % k)
Пример #2
0
 def to_representation(self, obj):
     return {
         "alert": obj.name,
         "expr": macro.rulemacro(obj),
         "for": obj.duration,
         "labels": obj.labels,
         "annotations": obj.annotations,
     }
Пример #3
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)
        })
Пример #4
0
def render_rules(rules=None, version=None):
    '''
    Render rules in a format that Prometheus understands

    :param rules: List of rules
    :type rules: list(Rule)
    :param int version: Prometheus rule format (1 or 2)
    :return: Returns rules in yaml or Prometheus v1 format
    :rtype: bytes

    This function can render in either v1 or v2 format
    We call prefetch_related_objects within this function to populate the
    other related objects that are mostly used for the sub lookups.
    '''
    if rules is None:
        rules = models.Rule.objects.filter(enabled=True)
    if version is None:
        version = settings.PROMGEN['prometheus'].get('version', 1)

    prefetch_related_objects(
        rules,
        'content_object',
        'content_type',
        'overrides__content_object',
        'overrides__content_type',
        'ruleannotation_set',
        'rulelabel_set',
    )

    # V1 format is a custom format which we render through django templates
    # See promgen/tests/examples/import.rule
    if version == 1:
        return render_to_string('promgen/prometheus.rule', {'rules': rules}).encode('utf-8')

    # V2 format is a yaml dictionary which we build and then render
    # See promgen/tests/examples/import.rule.yml
    rule_list = collections.defaultdict(list)
    for r in rules:
        rule_list[str(r.content_object)].append({
            'alert': r.name,
            'expr': macro.rulemacro(r.clause, r),
            'for': r.duration,
            'labels': r.labels,
            'annotations': r.annotations,
        })

    return yaml.safe_dump({'groups': [
        {'name': name, 'rules': rule_list[name]} for name in rule_list
    ]}, default_flow_style=False, allow_unicode=True, encoding='utf-8')