console_scripts =
ceilometer-api = ceilometer.cmd.api:main
ceilometer-agent-central = ceilometer.cmd.polling:main_central
ceilometer-agent-compute = ceilometer.cmd.polling:main_compute
ceilometer-polling = ceilometer.cmd.polling:main
ceilometer-agent-notification = ceilometer.cmd.agent_notification:main
ceilometer-agent-ipmi = ceilometer.cmd.polling:main_ipmi
ceilometer-send-sample = ceilometer.cli:send_sample
ceilometer-dbsync = ceilometer.cmd.storage:dbsync
ceilometer-expirer = ceilometer.cmd.storage:expirer
ceilometer-rootwrap = oslo_rootwrap.cmd:main
ceilometer-collector = ceilometer.cmd.collector:main
ceilometer-alarm-evaluator = ceilometer.cmd.alarm:evaluator
ceilometer-alarm-notifier = ceilometer.cmd.alarm:notifier
首先来看ceilometer-alarm-notifier的初始化和启动过程,这个组件服务所实现的功能是,当报警器被触发之后,发送相关的通知操作。
ceilometer/cmd/alarm.py----def notifier():
defnotifier():
"""
初始化并启动AlarmNotifierService服务(报警器被触发的通知服务);
"""
service.prepare_service()
"""
launch:加载并启动指定的服务,最终调用了服务的start方法实现服务的启动;
AlarmNotifierService:报警器被触发的通知服务实现;
AlarmNotifierService():获取类AlarmNotifierService的实例化对象;
"""
os_service.launch(alarm_service.AlarmNotifierService()).wait()
方法小结:
1 实现AlarmNotifierService类的初始化操作,在类的初始化过程中会加载命名空间ceilometer.alarm.notifier所定义的所有插件,确定所有实现通知操作的实现方式;
2 launch方法最终会调用类AlarmNotifierService的start方法,实现组件服务的启动操作
1 服务ceilometer-alarm-notifier的初始化
classAlarmNotifierService(os_service.Service):
"""
报警器被触发的通知服务实现;
"""
def__init__(self):
"""
通过messaging模块的get_transport方法获取transport,然后通过get_rpc_server获取rpc_server
"""
super(AlarmNotifierService,self).__init__()
transport = messaging.get_transport()
self.rpc_server = messaging.get_rpc_server(
transport,cfg.CONF.alarm.notifier_rpc_topic,self)
2 服务ceilometer-alarm-notifier的启动
class AlarmNotifierService----def start
defstart(self):
"""
服务的启动;
"""
super(AlarmNotifierService,self).start()
self.rpc_server.start()
# Add a dummy thread to have wait() working
self.tg.add_timer(604800,lambda:None)
3 类AlarmNotifierService中的方法notify_alarm
方法notify_alarm是具体实现报警器触发后的发送通知操作的具体方法,当报警器被触发之后,都会调用这个方法,主要实现了以下内容:
遍历所有要通知报警器被触发的URL,针对每个要通知的URL地址,实现:
1 获取系统所采用的消息通信方式;
2 通过HTTP/HTTPS协议POST方法实现发送相关报警器被触发的通知(到action指定的URL),(or)通过日志记录相关报警器被触发的通知;
defnotify_alarm(self,context,data):
"""
遍历所有要通知报警器被触发的URL,针对每个要通知的URL地址,实现:
1.获取系统所采用的消息通信方式;
2.通过HTTPS协议POST方法实现发送相关报警器被触发的通知(到action指定的URL),(or)通过日志记录相关报警器被触发的通知;
通知报警器被触发,通知内容中包括:
alarm_id:被触发的报警器的ID;
previous:报警器(触发)之前的状态;
current:报警器被触发后转换到的新状态;
reason:改变报警器状态的原因;
"""
actions = data.get('actions')
if notactions:
LOG.error(_("Unable to notify for an alarm with no action"))
return
# actions:要运行的action的URL(多个);
# alarm_id:被触发的报警器的ID;
# previous:报警器(触发)之前的状态;
# current:报警器被触发后转换到的新状态;
# reason:改变报警器状态的原因;
for actionin actions:
"""
获取系统所采用的消息通信方式;
通过HTTPS协议POST方法实现发送相关报警器被触发的通知(到action指定的URL),(or)通过日志记录相关报警器被触发的通知;
"""
self._handle_action(action,
data.get('alarm_id'),
data.get('alarm_name'),
data.get('severity'),
data.get('previous'),
data.get('current'),
data.get('reason'),
data.get('reason_data'))
ceilometer-alarm-evaluator服务的初始化和启动
再来分析服务组件ceilometer-alarm-evaluator的初始化和启动操作,这个服务组件即ceilometer报警服务;来看方法ceilometer/cmd/alarm.py----def evaluator()
,这个方法即实现了ceilometer-alarm-evaluator服务的初始化和启动操作。
defevaluator():
"""
加载并启动SingletonAlarmService服务(单例报警服务);
报警服务系统:SingletonAlarmService和PartitionedAlarmService;
默认报警服务:ceilometer.alarm.service.SingletonAlarmService;
如果要应用分布式报警系统,则需要在这里修改配置文件中的参数;
"""
service.prepare_service()
eval_service_mgr = driver.DriverManager(
"ceilometer.alarm.evaluator_service",
cfg.CONF.alarm.evaluation_service,
invoke_on_load=True)
LOG.debug("Alarm evaluator loaded: %s"%
eval_service_mgr.driver.__class__.__name__)
"""
launch:加载并启动SingletonAlarmService服务,最终调用了服务的start方法实现服务的启动;
配置文件定义了默认报警服务:ceilometer.alarm.service.SingletonAlarmService
SingletonAlarmService:单例的报警服务;
"""
os_service.launch(eval_service_mgr.driver).wait()
1 单例报警服务SingletonAlarmService的初始化和启动操作1.1 SingletonAlarmService类初始化操作
类SingletonAlarmService的初始化操作主要完成了两部分内容:
* 加载命名空间ceilometer.alarm.evaluator中的所有插件;
ceilometer.alarm.evaluator =
threshold = ceilometer.alarm.evaluator.threshold:ThresholdEvaluator
combination = ceilometer.alarm.evaluator.combination:CombinationEvaluator
即描述了报警器状态的评估判定的两种模式:联合报警器状态评估和单一报警器状态评估;
* 建立线程池,用于后续报警器服务中若干操作的运行;
classSingletonAlarmService(AlarmService,os_service.Service):
def__init__(self):
super(SingletonAlarmService,self).__init__()
通过父类AlarmService初始化:
@six.add_metaclass(abc.ABCMeta)
class AlarmService(object):
def__init__(self):
super(AlarmService,self).__init__()
self._load_evaluators()
self.api_client =None
def_load_evaluators(self):
"""
_load_evaluators:
这里得到的就是加载命名空间ceilometer.alarm.evaluator中的所有插件;
namespace = ceilometer.alarm.evaluator
ceilometer.alarm.evaluator =
threshold = ceilometer.alarm.evaluator.threshold:ThresholdEvaluator
combination = ceilometer.alarm.evaluator.combination:CombinationEvaluator
"""
self.evaluators = extension.ExtensionManager(
namespace=ceilometer_alarm.EVALUATOR_EXTENSIONS_NAMESPACE,
invoke_on_load=True,
invoke_args=(rpc_alarm.RPCAlarmNotifier(),)
)
# 这里得到的就是上面所加载的命名空间ceilometer.alarm.evaluator中的所有插件;
self.supported_evaluators = [ext.namefor extin
self.evaluators.extensions]
1.2 SingletonAlarmService类启动操作
defstart(self):
"""
单例报警器服务SingletonAlarmService的启动操作;
按照一定时间间隔实现循环执行方法self._evaluate_assigned_alarms;
获取alarm集合,针对每一个报警器,实现根据报警器模式的类型(threshold和combination),来实现单一报警器模式或者联合报警器模式的评估判定;
"""
super(SingletonAlarmService,self).start()
# 评估周期60s;
ifself.evaluators:
interval = cfg.CONF.alarm.evaluation_interval
# add_timer:按照一定时间间隔实现循环执行方法self._evaluate_assigned_alarms;
# _evaluate_assigned_alarms:
# 先获取alarm集合,对每一个alarm,调用_evaluate_alarm方法;
# 针对每一个报警器,实现根据报警器的类型(threshold和combination),来实现:
# 单一报警器状态的评估判定;
# 联合报警器状态的评估判定;
self.tg.add_timer(
interval,
self._evaluate_assigned_alarms,
0)
# Add a dummy thread to have wait() working
self.tg.add_timer(604800,lambda:None)
class AlarmService----def _evaluate_assigned_alarms
这个方法实现获取当前部分的所有报警器,对每一个报警器进行报警触发的评估判定;
1.获取当前部分的所有报警器;
2.针对每一个报警器,实现根据报警器模式的类型(threshold和combination),来实现单一报警器模式或者联合报警器模式的评估判定;
def_evaluate_assigned_alarms(self):
"""
获取当前部分的所有报警器,对每一个报警器进行报警触发的评估判定;
1.获取当前部分的所有报警器;
2.针对每一个报警器,实现根据报警器模式的类型(threshold和combination),
来实现单一报警器模式或者联合报警器模式的评估判定;
"""
try:
# 获取所有报警器列表;
# 对于单例报警器:通过指定客户端通过http协议发送GET请求获取分配给当前部分的报警器;
alarms =self._assigned_alarms()
LOG.info(_('initiating evaluation cycle on %d alarms') %
len(alarms))
# 遍历所有的报警器;
# 针对每一个报警器,实现根据报警器的类型(threshold和combination),来实现:
# 单一报警器状态的评估判定;
# 联合报警器状态的评估判定;
foralarm inalarms:
self._evaluate_alarm(alarm)
exceptException:
LOG.exception(_('alarm evaluation cycle failed'))
2 分布式报警服务PartitionedAlarmService的初始化和启动操作
与单例报警服务SingletonAlarmService类似