~ubuntu-branches/ubuntu/vivid/ceilometer/vivid-proposed

« back to all changes in this revision

Viewing changes to ceilometer/openstack/common/notifier/api.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2014-06-13 13:20:35 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20140613132035-42ibzh8j7ww2q31i
Tags: 2014.2~b1-0ubuntu1
* New upstream release.
* debian/control: Open up juno release
* debian/patches/fix-requirements.patch: Refreshed.
* debian/rules: Patch the ceilometer.conf.sample directly since
  the configuration files are generated by a tool.
* debian/ceilometer-common.install: Drop sources.json.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2011 OpenStack Foundation.
2
 
# All Rights Reserved.
3
 
#
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
7
 
#
8
 
#         http://www.apache.org/licenses/LICENSE-2.0
9
 
#
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
14
 
#    under the License.
15
 
 
16
 
import socket
17
 
import uuid
18
 
 
19
 
from oslo.config import cfg
20
 
 
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
27
 
 
28
 
 
29
 
LOG = logging.getLogger(__name__)
30
 
 
31
 
notifier_opts = [
32
 
    cfg.MultiStrOpt('notification_driver',
33
 
                    default=[],
34
 
                    help='Driver or drivers to handle sending notifications'),
35
 
    cfg.StrOpt('default_notification_level',
36
 
               default='INFO',
37
 
               help='Default notification level for outgoing notifications'),
38
 
    cfg.StrOpt('default_publisher_id',
39
 
               default=None,
40
 
               help='Default publisher_id for outgoing notifications'),
41
 
]
42
 
 
43
 
CONF = cfg.CONF
44
 
CONF.register_opts(notifier_opts)
45
 
 
46
 
WARN = 'WARN'
47
 
INFO = 'INFO'
48
 
ERROR = 'ERROR'
49
 
CRITICAL = 'CRITICAL'
50
 
DEBUG = 'DEBUG'
51
 
 
52
 
log_levels = (DEBUG, WARN, INFO, ERROR, CRITICAL)
53
 
 
54
 
 
55
 
class BadPriorityException(Exception):
56
 
    pass
57
 
 
58
 
 
59
 
def notify_decorator(name, fn):
60
 
    """Decorator for notify which is used from utils.monkey_patch().
61
 
 
62
 
        :param name: name of the function
63
 
        :param function: - object of the function
64
 
        :returns: function -- decorated function
65
 
 
66
 
    """
67
 
    def wrapped_func(*args, **kwarg):
68
 
        body = {}
69
 
        body['args'] = []
70
 
        body['kwarg'] = {}
71
 
        for arg in args:
72
 
            body['args'].append(arg)
73
 
        for key in kwarg:
74
 
            body['kwarg'][key] = kwarg[key]
75
 
 
76
 
        ctxt = context.get_context_from_function_and_args(fn, args, kwarg)
77
 
        notify(ctxt,
78
 
               CONF.default_publisher_id or socket.gethostname(),
79
 
               name,
80
 
               CONF.default_notification_level,
81
 
               body)
82
 
        return fn(*args, **kwarg)
83
 
    return wrapped_func
84
 
 
85
 
 
86
 
def publisher_id(service, host=None):
87
 
    if not host:
88
 
        try:
89
 
            host = CONF.host
90
 
        except AttributeError:
91
 
            host = CONF.default_publisher_id or socket.gethostname()
92
 
    return "%s.%s" % (service, host)
93
 
 
94
 
 
95
 
def notify(context, publisher_id, event_type, priority, payload):
96
 
    """Sends a notification using the specified driver
97
 
 
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
103
 
 
104
 
    Outgoing message format includes the above parameters, and appends the
105
 
    following:
106
 
 
107
 
    message_id
108
 
      a UUID representing the id for this notification
109
 
 
110
 
    timestamp
111
 
      the GMT timestamp the notification was sent at
112
 
 
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
115
 
    by the driver.
116
 
 
117
 
    Message example::
118
 
 
119
 
        {'message_id': str(uuid.uuid4()),
120
 
         'publisher_id': 'compute.host1',
121
 
         'timestamp': timeutils.utcnow(),
122
 
         'priority': 'WARN',
123
 
         'event_type': 'compute.create_instance',
124
 
         'payload': {'instance_id': 12, ... }}
125
 
 
126
 
    """
127
 
    if priority not in log_levels:
128
 
        raise BadPriorityException(
129
 
            _('%s not in valid priorities') % priority)
130
 
 
131
 
    # Ensure everything is JSON serializable.
132
 
    payload = jsonutils.to_primitive(payload, convert_instances=True)
133
 
 
134
 
    msg = dict(message_id=str(uuid.uuid4()),
135
 
               publisher_id=publisher_id,
136
 
               event_type=event_type,
137
 
               priority=priority,
138
 
               payload=payload,
139
 
               timestamp=str(timeutils.utcnow()))
140
 
 
141
 
    for driver in _get_drivers():
142
 
        try:
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))
149
 
 
150
 
 
151
 
_drivers = None
152
 
 
153
 
 
154
 
def _get_drivers():
155
 
    """Instantiate, cache, and return drivers based on the CONF."""
156
 
    global _drivers
157
 
    if _drivers is None:
158
 
        _drivers = {}
159
 
        for notification_driver in CONF.notification_driver:
160
 
            try:
161
 
                driver = importutils.import_module(notification_driver)
162
 
                _drivers[notification_driver] = driver
163
 
            except ImportError:
164
 
                LOG.exception(_("Failed to load notifier %s. "
165
 
                                "These notifications will not be sent.") %
166
 
                              notification_driver)
167
 
    return _drivers.values()
168
 
 
169
 
 
170
 
def _reset_drivers():
171
 
    """Used by unit tests to reset the drivers."""
172
 
    global _drivers
173
 
    _drivers = None