Add notifier plugin based on Ceilometer

This drivers sends notifications using notifer API from oslo.messaging

These notifications has speical topic "profiler", and they are collected
by this Ceilometer notification pluging:

https://review.openstack.org/#/c/100239/

Change-Id: I305fc7a13d3c052ffd22073d77ae4f12fae348ca
This commit is contained in:
Boris Pavlovic 2014-07-03 15:18:13 +04:00
parent 090e577244
commit 25eeb78cfe
6 changed files with 103 additions and 2 deletions

@ -0,0 +1,20 @@
# Copyright 2011 OpenStack Foundation.
# All Rights Reserved.
#
# 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 osprofiler import _utils as utils
utils.import_modules_from_package("osprofiler._notifiers")

@ -18,11 +18,26 @@ from osprofiler import _utils as utils
class Notifier(object):
def notify(self, info):
def notify(self, info, context=None):
"""This method will be called on each notifier.notify() call.
To add new drivers you should, create new subclass of this class and
implement notify method.
:param info: Contains information about trace element.
In payload dict there are always 3 ids:
"base_id" - uuid that is common for all notifications
related to one trace. Used to simplify
retrieving of all trace elements from
Ceilometer.
"parent_id" - uuid of parent element in trace
"trace_id" - uuid of current element in trace
With parent_id and trace_id it's quite simple to build
tree of trace elements, which simplify analyze of trace.
:param context: request context that is mostly used to specify
current active user and tenant.
"""
@staticmethod

@ -12,3 +12,45 @@
# 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 osprofiler._notifiers import base
class Messaging(base.Notifier):
def __init__(self, messaging, context, transport, project, service, host):
"""Init Messaging notify driver.
"""
super(Messaging, self).__init__()
self.messaging = messaging
self.context = context
self.project = project
self.service = service
self.notifier = messaging.Notifier(
transport, publisher_id=host, driver="messaging", topic="profiler")
def notify(self, info, context=None):
"""Send notifications to Ceilometer via oslo.messaging notifier API.
:param info: Contains information about trace element.
In payload dict there are always 3 ids:
"base_id" - uuid that is common for all notifications
related to one trace. Used to simplify
retrieving of all trace elements from
Ceilometer.
"parent_id" - uuid of parent element in trace
"trace_id" - uuid of current element in trace
With parent_id and trace_id it's quite simple to build
tree of trace elements, which simplify analyze of trace.
:param context: request context that is mostly used to specify
current active user and tenant.
"""
info["project"] = self.project
info["service"] = self.service
self.notifier.info(context or self.context,
"profiler.%s" % self.service, info)

@ -17,6 +17,8 @@ import base64
import hashlib
import hmac
import json
import os
import six
@ -110,3 +112,19 @@ def itersubclasses(cls, _seen=None):
yield sub
for sub in itersubclasses(sub, _seen):
yield sub
def import_modules_from_package(package):
"""Import modules from package and append into sys.modules
:param: package - Full package name. For example: rally.deploy.engines
"""
path = [os.path.dirname(__file__), '..'] + package.split('.')
path = os.path.join(*path)
for root, dirs, files in os.walk(path):
for filename in files:
if filename.startswith('__') or not filename.endswith('.py'):
continue
new_package = ".".join(root.split(os.sep)).split("....")[1]
module_name = '%s.%s' % (new_package, filename[:-3])
__import__(module_name)

@ -16,7 +16,7 @@
from osprofiler._notifiers import base
def _noop_notifier(info):
def _noop_notifier(info, context=None):
"""Do nothing on notify()."""
pass

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from osprofiler._notifiers import base
from tests import test
@ -46,3 +48,7 @@ class NotifierBaseTestCase(test.TestCase):
def test_notify(self):
base.Notifier().notify("")
def test_plugins_are_imported(self):
base.Notifier.factory("Messaging", mock.MagicMock(), "context",
"transport", "project", "service", "host")