kiloeyes/kiloeyes/v2/elasticsearch/alarms.py

212 lines
8.5 KiB
Python
Executable File

# Copyright 2015 Carnegie Mellon University
##
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import ast
import falcon
from oslo_config import cfg
from stevedore import driver
from kiloeyes.common import es_conn
from kiloeyes.common import namespace
from kiloeyes.common import resource_api
from oslo_log import log
try:
import ujson as json
except ImportError:
import json
alarms_opts = [
cfg.StrOpt('doc_type', default='alarms',
help='The doc_type that alarm definitions will be saved to.'),
cfg.StrOpt('index_strategy', default='timed',
help='The index strategy used to create index name.'),
cfg.StrOpt('index_prefix', default='data_',
help='The index prefix where metrics were saved to.'),
cfg.IntOpt('size', default=10000,
help=('The query result limit. Any result set more than '
'the limit will be discarded.')),
]
cfg.CONF.register_opts(alarms_opts, group='alarms')
LOG = log.getLogger(__name__)
class AlarmDispatcher(object):
def __init__(self, global_conf):
LOG.debug('Initializing Alarm V2API!')
super(AlarmDispatcher, self).__init__()
self.doc_type = cfg.CONF.alarms.doc_type
self.index_prefix = cfg.CONF.alarms.index_prefix
self.size = cfg.CONF.alarms.size
# load index strategy
if cfg.CONF.alarms.index_strategy:
self.index_strategy = driver.DriverManager(
namespace.STRATEGY_NS,
cfg.CONF.alarms.index_strategy,
invoke_on_load=True,
invoke_kwds={}).driver
LOG.debug(self.index_strategy)
else:
self.index_strategy = None
self._es_conn = es_conn.ESConnection(
self.doc_type, self.index_strategy, self.index_prefix)
def _get_alarms_response(self, res, ele_name='hits'):
if res and res.status_code == 200:
obj = res.json()
if obj:
return obj.get(ele_name)
return None
else:
return None
@resource_api.Restify('/v2.0/alarms', method='get')
def do_get_alarms(self, req, res):
LOG.debug('The alarms GET request is received!')
# Extract the query string frm the request
query_string = req.query_string
LOG.debug('Request Query String: %s' % query_string)
# Transform the query string with proper search format
# params = self._get_alarms_helper(query_string)
# LOG.debug('Query Data: %s' % params)
params = ('{"aggs": {"latest_state": {'
'"terms": {"field": "alarm_definition.name", "size": 0},'
'"aggs": {"top_state_hits": {"top_hits": {"sort": ['
'{"updated_timestamp": {"order": "desc", '
'"ignore_unmapped": true}}],'
'"_source": {"include": ['
'"state", "created_timestamp","updated_timestamp",'
'"metrics","sub_alarms","state_updated_timestamp",'
'"id", "alarm_definition"]},"size" : 1}}}}}}')
LOG.debug("params= %s" % params)
es_res = self._es_conn.get_messages(json.loads(params),
q_string='search_type=count')
res.status = getattr(falcon, 'HTTP_%s' % es_res.status_code)
LOG.debug('Query to ElasticSearch returned Status: %s' %
es_res.status_code)
es_res = self._get_alarms_response(es_res, ele_name='aggregations')
LOG.debug('Query to ElasticSearch returned: %s' % es_res)
res.body = ''
result_elements = []
try:
if es_res and es_res.get("latest_state"):
res_data = es_res["latest_state"]["buckets"]
res.body = '['
for bucket in res_data:
alarm = bucket['top_state_hits']['hits']['hits'][0]
if alarm and alarm['_source']:
alarm = alarm['_source']
result_elements.append({
"id": alarm["id"],
"links": [{"rel": "self",
"href": req.uri}],
"alarm_definition": alarm["alarm_definition"],
"metrics": alarm["metrics"],
"state": alarm["state"],
"sub_alarms": alarm["sub_alarms"],
"state_updated_timestamp":
alarm["state_updated_timestamp"],
"updated_timestamp": alarm["updated_timestamp"],
"created_timestamp": alarm["created_timestamp"]})
res.body = json.dumps({
"links": [{"rel": "self", "href": req.uri}],
"elements": result_elements
})
else:
res.body = ''
res.content_type = 'application/json;charset=utf-8'
except Exception:
res.status = getattr(falcon, 'HTTP_400')
LOG.exception('Error occurred while handling Alarms Get Request.')
@resource_api.Restify('/v2.0/alarms/{id}', method='get')
def do_get_alarms_by_id(self, req, res, id):
LOG.debug('The alarms by id GET request is received!')
LOG.debug(id)
es_res = self._es_conn.get_message_by_id(id)
res.status = getattr(falcon, 'HTTP_%s' % es_res.status_code)
LOG.debug('Query to ElasticSearch returned Status: %s' %
es_res.status_code)
es_res = self._get_alarms_response(es_res)
LOG.debug('Query to ElasticSearch returned: %s' % es_res)
res.body = ''
try:
if es_res["hits"]:
res_data = es_res["hits"][0]
if res_data:
res.body = json.dumps({
"id": id,
"links": [{"rel": "self",
"href": req.uri}],
"metrics": res_data["_source"]["metrics"],
"state": res_data["_source"]["state"],
"sub_alarms": res_data["_source"]["sub_alarms"],
"state_updated_timestamp":
res_data["_source"]["state_updated_timestamp"],
"updated_timestamp":
res_data["_source"]["updated_timestamp"],
"created_timestamp":
res_data["_source"]["created_timestamp"]})
res.content_type = 'application/json;charset=utf-8'
else:
res.body = ''
except Exception:
res.status = getattr(falcon, 'HTTP_400')
LOG.exception('Error occurred while handling Alarm '
'Get By ID Request.')
@resource_api.Restify('/v2.0/alarms/{id}', method='put')
def do_put_alarms(self, req, res, id):
LOG.debug("Put the alarm with id: %s" % id)
try:
msg = req.stream.read()
put_msg = ast.literal_eval(msg)
es_res = self._es_conn.put_messages(json.dumps(put_msg), id)
LOG.debug('Query to ElasticSearch returned Status: %s' %
es_res)
res.status = getattr(falcon, 'HTTP_%s' % es_res)
except Exception:
res.status = getattr(falcon, 'HTTP_400')
LOG.exception('Error occurred while handling Alarm Put Request.')
@resource_api.Restify('/v2.0/alarms/{id}', method='delete')
def do_delete_alarms(self, req, res, id):
LOG.debug("Delete the alarm with id: %s" % id)
try:
es_res = self._es_conn.del_messages(id)
LOG.debug('Query to ElasticSearch returned Status: %s' %
es_res)
res.status = getattr(falcon, 'HTTP_%s' % es_res)
except Exception:
res.status = getattr(falcon, 'HTTP_400')
LOG.exception('Error occurred while handling '
'Alarm Delete Request.')