From 3048e85cd712b7da77cf6ac55dd6a689d00e47e5 Mon Sep 17 00:00:00 2001 From: John Spray Date: Tue, 22 Aug 2017 11:41:26 -0400 Subject: [PATCH] pybind/mgr: add MgrStandbyModule Signed-off-by: John Spray --- src/pybind/mgr/mgr_module.py | 117 ++++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py index aaad609e6192f..83fc75ae2cf14 100644 --- a/src/pybind/mgr/mgr_module.py +++ b/src/pybind/mgr/mgr_module.py @@ -10,6 +10,45 @@ import threading from collections import defaultdict +class CPlusPlusHandler(logging.Handler): + def __init__(self, module_inst): + super(CPlusPlusHandler, self).__init__() + self._module = module_inst + + def emit(self, record): + if record.levelno <= logging.DEBUG: + ceph_level = 20 + elif record.levelno <= logging.INFO: + ceph_level = 4 + elif record.levelno <= logging.WARNING: + ceph_level = 1 + else: + ceph_level = 0 + + self._module._ceph_log(ceph_level, self.format(record)) + + +def configure_logger(module_inst, name): + logger = logging.getLogger(name) + + + # Don't filter any logs at the python level, leave it to C++ + logger.setLevel(logging.DEBUG) + + # FIXME: we should learn the log level from C++ land, and then + # avoid calling the C++ level log when we know a message is of + # an insufficient level to be ultimately output + logger.addHandler(CPlusPlusHandler(module_inst)) + + return logger + + +def unconfigure_logger(module_inst, name): + logger = logging.getLogger(name) + rm_handlers = [h for h in logger.handlers if isinstance(h, CPlusPlusHandler)] + for h in rm_handlers: + logger.removeHandler(h) + class CommandResult(object): """ Use with MgrModule.send_command @@ -115,6 +154,52 @@ class CRUSHMap(object): uglymap = ceph_crushmap.get_take_weight_osd_map(self._handle, root) return { int(k): v for k, v in uglymap.get('weights', {}).iteritems() } +class MgrStandbyModule(ceph_module.BaseMgrStandbyModule): + """ + Standby modules only implement a serve and shutdown method, they + are not permitted to implement commands and they do not receive + any notifications. + + They only have access to the mgrmap (for acecssing service URI info + from their active peer), and to configuration settings (read only). + """ + + def __init__(self, module_name, capsule): + super(MgrStandbyModule, self).__init__(capsule) + self.module_name = module_name + self._logger = configure_logger(self, module_name) + + def __del__(self): + unconfigure_logger(self, self.module_name) + + @property + def log(self): + return self._logger + + def serve(self): + """ + The serve method is mandatory for standby modules. + :return: + """ + raise NotImplementedError() + + def get_mgr_id(self): + return self._ceph_get_mgr_id() + + def get_config(self, key): + return self._ceph_get_config(key) + + def get_active_uri(self): + return self._ceph_get_active_uri() + + def get_localized_config(self, key, default=None): + r = self.get_config(self.get_mgr_id() + '/' + key) + if r is None: + r = self.get_config(key) + + if r is None: + r = default + return r class MgrModule(ceph_module.BaseMgrModule): COMMANDS = [] @@ -137,36 +222,22 @@ class MgrModule(ceph_module.BaseMgrModule): PERFCOUNTER_TYPE_MASK = ~2 def __init__(self, module_name, py_modules_ptr, this_ptr): - super(MgrModule, self).__init__(py_modules_ptr, this_ptr) - self._logger = logging.getLogger(module_name) + self.module_name = module_name - # Don't filter any logs at the python level, leave it to C++ - self._logger.setLevel(logging.DEBUG) + # If we're taking over from a standby module, let's make sure + # its logger was unconfigured before we hook ours up + unconfigure_logger(self, self.module_name) + self._logger = configure_logger(self, module_name) - # FIXME: we should learn the log level from C++ land, and then - # avoid calling the C++ level log when we know a message is of - # an insufficient level to be ultimately output - - module_inst = self - class CPlusPlusHandler(logging.Handler): - def emit(self, record): - if record.levelno <= logging.DEBUG: - ceph_level = 20 - elif record.levelno <= logging.INFO: - ceph_level = 4 - elif record.levelno <= logging.WARNING: - ceph_level = 1 - else: - ceph_level = 0 - - module_inst._ceph_log(ceph_level, self.format(record)) - - self._logger.addHandler(CPlusPlusHandler()) + super(MgrModule, self).__init__(py_modules_ptr, this_ptr) self._version = self._ceph_get_version() self._perf_schema_cache = None + def __del__(self): + unconfigure_logger(self, self.module_name) + def update_perf_schema(self, daemon_type, daemon_name): """ For plugins that use get_all_perf_counters, call this when -- 2.39.5