ceilometer通过notification和polling两种方式收集数据的,这里介绍通知机制(notification)的实现过程。
Notification子模块中最重要的类是NotificationService,它主要接受来自openstack各个模块中针对不同meter的notificationmessages,再将消息交给pipelineManager,由pipelineManager将message转化为Sample并发布出去(一般是通过rpc),而ceilometer的collector服务接受rpc消息,然后调用相关的dispatcher(一般是database)来保存sample.
下面针对代码来看一下详细处理流程:
1. 首先NotificationService继承自rpc_service和DispatchedService,因此它可以接收到notificationmessages,并且包含一个dispatcher_manager成员,这里用dispatcher_manager主要是为了记录由notification转化成的Event(见_message_to_event方法)。
class NotificationService(service.DispatchedService, rpc_service.Service):
2. 在initialize_service_hook这个hook中,初始化了pipeline_manager,event_converter和notification_manager三个成员。其中notification_manager通过extension.ExtensionManager方式加载了namespace为“ceilometer.notification”的所有entry_points(定义在setup.cfg中),这里的每个entry_point都是一个NotificationBase对象。
self.pipeline_manager = pipeline.setup_pipeline(
transformer.TransformerExtensionManager(
'ceilometer.transformer',
),
)
self.event_converter = event_converter.setup_events(
extension.ExtensionManager(
namespace='ceilometer.event.trait_plugin'))
self.notification_manager = \
extension.ExtensionManager(
namespace=self.NOTIFICATION_NAMESPACE,
invoke_on_load=True,
)
3. NotificationBase是一个专门针对Notification场景下Plugin的基类(与之对应的PollsterBase类针对的是polling的场景)。具体的plugin子类要为其所支持的事件类型成员变量event_types赋值,同时还要实现两个抽象方法:get_exchange_topics,process_notification,get_exchange_topics方法中要指定连接plugin子类的exchange和topic;process_notification方法中是将notification转化成sample的具体实现,该方法由to_samples方法来调用,to_samples方法是对外的接口。
4. 在NotificationService的initialize_service_hook方法最后notification_manager中每个NotificationBase对象通过_setup_subscription方法将其topics和exchange的组合加入消息队列供NotificationService来监听。一旦有消息进来,回调函数process_notification会被调用。
self.notification_manager.map(self._setup_subscription)
for exchange_topic in handler.get_exchange_topics(cfg.CONF):
for topic in exchange_topic.topics:
try:
self.conn.join_consumer_pool(
callback=self.process_notification,
pool_name=topic,
topic=topic,
exchange_name=exchange_topic.exchange,
ack_on_error=ack_on_error)
5. 在process_notification中notification通过方法参数的方式传进来,在该方法内notification_manager中的每个NotificationBase对象和notification又被传入_process_notification_for_ext中并执行。
self.notification_manager.map(self._process_notification_for_ext,
notification=notification)
6. _process_notification_for_ext方法中调用了NotificationBase对象的to_samples方法生成samples(会做event_type是否匹配的判断),并由pipeline_manager将samples发布出去。
with self.pipeline_manager.publisher(context.get_admin_context()) as p:
# FIXME(dhellmann): Spawn green thread?
p(list(ext.obj.to_samples(notification)))
7. 如果配置了store_events参数,process_notification方法还会调用_message_to_event方法来记录这次notification事件。
for dispatcher in self.dispatcher_manager:
problem_events.extend(dispatcher.obj.record_events(event))