mirror of
https://github.com/alerta/alerta.git
synced 2025-01-26 02:08:31 +00:00
208 lines
8.5 KiB
Python
208 lines
8.5 KiB
Python
import sys
|
|
import datetime
|
|
import pytz
|
|
|
|
import pymongo
|
|
|
|
from alerta.common import log as logging
|
|
from alerta.common import config
|
|
from alerta.alert import Alert
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
CONF = config.CONF
|
|
|
|
|
|
class Mongo(object):
|
|
|
|
def __init__(self):
|
|
|
|
# Connect to MongoDB
|
|
try:
|
|
self.conn = pymongo.MongoClient(CONF.mongo_host, CONF.mongo_port)
|
|
self.db = self.conn.monitoring # TODO(nsatterl): make 'monitoring' a SYSTEM DEFAULT
|
|
except Exception, e:
|
|
LOG.error('MongoDB Client error : %s', e)
|
|
sys.exit(1)
|
|
|
|
if self.conn.alive():
|
|
LOG.info('Connected to MongoDB server %s:%s', CONF.mongo_host, CONF.mongo_port)
|
|
LOG.debug('MongoDB %s, databases available: %s', self.conn.server_info()['version'], ', '.join(self.conn.database_names()))
|
|
|
|
self.db.alerts.create_index([('environment', pymongo.DESCENDING), ('resource', pymongo.DESCENDING),
|
|
('event', pymongo.DESCENDING)]) # TODO(nsatterl): verify perf of this index
|
|
|
|
def is_duplicate(self, environment, resource, event, severity=None):
|
|
|
|
if severity:
|
|
found = self.db.alerts.find_one({"environment": environment, "resource": resource, "event": event, "severity": severity})
|
|
else:
|
|
found = self.db.alerts.find_one({"environment": environment, "resource": resource, "event": event})
|
|
|
|
return found is not None
|
|
|
|
def is_correlated(self, environment, resource, event):
|
|
|
|
found = self.db.alerts.find_one({"environment": environment, "resource": resource,
|
|
'$or': [{"event": event}, {"correlatedEvents": event}]})
|
|
return found is not None
|
|
|
|
def get_severity(self, environment, resource, event):
|
|
|
|
return self.db.alerts.find_one({"environment": environment, "resource": resource,
|
|
'$or': [{"event": event}, {"correlatedEvents": event}]},
|
|
{"severity": 1, "_id": 0})['severity']
|
|
|
|
def get_alert(self, environment, resource, event, severity=None):
|
|
|
|
if severity:
|
|
response = self.db.alerts.find_one({"environment": environment, "resource": resource, "event": event, "severity": severity})
|
|
else:
|
|
response = self.db.alerts.find_one({"environment": environment, "resource": resource, "event": event})
|
|
|
|
if not response:
|
|
LOG.warning('Alert not found with environment, resource, event, severity = %s %s %s %s', environment, resource, event, severity)
|
|
return
|
|
|
|
return Alert(
|
|
alertid=response['_id'],
|
|
resource=response['resource'],
|
|
event=response['event'],
|
|
correlate=response['correlatedEvents'],
|
|
group=response['group'],
|
|
value=response['value'],
|
|
severity=response['severity'],
|
|
environment=response['environment'],
|
|
service=response['service'],
|
|
text=response['text'],
|
|
event_type=response['type'],
|
|
tags=response['tags'],
|
|
origin=response['origin'],
|
|
threshold_info=response['thresholdInfo'],
|
|
summary=response['summary'],
|
|
timeout=response['timeout'],
|
|
create_time=response['createTime'],
|
|
receive_time=response['receiveTime'],
|
|
last_receive_time=response['lastReceiveTime'],
|
|
trend_indication=response['trendIndication'],
|
|
)
|
|
|
|
def save_alert(self, alert):
|
|
|
|
body = alert.get_body()
|
|
body['history'] = [{
|
|
"id": body['id'],
|
|
"event": body['event'],
|
|
"severity": body['severity'],
|
|
"value": body['value'],
|
|
"text": body['text'],
|
|
"createTime": body['createTime'],
|
|
"receiveTime": body['receiveTime'],
|
|
}]
|
|
body['_id'] = body['id']
|
|
del body['id']
|
|
|
|
return self.db.alerts.insert(body, safe=True)
|
|
|
|
def modify_alert(self, environment, resource, event, update):
|
|
|
|
# FIXME - no native find_and_modify method in this version of pymongo
|
|
no_obj_error = "No matching object found"
|
|
response = self.db.command("findAndModify", 'alerts',
|
|
allowable_errors=[no_obj_error],
|
|
query={"environment": environment, "resource": resource,
|
|
'$or': [{"event": event}, {"correlatedEvents": event}]},
|
|
update={'$set': update,
|
|
'$push': {"history": {
|
|
"createTime": update['createTime'],
|
|
"receiveTime": update['receiveTime'],
|
|
"severity": update['severity'],
|
|
"event": update['event'],
|
|
"value": update['value'],
|
|
"text": update['text'],
|
|
"id": update['lastReceiveId']
|
|
}
|
|
}
|
|
},
|
|
new=True,
|
|
fields={"history": 0})['value']
|
|
|
|
return Alert(
|
|
alertid=response['_id'],
|
|
resource=response['resource'],
|
|
event=response['event'],
|
|
correlate=response['correlatedEvents'],
|
|
group=response['group'],
|
|
value=response['value'],
|
|
severity=response['severity'],
|
|
environment=response['environment'],
|
|
service=response['service'],
|
|
text=response['text'],
|
|
event_type=response['type'],
|
|
tags=response['tags'],
|
|
origin=response['origin'],
|
|
threshold_info=response['thresholdInfo'],
|
|
summary=response['summary'],
|
|
timeout=response['timeout'],
|
|
create_time=response['createTime'],
|
|
receive_time=response['receiveTime'],
|
|
last_receive_time=response['lastReceiveTime'],
|
|
trend_indication=response['trendIndication'],
|
|
)
|
|
|
|
def duplicate_alert(self, environment, resource, event, **kwargs):
|
|
|
|
# FIXME - no native find_and_modify method in this version of pymongo
|
|
no_obj_error = "No matching object found"
|
|
return self.db.command("findAndModify", 'alerts',
|
|
allowable_errors=[no_obj_error],
|
|
query={"environment": environment, "resource": resource, "event": event},
|
|
update={'$set': kwargs,
|
|
'$inc': {"duplicateCount": 1}},
|
|
new=True,
|
|
fields={"history": 0})['value']
|
|
|
|
def update_status(self, environment, resource, event, status):
|
|
|
|
update_time = datetime.datetime.utcnow()
|
|
update_time = update_time.replace(tzinfo=pytz.utc)
|
|
|
|
LOG.info('Alert status for %s %s %s alert set to %s', environment, resource, event, status)
|
|
|
|
query = {"environment": environment, "resource": resource,
|
|
'$or': [{"event": event}, {"correlatedEvents": event}]}
|
|
update = {'$set': {"status": status}, '$push': {"history": {"status": status, "updateTime": update_time}}}
|
|
|
|
LOG.debug('query = %s, update = %s', query, update)
|
|
|
|
try:
|
|
self.db.alerts.update(query, update)
|
|
except pymongo.errors.OperationFailure, e:
|
|
LOG.error('MongoDB error: %s', e)
|
|
|
|
def update_hb(self, origin, version, create_time, receive_time):
|
|
|
|
LOG.info('Update heartbeat for %s %s', origin, version)
|
|
|
|
query = {"origin": origin}
|
|
update = {"origin": origin, "version": version, "createTime": create_time, "receiveTime": receive_time}
|
|
|
|
try:
|
|
self.db.heartbeats.update(query, update, True)
|
|
except pymongo.errors.OperationFailure, e:
|
|
LOG.error('MongoDB error: %s', e)
|
|
|
|
# TODO(nsatterl): is this needed?
|
|
# def save_heartbeat(self, heartbeat):
|
|
#
|
|
# body = heartbeat.get_body()
|
|
# body['_id'] = body['id']
|
|
# del body['id']
|
|
#
|
|
# return self.db.heartbeats.insert(body, safe=True)
|
|
|
|
def disconnect(self):
|
|
|
|
if self.conn.alive():
|
|
self.conn.disconnect()
|
|
|
|
LOG.info('Mongo disconnected.')
|