1
# Copyright 2011 OpenStack Foundation.
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
19
from oslo.config import cfg
21
from ceilometer.openstack.common import context
22
from ceilometer.openstack.common.gettextutils import _
23
from ceilometer.openstack.common import importutils
24
from ceilometer.openstack.common import jsonutils
25
from ceilometer.openstack.common import log as logging
26
from ceilometer.openstack.common import timeutils
29
LOG = logging.getLogger(__name__)
32
cfg.MultiStrOpt('notification_driver',
34
help='Driver or drivers to handle sending notifications'),
35
cfg.StrOpt('default_notification_level',
37
help='Default notification level for outgoing notifications'),
38
cfg.StrOpt('default_publisher_id',
40
help='Default publisher_id for outgoing notifications'),
44
CONF.register_opts(notifier_opts)
52
log_levels = (DEBUG, WARN, INFO, ERROR, CRITICAL)
55
class BadPriorityException(Exception):
59
def notify_decorator(name, fn):
60
"""Decorator for notify which is used from utils.monkey_patch().
62
:param name: name of the function
63
:param function: - object of the function
64
:returns: function -- decorated function
67
def wrapped_func(*args, **kwarg):
72
body['args'].append(arg)
74
body['kwarg'][key] = kwarg[key]
76
ctxt = context.get_context_from_function_and_args(fn, args, kwarg)
78
CONF.default_publisher_id or socket.gethostname(),
80
CONF.default_notification_level,
82
return fn(*args, **kwarg)
86
def publisher_id(service, host=None):
90
except AttributeError:
91
host = CONF.default_publisher_id or socket.gethostname()
92
return "%s.%s" % (service, host)
95
def notify(context, publisher_id, event_type, priority, payload):
96
"""Sends a notification using the specified driver
98
:param publisher_id: the source worker_type.host of the message
99
:param event_type: the literal type of event (ex. Instance Creation)
100
:param priority: patterned after the enumeration of Python logging
101
levels in the set (DEBUG, WARN, INFO, ERROR, CRITICAL)
102
:param payload: A python dictionary of attributes
104
Outgoing message format includes the above parameters, and appends the
108
a UUID representing the id for this notification
111
the GMT timestamp the notification was sent at
113
The composite message will be constructed as a dictionary of the above
114
attributes, which will then be sent via the transport mechanism defined
119
{'message_id': str(uuid.uuid4()),
120
'publisher_id': 'compute.host1',
121
'timestamp': timeutils.utcnow(),
123
'event_type': 'compute.create_instance',
124
'payload': {'instance_id': 12, ... }}
127
if priority not in log_levels:
128
raise BadPriorityException(
129
_('%s not in valid priorities') % priority)
131
# Ensure everything is JSON serializable.
132
payload = jsonutils.to_primitive(payload, convert_instances=True)
134
msg = dict(message_id=str(uuid.uuid4()),
135
publisher_id=publisher_id,
136
event_type=event_type,
139
timestamp=str(timeutils.utcnow()))
141
for driver in _get_drivers():
143
driver.notify(context, msg)
144
except Exception as e:
145
LOG.exception(_("Problem '%(e)s' attempting to "
146
"send to notification system. "
147
"Payload=%(payload)s")
148
% dict(e=e, payload=payload))
155
"""Instantiate, cache, and return drivers based on the CONF."""
159
for notification_driver in CONF.notification_driver:
161
driver = importutils.import_module(notification_driver)
162
_drivers[notification_driver] = driver
164
LOG.exception(_("Failed to load notifier %s. "
165
"These notifications will not be sent.") %
167
return _drivers.values()
170
def _reset_drivers():
171
"""Used by unit tests to reset the drivers."""