def incoming(self, path, query_string, payload): notification = json.loads(payload) if notification['Type'] == 'SubscriptionConfirmation': return Alert( resource=notification['TopicArn'], event=notification['Type'], environment='Production', severity='informational', service=['Unknown'], group='AWS/CloudWatch', text='{} <a href="{}" target="_blank">SubscribeURL</a>'.format( notification['Message'], notification['SubscribeURL']), origin=notification['TopicArn'], event_type='cloudwatchAlarm', create_time=datetime.strptime(notification['Timestamp'], '%Y-%m-%dT%H:%M:%S.%fZ'), raw_data=notification ) elif notification['Type'] == 'Notification': alarm = json.loads(notification['Message']) if 'Trigger' not in alarm: raise ValueError('SNS message is not a Cloudwatch notification') resource = notification['TopicArn'].split(':')[-1] if alarm['Trigger']['Dimensions']: resource = '{}:{}'.format(alarm['Trigger']['Dimensions'][0]['name'], alarm['Trigger']['Dimensions'][0]['value']) return Alert( resource=resource, event=alarm['AlarmName'], environment='Production', severity=self.cw_state_to_severity(alarm['NewStateValue']), service=[alarm['AWSAccountId']], group=alarm['Trigger']['Namespace'], value=alarm['NewStateValue'], text=alarm['AlarmDescription'], tags=[alarm['Region']], attributes={ 'incidentKey': alarm['AlarmName'], 'thresholdInfo': alarm['Trigger'] }, origin=notification['TopicArn'], event_type='cloudwatchAlarm', create_time=datetime.strptime(notification['Timestamp'], '%Y-%m-%dT%H:%M:%S.%fZ'), raw_data=alarm ) else: raise ValueError('No SNS notification in payload')
def parse_notification(notification): notification = json.loads(notification) if notification['Type'] == 'SubscriptionConfirmation': return Alert( resource=notification['TopicArn'], event=notification['Type'], environment='Production', severity='informational', service=['Unknown'], group='AWS/CloudWatch', text='%s <a href="%s" target="_blank">SubscribeURL</a>' % (notification['Message'], notification['SubscribeURL']), origin=notification['TopicArn'], event_type='cloudwatchAlarm', create_time=datetime.strptime(notification['Timestamp'], '%Y-%m-%dT%H:%M:%S.%fZ'), raw_data=notification, ) elif notification['Type'] == 'Notification': alarm = json.loads(notification['Message']) if 'Trigger' not in alarm: raise ValueError("SNS message is not a Cloudwatch notification") return Alert(resource='%s:%s' % (alarm['Trigger']['Dimensions'][0]['name'], alarm['Trigger']['Dimensions'][0]['value']), event=alarm['AlarmName'], environment='Production', severity=cw_state_to_severity(alarm['NewStateValue']), service=[alarm['AWSAccountId']], group=alarm['Trigger']['Namespace'], value=alarm['NewStateValue'], text=alarm['AlarmDescription'], tags=[alarm['Region']], attributes={ 'incidentKey': alarm['AlarmName'], 'thresholdInfo': alarm['Trigger'] }, origin=notification['TopicArn'], event_type='cloudwatchAlarm', create_time=datetime.strptime(notification['Timestamp'], '%Y-%m-%dT%H:%M:%S.%fZ'), raw_data=alarm)
def incoming(self, path, query_string, payload): if payload['fixed']: severity = 'ok' else: severity = 'critical' return Alert( resource=payload['item_name'], event=payload['alert_type'], environment=current_app.config['DEFAULT_ENVIRONMENT'], severity=severity, service=[payload['item_type']], group=payload['alert_section'], value=payload['configured_trigger_value'], text= f"Alert created for {payload['item_type']}:{payload['item_name']}", tags=['cloud'] if payload['item_cloud'] else [], attributes={ 'alertId': payload['alert_id'], 'itemId': payload['item_id'] }, origin='ServerDensity', event_type='serverDensityAlert', raw_data=payload)
def test_get_body(self): from flask import g with self.app.test_request_context('/'): g.login = '******' alert_in = Alert(resource='test1', event='event1', environment='Development', service=['svc1', 'svc2']) self.assertTrue(isinstance(alert_in.create_time, datetime)) self.assertEqual(alert_in.last_receive_time, None) self.assertTrue(isinstance(alert_in.receive_time, datetime)) self.assertEqual(alert_in.update_time, None) body = alert_in.get_body() self.assertEqual(type(body['createTime']), str) self.assertEqual(body['lastReceiveTime'], None) self.assertEqual(type(body['receiveTime']), str) self.assertEqual(body['updateTime'], None) alert_out = process_alert(alert_in) self.assertTrue(isinstance(alert_out.create_time, datetime)) self.assertTrue(isinstance(alert_out.last_receive_time, datetime)) self.assertTrue(isinstance(alert_out.receive_time, datetime)) self.assertTrue(isinstance(alert_out.update_time, datetime)) body = alert_out.get_body() self.assertEqual(type(body['createTime']), str) self.assertEqual(type(body['lastReceiveTime']), str) self.assertEqual(type(body['receiveTime']), str) self.assertEqual(type(body['updateTime']), str)
def incoming(self, query_string, payload): # Default parameters environment = 'Production' group = 'OpenDistro' text = '' tags = [] attributes = {} origin = '' service = ['OpenDistro Action'] value = '' return Alert(resource=payload['resource'], event=payload['event'], environment=payload.get('environment', environment), severity=SEVERITY_MAP[payload.get( 'severity', DEFAULT_SEVERITY_LEVEL)], service=payload.get('service', service), group=payload.get('group', group), value=payload.get('value', value), text=payload.get('text', text), tags=payload.get('tags', tags), attributes=payload.get('attributes', attributes), origin=payload.get('origin', origin), raw_data=json.dumps(payload, indent=4))
def incoming(self, query_string, payload): # Default parameters environment = 'Production' severity ='error' group ='Cron' text = '' tags = [] status = 'DOWN' event = 'health' #tags=['{}'.format(v) for k, v in payload['event']['tags']], #attributes={'tags': ['{}'.format(k, v) in query_string.items() if k.startswith("TAG")]}, return Alert( service=['healthchecks'], resource=query_string.get('name',payload.get('name', environment)), text=query_string.get('text',payload.get('text', text)), event=query_string.get('event',payload.get('event', event)), group=query_string.get('group',payload.get('group', group)), severity=query_string.get('severity',payload.get('severity', severity)), value=query_string.get('status',payload.get('status', status)), environment=query_string.get('environment',payload.get('environment', environment)), tags=[], attributes={}, origin='Healthchecks/{}'.format(query_string.get('code',payload.get('code', 'Unknown'))), raw_data=json.dumps(payload, indent=4) )
def incoming(self, query_string, payload): # Default parameters environment = 'Production' severity ='security' group ='Fail2Ban' text = '' tags = [] attributes = {} origin = '' return Alert( resource=payload['resource'], event=payload['event'], environment=payload.get('environment', environment), severity=payload.get('severity', severity), service=['fail2ban'], group=payload.get('group', group), value='BAN', text=payload.get('message', text), tags=payload.get('tags', tags), attributes=payload.get('attributes', attributes), origin=payload.get('hostname', origin), raw_data=json.dumps(payload, indent=4) )
def incoming(self, query_string, payload): return Alert( resource=query_string['foo'], event=payload['field1'], environment='Production', service=['Foo'] )
def parse_grafana(alert, match): if alert['state'] == 'alerting': severity = 'major' elif alert['state'] == 'ok': severity = 'normal' else: severity = 'indeterminate' attributes = match.get('tags', None) or dict() attributes['ruleId'] = str(alert['ruleId']) if 'ruleUrl' in alert: attributes[ 'ruleUrl'] = '<a href="%s" target="_blank">Rule</a>' % alert[ 'ruleUrl'] if 'imageUrl' in alert: attributes[ 'imageUrl'] = '<a href="%s" target="_blank">Image</a>' % alert[ 'imageUrl'] return Alert(resource=match['metric'], event=alert['ruleName'], environment='Production', severity=severity, service=['Grafana'], group='Performance', value='%s' % match['value'], text=alert.get('message', None) or alert.get('title', alert['state']), tags=list(), attributes=attributes, origin='Grafana', event_type='performanceAlert', timeout=300, raw_data=alert)
def incoming(self, query_string, payload): return Alert( resource=query_string.get('foo') or 'nofoo', event=payload, environment='Production', service=['Foo'] )
def incoming(self, query_string, payload): return Alert( resource=query_string['foo'], event='Say {} to {}'.format(payload['say'], payload['to']), environment='Production', service=['Foo'] )
def incoming(self, query_string, payload): alert_severity = os.environ.get('STATUSCAKE_DEFAULT_ALERT_SEVERITY', 'major') # If the statuscake username and apikey are provided # We can validate that the webhook call is valid statuscake_username = os.environ.get('STATUSCAKE_USERNAME') statuscake_apikey = os.environ.get('STATUSCAKE_APIKEY') if statuscake_username and statuscake_apikey: decoded_token = statuscake_username + statuscake_apikey statuscake_token = hashlib.md5(decoded_token.encode()).hexdigest() if statuscake_token != payload['Token']: raise RejectException("Provided Token couldn't be verified") if payload['Status'] == 'UP': severity = 'normal' else: severity = alert_severity return Alert(resource=payload['Name'], event='AppDown', environment='Production', severity=severity, service=['StatusCake'], group='Application', value=payload['StatusCode'], text="%s is down" % payload['URL'], tags=payload['Tags'].split(','), origin='statuscake', raw_data=str(payload))
def incoming(self, query_string, payload): # return Alert( # resource=payload['culprit'], # event=payload['event']['event_id'], # environment=environment, # severity=severity, # service=[payload['project']], # group='Application', # value=payload['level'], # text='{} {}'.format(payload['message'], payload['url']), # tags=['{}={}'.format(k, v) for k, v in payload['event']['tags']], # attributes={'modules': ['{}=={}'.format(k, v) for k, v in payload['event']['modules'].items()]}, # origin='sentry.io', # raw_data=str(payload) # ) return Alert(resource="UKGR", event="dynatrace_alert", environment="Production", severity="critical", service=["dynatrace"], group="Application", value="sample", text="something is missing", tags=list(), origin="Dynatrace", raw_data=json.dumps(payload))
def parse_serverdensity(alert): if alert['fixed']: severity = 'ok' else: severity = 'critical' return Alert( resource=alert['item_name'], event=alert['alert_type'], environment='Production', severity=severity, service=[alert['item_type']], group=alert['alert_section'], value=alert['configured_trigger_value'], text='Alert created for {}:{}'.format(alert['item_type'], alert['item_name']), tags=['cloud'] if alert['item_cloud'] else [], attributes={ 'alertId': alert['alert_id'], 'itemId': alert['item_id'] }, origin='ServerDensity', event_type='serverDensityAlert', raw_data=alert )
def parse_pingdom(check: JSON) -> Alert: if check['importance_level'] == 'HIGH': severity = 'critical' else: severity = 'warning' if check['current_state'] == 'UP': severity = 'normal' return Alert(resource=check['check_name'], event=check['current_state'], correlate=['UP', 'DOWN'], environment='Production', severity=severity, service=[check['check_type']], group='Network', value=check['description'], text='{}: {}'.format(check['importance_level'], check['long_description']), tags=check['tags'], attributes={'checkId': check['check_id']}, origin='Pingdom', event_type='availabilityAlert', raw_data=check)
def incoming(self, query_string, payload): # For Sentry v9 # Defaults to value before Sentry v9 if 'request' in payload.get('event'): key = 'request' else: key = 'sentry.interfaces.Http' if payload.get('event')[key]['env']['ENV'] == 'prod': environment = 'Production' else: environment = 'Development' if payload['level'] == 'error': severity = 'critical' else: severity = 'ok' return Alert( resource=payload['culprit'], event=payload['event']['event_id'], environment=environment, severity=severity, service=[payload['project']], group='Application', value=payload['level'], text='{} {}'.format(payload['message'], payload['url']), tags=['{}={}'.format(k, v) for k, v in payload['event']['tags']], attributes={'modules': ['{}=={}'.format(k, v) for k, v in payload['event']['modules'].items()]}, origin='sentry.io', raw_data=str(payload) )
def incoming(self, query_string, payload): if payload['importance_level'] == 'HIGH': severity = 'critical' else: severity = 'warning' if payload['current_state'] == 'UP': severity = alarm_model.DEFAULT_NORMAL_SEVERITY return Alert(resource=payload['check_name'], event=payload['current_state'], correlate=['UP', 'DOWN'], environment='Production', severity=severity, service=[payload['check_type']], group='Network', value=payload['description'], text='{}: {}'.format(payload['importance_level'], payload['long_description']), tags=payload['tags'], attributes={'checkId': payload['check_id']}, origin='Pingdom', event_type='availabilityAlert', raw_data=payload)
def incoming(self, query_string, payload): #Change Kentik alert states into what Alerta Understands if payload['AlarmState'] == 'ALARM': severity = 'critical' else: severity = 'normal' #Grab only necessary values and make them look nice src_ip = payload['AlertKey'][0]['DimensionValue'] event = "Outgoing DDoS from: " + src_ip metrics = payload['AlertValue']['Value'] value = "Packets/s: " + str(metrics) #Send Alert return Alert(resource=payload['AlertPolicyName'], event=event, environment='Production', severity=severity, service=['Kentik'], origin='Kentik', value=value, text=payload['EventType'])
def incoming(self, path, query_string, payload): incident = payload['incident'] state = incident['state'] # 'documentation' is an optional field that you can use to customize # your alert sending a json if 'documentation' in incident: try: content = json.loads(incident['documentation']['content']) incident.update(content) except Exception: current_app.logger.warning( "Invalid documentation content: '{}'".format( incident['documentation'])) status = None severity = incident.get('severity', 'critical') if state == 'open': status = None elif state == 'acknowledged': status = 'ack' elif state == 'closed': severity = 'ok' else: severity = 'indeterminate' service = [] if incident['policy_name']: service.append(incident['policy_name']) return Alert( resource=incident['resource_name'], event=incident['condition_name'], environment=incident.get('environment', 'Production'), severity=severity, status=status, service=service, group=incident.get('group', 'Cloud'), text=incident['summary'], attributes={ 'incidentId': incident['incident_id'], 'resourceId': incident['resource_id'], 'moreInfo': '<a href="%s" target="_blank">Stackdriver Console</a>' % incident['url'], 'startedAt': incident['started_at'], 'endedAt': incident['ended_at'] }, customer=incident.get('customer'), origin=incident.get('origin', 'Stackdriver'), event_type='stackdriverAlert', raw_data=payload)
def incoming(self, query_string, payload): # For Sentry v9 # Defaults to value before Sentry v9 if 'request' in payload.get('event'): key = 'request' else: key = 'sentry.interfaces.Http' if 'env' in payload.get('event')[key]: if payload.get('event')[key]['env']['ENV'] == 'prod': environment = 'Production' else: environment = 'Development' else: environment = 'Production' if 'modules' in payload['event']: modules = [ '{}=={}'.format(k, v) for k, v in payload['event']['modules'].items() ] else: modules = [] if payload['level'] == 'error': severity = 'critical' else: severity = 'ok' if payload['message'] == '': if 'title' in payload['event']: message = payload['event']['title'] else: message = payload['url'] else: message = payload['message'] return Alert( resource=payload['culprit'], event=payload['id'], environment=environment, severity=severity, service=[payload['project']], group='Application', value=payload['level'], text=message, tags=['{}={}'.format(k, v) for k, v in payload['event']['tags']], attributes={ 'modules': modules, 'eventId': payload['event']['event_id'], 'sentryLink': '<a href="%s" target="_blank">Sentry URL</a>' % payload['url'] }, origin='sentry.io', raw_data=str(payload))
def test_invalid(self): with self.app.test_request_context('/'): self.app.preprocess_request() with self.assertRaises(Exception) as e: process_alert(Alert(resource='foo', event='bar', environment='Development', service=['Svc'], severity='baz')) exc = e.exception self.assertEqual(str(exc)[:70], 'Severity (baz) is not one of security, critical, major, minor, warning')
def incoming(self, path, query_string, payload): return Alert(resource=query_string['foo'], event=payload['baz'], environment='Production', service=['Foo'], attributes={ 'path': path, 'qs': query_string, 'data': payload })
def parse_prometheus(alert, external_url): status = alert.get('status', 'firing') labels = copy(alert['labels']) annotations = copy(alert['annotations']) starts_at = parse_date(alert['startsAt']) if alert['endsAt'] == '0001-01-01T00:00:00Z': ends_at = None else: ends_at = parse_date(alert['endsAt']) if status == 'firing': severity = labels.pop('severity', 'warning') create_time = starts_at elif status == 'resolved': severity = 'normal' create_time = ends_at else: severity = 'unknown' create_time = ends_at or starts_at summary = annotations.pop('summary', None) description = annotations.pop('description', None) text = description or summary or '%s: %s on %s' % (labels['job'], labels['alertname'], labels['instance']) try: timeout = int(labels.pop('timeout', 0)) or None except ValueError: timeout = None if external_url: annotations['externalUrl'] = external_url if 'generatorURL' in alert: annotations['moreInfo'] = '<a href="%s" target="_blank">Prometheus Graph</a>' % alert['generatorURL'] return Alert( resource=labels.pop('exported_instance', None) or labels.pop('instance', 'n/a'), event=labels.pop('alertname'), environment=labels.pop('environment', 'Production'), severity=severity, correlate=labels.pop('correlate').split(',') if 'correlate' in labels else None, service=labels.pop('service', '').split(','), group=labels.pop('job', 'Prometheus'), value=labels.pop('value', None), text=text, attributes=annotations, origin='prometheus/' + labels.pop('monitor', '-'), event_type='prometheusAlert', create_time=create_time.astimezone(tz=pytz.UTC).replace(tzinfo=None), timeout=timeout, raw_data=alert, tags=["%s=%s" % t for t in labels.items()] # any labels left are used for tags )
def parse_stackdriver(notification: JSON) -> Alert: incident = notification['incident'] state = incident['state'] # 'documentation' is an optional field that you can use to customize # your alert sending a json if 'documentation' in incident: try: content = json.loads(incident['documentation']['content']) incident.update(content) except Exception as e: LOG.warning("Invalid documentation content: '{}'".format( incident['documentation'])) service = [] status = None create_time = None # type: ignore severity = incident.get('severity', 'critical') if incident['policy_name']: service.append(incident['policy_name']) if state == 'open': create_time = datetime.utcfromtimestamp(incident['started_at']) elif state == 'acknowledged': status = 'ack' elif state == 'closed': severity = 'ok' create_time = datetime.utcfromtimestamp(incident['ended_at']) else: severity = 'indeterminate' return Alert(resource=incident['resource_name'], event=incident['condition_name'], environment=incident.get('environment', 'Production'), severity=severity, status=status, service=service, group=incident.get('group', 'Cloud'), text=incident['summary'], attributes={ 'incidentId': incident['incident_id'], 'resourceId': incident['resource_id'], 'moreInfo': '<a href="%s" target="_blank">Stackdriver Console</a>' % incident['url'] }, customer=incident.get('customer'), origin=incident.get('origin', 'Stackdriver'), event_type='stackdriverAlert', create_time=create_time, raw_data=notification)
def incoming(self, path, query_string, payload): if 'version' not in payload: raise ValueError('New Relic Legacy Alerting is not supported') status = payload['current_state'].lower() if status == 'open': severity = payload['severity'].lower() elif status == 'acknowledged': severity = payload['severity'].lower() status = 'ack' elif status == 'closed': severity = 'ok' elif payload['severity'].lower() == 'info': severity = 'informational' status = 'open' else: severity = payload['severity'].lower() status = 'open' if severity not in SEVERITY_MAP: if severity.lower() == 'info': severity = 'informational' else: severity = 'unknown' attributes = dict() if 'incident_url' in payload and payload['incident_url'] is not None: attributes['incident_url'] = payload['incident_url'] if 'runbook_url' in payload and payload['runbook_url'] is not None: attributes['runbook_url'] = payload['runbook_url'] resource = payload['targets'][0]['name'] or UNKNOWN event = payload['condition_name'] or UNKNOWN return Alert( resource=resource, event=event, environment='Production', severity=severity, status=status, service=[payload['account_name']], group=payload['targets'][0]['type'], text=payload['details'], tags=[ '{}:{}'.format(key, value) for (key, value) in payload['targets'][0]['labels'].items() ], attributes=attributes, origin='New Relic/v%s' % payload['version'], event_type=payload['event_type'].lower(), raw_data=payload)
def parse_riemann(alert): return Alert(resource='%s-%s' % (alert['host'], alert['service']), event=alert.get('event', alert['service']), environment=alert.get('environment', 'Production'), severity=alert.get('state', 'unknown'), service=[alert['service']], group=alert.get('group', 'Performance'), text=alert.get('description', None), value=alert.get('metric', None), tags=alert.get('tags', None), origin='Riemann', raw_data=alert)
def test_invalid(self): with self.app.test_request_context('/'): self.app.preprocess_request() with self.assertRaises(Exception) as e: process_alert( Alert(resource='foo', event='bar', environment='Development', service=['Svc'], severity='baz')) exc = e.exception self.assertEqual(str(exc), '\'baz\' is not a valid severity')
def incoming(self, query_string, payload): return Alert(resource='{}-{}'.format(payload['host'], payload['service']), event=payload.get('event', payload['service']), environment=payload.get('environment', 'Production'), severity=payload.get('state', 'unknown'), service=[payload['service']], group=payload.get('group', 'Performance'), text=payload.get('description', None), value=payload.get('metric', None), tags=payload.get('tags', None), origin='Riemann', raw_data=payload)
def parse_graylog(alert): return Alert( resource=alert['stream']['title'], event="Alert", environment='Development', service=["test"], severity="critical", value="n/a", text=alert['check_result']['result_description'], attributes={'checkId': alert['check_result']['triggered_condition']['id']}, origin='Graylog', event_type='performanceAlert', raw_data=alert)
def incoming(self, path, query_string, payload): if payload['criticality'] == 'ALERT_CRITICALITY_LEVEL_WARNING': severity = 'critical' else: severity = 'normal' return Alert(id=payload['alertId'], resource=payload['resourceName'], event=payload['subType'], environment='Production', service=[payload['resourceKind']], severity=severity, group=payload['resourceKind'], type=payload['type'], text=payload['info'])