Move event database driver out of engine

This patch moves the event module out of the engine in preparation for a
re-org of the event logging facility.

Change-Id: Ic8fbf1af13a06b400215339d340c6343743f93bf
partial-blueprint: generic-event
This commit is contained in:
tengqm 2016-11-16 00:15:55 -05:00
parent 38ec3ea2b4
commit b47d9b6ca2
5 changed files with 130 additions and 116 deletions

View File

@ -11,106 +11,20 @@
# under the License.
from oslo_log import log as logging
from oslo_utils import reflection
from oslo_utils import timeutils
from senlin.common.i18n import _LC, _LE, _LW, _LI
from senlin.objects import event as eo
from senlin.events import database as DB
LOG = logging.getLogger(__name__)
class Event(object):
'''Class capturing an interesting happening in Senlin.'''
def __init__(self, timestamp, level, entity=None, **kwargs):
self.timestamp = timestamp
self.level = level
self.id = kwargs.get('id', None)
self.user = kwargs.get('user', None)
self.project = kwargs.get('project', None)
self.action = kwargs.get('action', None)
self.status = kwargs.get('status', None)
self.status_reason = kwargs.get('status_reason', None)
# we deal with deserialization first
self.oid = kwargs.get('oid', None)
self.otype = kwargs.get('otype', None)
self.oname = kwargs.get('oname', None)
self.cluster_id = kwargs.get('cluster_id', None)
self.metadata = kwargs.get('metadata', {})
# entity not None implies an initial creation of event object,
# not a deserialization, so we try make an inference here
if entity is not None:
self._infer_entity_data(entity)
def _infer_entity_data(self, entity):
if self.status is None:
self.status = entity.status
if self.status_reason is None:
self.status_reason = entity.status_reason
e_type = reflection.get_class_name(entity, fully_qualified=False)
e_type = e_type.upper()
if e_type == 'CLUSTER':
self.oid = entity.id
self.cluster_id = entity.id
self.oname = entity.name
self.otype = 'CLUSTER'
elif e_type == 'NODE':
self.oid = entity.id
self.cluster_id = entity.cluster_id
self.oname = entity.name
self.otype = 'NODE'
elif e_type == 'CLUSTERACTION':
self.oid = entity.target
self.cluster_id = entity.target
self.oname = entity.cluster.name
self.otype = 'CLUSTER'
elif e_type == 'NODEACTION':
self.oid = entity.target
self.cluster_id = entity.node.cluster_id
self.oname = entity.node.name
self.otype = 'NODE'
else:
self.oid = entity.target
self.cluster_id = ''
self.oname = ''
self.otype = ''
def store(self, context):
'''Store the event into database and return its ID.'''
values = {
'level': self.level,
'timestamp': self.timestamp,
'oid': self.oid,
'otype': self.otype,
'oname': self.oname,
'cluster_id': self.cluster_id,
'user': self.user,
'project': self.project,
'action': self.action,
'status': self.status,
'status_reason': self.status_reason,
'meta_data': self.metadata,
}
event = eo.Event.create(context, values)
self.id = event.id
return self.id
def critical(context, entity, action, status=None, status_reason=None,
timestamp=None):
timestamp = timestamp or timeutils.utcnow(True)
event = Event(timestamp, logging.CRITICAL, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event = DB.Event(timestamp, logging.CRITICAL, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event.store(context)
LOG.critical(_LC('%(name)s [%(id)s] - %(status)s: %(reason)s'),
{'name': event.oname,
@ -122,9 +36,9 @@ def critical(context, entity, action, status=None, status_reason=None,
def error(context, entity, action, status=None, status_reason=None,
timestamp=None):
timestamp = timestamp or timeutils.utcnow(True)
event = Event(timestamp, logging.ERROR, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event = DB.Event(timestamp, logging.ERROR, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event.store(context)
msg = _LE('%(name)s [%(id)s] %(action)s - %(status)s: %(reason)s')
LOG.error(msg,
@ -138,9 +52,9 @@ def error(context, entity, action, status=None, status_reason=None,
def warning(context, entity, action, status=None, status_reason=None,
timestamp=None):
timestamp = timestamp or timeutils.utcnow(True)
event = Event(timestamp, logging.WARNING, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event = DB.Event(timestamp, logging.WARNING, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event.store(context)
msg = _LW('%(name)s [%(id)s] %(action)s - %(status)s: %(reason)s')
LOG.warning(msg,
@ -154,9 +68,9 @@ def warning(context, entity, action, status=None, status_reason=None,
def info(context, entity, action, status=None, status_reason=None,
timestamp=None):
timestamp = timestamp or timeutils.utcnow(True)
event = Event(timestamp, logging.INFO, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event = DB.Event(timestamp, logging.INFO, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event.store(context)
LOG.info(_LI('%(name)s [%(id)s] %(action)s - %(status)s: %(reason)s'),
{'name': event.oname,
@ -169,9 +83,9 @@ def info(context, entity, action, status=None, status_reason=None,
def debug(context, entity, action, status=None, status_reason=None,
timestamp=None):
timestamp = timestamp or timeutils.utcnow(True)
event = Event(timestamp, logging.DEBUG, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event = DB.Event(timestamp, logging.DEBUG, entity,
action=action, status=status, status_reason=status_reason,
user=context.user, project=context.project)
event.store(context)
LOG.debug('%(name)s [%(id)s] %(action)s - %(status)s: %(reason)s',
{'name': event.oname,

View File

100
senlin/events/database.py Normal file
View File

@ -0,0 +1,100 @@
# 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.
from oslo_utils import reflection
from senlin.objects import event as eo
class Event(object):
"""Class encapsulating an interesting happening in Senlin."""
def __init__(self, timestamp, level, entity=None, **kwargs):
self.timestamp = timestamp
self.level = level
self.id = kwargs.get('id', None)
self.user = kwargs.get('user', None)
self.project = kwargs.get('project', None)
self.action = kwargs.get('action', None)
self.status = kwargs.get('status', None)
self.status_reason = kwargs.get('status_reason', None)
# we deal with deserialization first
self.oid = kwargs.get('oid', None)
self.otype = kwargs.get('otype', None)
self.oname = kwargs.get('oname', None)
self.cluster_id = kwargs.get('cluster_id', None)
self.metadata = kwargs.get('metadata', {})
# entity not None implies an initial creation of event object,
# not a deserialization, so we try make an inference here
if entity is not None:
self._infer_entity_data(entity)
def _infer_entity_data(self, entity):
if self.status is None:
self.status = entity.status
if self.status_reason is None:
self.status_reason = entity.status_reason
e_type = reflection.get_class_name(entity, fully_qualified=False)
e_type = e_type.upper()
if e_type == 'CLUSTER':
self.oid = entity.id
self.cluster_id = entity.id
self.oname = entity.name
self.otype = 'CLUSTER'
elif e_type == 'NODE':
self.oid = entity.id
self.cluster_id = entity.cluster_id
self.oname = entity.name
self.otype = 'NODE'
elif e_type == 'CLUSTERACTION':
self.oid = entity.target
self.cluster_id = entity.target
self.oname = entity.cluster.name
self.otype = 'CLUSTER'
elif e_type == 'NODEACTION':
self.oid = entity.target
self.cluster_id = entity.node.cluster_id
self.oname = entity.node.name
self.otype = 'NODE'
else:
self.oid = entity.target
self.cluster_id = ''
self.oname = ''
self.otype = ''
def store(self, context):
"""Store the event into database and return its ID."""
values = {
'level': self.level,
'timestamp': self.timestamp,
'oid': self.oid,
'otype': self.otype,
'oname': self.oname,
'cluster_id': self.cluster_id,
'user': self.user,
'project': self.project,
'action': self.action,
'status': self.status,
'status_reason': self.status_reason,
'meta_data': self.metadata,
}
event = eo.Event.create(context, values)
self.id = event.id
return self.id

View File

View File

@ -16,7 +16,7 @@ from oslo_log import log as logging
from oslo_utils import timeutils
from senlin.engine import cluster as cluster_mod
from senlin.engine import event as EVENT
from senlin.events import database as DB
from senlin.objects import event as eo
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
@ -24,10 +24,10 @@ from senlin.tests.unit.common import utils
CLUSTER_ID = '2c5139a6-24ba-4a6f-bd53-a268f61536de'
class TestEvent(base.SenlinTestCase):
class TestDatabase(base.SenlinTestCase):
def setUp(self):
super(TestEvent, self).setUp()
super(TestDatabase, self).setUp()
self.context = utils.dummy_context()
def test_event_init(self):
@ -46,7 +46,7 @@ class TestEvent(base.SenlinTestCase):
'metadata': {'foo': 'bar'},
}
event = EVENT.Event(timestamp, logging.CRITICAL, **kwargs)
event = DB.Event(timestamp, logging.CRITICAL, **kwargs)
self.assertEqual(timestamp, event.timestamp)
self.assertEqual(logging.CRITICAL, event.level)
@ -69,11 +69,11 @@ class TestEvent(base.SenlinTestCase):
x_cluster = cluster_mod.Cluster('fake-cluster', 0, 'fake-profile',
id='FAKE_CLUSTER')
event = EVENT.Event(timestamp, logging.CRITICAL, x_cluster,
action="FAKE_ACTION", status="ACTIVE",
status_reason="Recovered just now",
user=self.context.user,
project=self.context.project)
event = DB.Event(timestamp, logging.CRITICAL, x_cluster,
action="FAKE_ACTION", status="ACTIVE",
status_reason="Recovered just now",
user=self.context.user,
project=self.context.project)
self.assertEqual(timestamp, event.timestamp)
self.assertIsNone(event.id)
@ -97,7 +97,7 @@ class TestEvent(base.SenlinTestCase):
entity.name = 'obj-name'
mock_get.return_value = 'Cluster'
event = EVENT.Event('timestamp', 'level', entity)
event = DB.Event('timestamp', 'level', entity)
self.assertEqual('timestamp', event.timestamp)
self.assertEqual('level', event.level)
@ -117,7 +117,7 @@ class TestEvent(base.SenlinTestCase):
entity.name = 'obj-name'
mock_get.return_value = 'Node'
event = EVENT.Event('timestamp', 'level', entity)
event = DB.Event('timestamp', 'level', entity)
self.assertEqual('timestamp', event.timestamp)
self.assertEqual('level', event.level)
@ -137,7 +137,7 @@ class TestEvent(base.SenlinTestCase):
entity.cluster.name = 'obj-name'
mock_get.return_value = 'ClusterAction'
event = EVENT.Event('timestamp', 'level', entity)
event = DB.Event('timestamp', 'level', entity)
self.assertEqual('timestamp', event.timestamp)
self.assertEqual('level', event.level)
@ -158,7 +158,7 @@ class TestEvent(base.SenlinTestCase):
entity.node.cluster_id = CLUSTER_ID
mock_get.return_value = 'NodeAction'
event = EVENT.Event('timestamp', 'level', entity)
event = DB.Event('timestamp', 'level', entity)
self.assertEqual('timestamp', event.timestamp)
self.assertEqual('level', event.level)
@ -185,7 +185,7 @@ class TestEvent(base.SenlinTestCase):
'metadata': {'foo': 'bar'},
}
event = EVENT.Event(timestamp, logging.CRITICAL, **kwargs)
event = DB.Event(timestamp, logging.CRITICAL, **kwargs)
self.assertIsNone(event.id)
event_id = event.store(self.context)