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
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
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
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
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) })
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
def to_representation(self, obj): return shortcuts.resolve_domain(obj.get_absolute_url())
def get__html(self, obj): return shortcuts.resolve_domain('shard-detail', obj.id)
def get__shard(self, obj): return shortcuts.resolve_domain('api:shard-detail', obj.service.shard.name)
def get__service(self, obj): return shortcuts.resolve_domain('api:service-detail', obj.service.name)
def get__projects(self, obj): return shortcuts.resolve_domain('api:service-projects', obj.name)
def get__services(self, obj): return shortcuts.resolve_domain('api:shard-services', obj.name)