Allow to publish several counters in a row

Support publishing of multiple counters at once. This change the pipeline
and RPC calls to send a list of counter by default instead of only once
counter. This allows to make only one RPC calls when sending multiple
counters to be more efficient.

This implements blueprint publish-counters-list-rpc

Change-Id: Ie4155b35585f261e6ff9816e5a845a479151eefd
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou
2013-02-05 11:32:58 +01:00
parent 3340461656
commit 59b5a5a488
11 changed files with 177 additions and 89 deletions

View File

@@ -16,12 +16,12 @@
# License for the specific language governing permissions and limitations
# under the License.
import itertools
import os
from stevedore import extension
import yaml
from ceilometer import extension_manager
from ceilometer.openstack.common import cfg
from ceilometer.openstack.common import log
@@ -170,13 +170,12 @@ class Pipeline(object):
return transformers
def _publish_counter_to_one_publisher(self, ext, ctxt, counter, source):
def _publish_counters_to_one_publisher(self, ext, ctxt, counters, source):
try:
ext.obj.publish_counter(ctxt, counter, source)
ext.obj.publish_counters(ctxt, counters, source)
except Exception as err:
LOG.warning("Pipeline %s: Continue after error "
"from publisher %s for %s",
self, ext.name, counter)
"from publisher %s", self, ext.name)
LOG.exception(err)
def _transform_counter(self, start, ctxt, counter, source):
@@ -194,36 +193,45 @@ class Pipeline(object):
self, transformer, counter)
LOG.exception(err)
def _publish_counter(self, start, ctxt, counter, source):
def _publish_counters(self, start, ctxt, counters, source):
"""Push counter into pipeline for publishing.
param start: the first transformer that the counter will be injected.
This is mainly for flush() invocation that transformer
may emit counters
param ctxt: execution context from the manager or service
param counter: counter
param counters: counter list
param source: counter source
"""
LOG.audit("Pipeline %s: Transform counter %s from %s transformer",
self, counter, start)
counter = self._transform_counter(start, ctxt, counter, source)
if not counter:
return
LOG.audit("Pipeline %s: Publish counter %s", self, counter)
transformed_counters = []
for counter in counters:
LOG.audit("Pipeline %s: Transform counter %s from %s transformer",
self, counter, start)
counter = self._transform_counter(start, ctxt, counter, source)
if counter:
transformed_counters.append(counter)
LOG.audit("Pipeline %s: Publishing counters", self)
self.publisher_manager.map(self.publishers,
self._publish_counter_to_one_publisher,
self._publish_counters_to_one_publisher,
ctxt=ctxt,
counter=counter,
counters=transformed_counters,
source=source,
)
LOG.audit("Pipeline %s: Published counter %s", self, counter)
LOG.audit("Pipeline %s: Published counters", self)
def publish_counter(self, ctxt, counter, source):
if self.support_counter(counter.name):
self._publish_counter(0, ctxt, counter, source)
self.publish_counters(ctxt, [counter], source)
def publish_counters(self, ctxt, counters, source):
for counter_name, counters in itertools.groupby(
sorted(counters, key=lambda c: c.name),
lambda c: c.name):
if self.support_counter(counter_name):
self._publish_counters(0, ctxt, counters, source)
# (yjiang5) To support counters like instance:m1.tiny,
# which include variable part at the end starting with ':'.
@@ -251,8 +259,9 @@ class Pipeline(object):
LOG.audit("Flush pipeline %s", self)
for (i, transformer) in enumerate(self.transformers):
for c in transformer.flush(ctxt, source):
self._publish_counter(i + 1, ctxt, c, source)
self._publish_counters(i + 1, ctxt,
list(transformer.flush(ctxt, source)),
source)
def get_interval(self):
return self.interval