mirror of
https://gitee.com/quecpython/helios-service.git
synced 2025-05-19 06:08:22 +08:00
879 lines
24 KiB
Python
879 lines
24 KiB
Python
import _thread
|
|
import dataCall
|
|
import net
|
|
import sim
|
|
import checkNet
|
|
import osTimer
|
|
import ujson
|
|
import uos as os
|
|
import utime
|
|
from event_message import Event, EventManager
|
|
from misc import Power
|
|
|
|
__GROUP_ID = "qpy.quectel.com"
|
|
__ARTIFACT_ID = "qpy-framework"
|
|
__VERSION = "1.0.0.RELEASE"
|
|
|
|
ANY = "anonymous"
|
|
|
|
|
|
class Signal(object):
|
|
|
|
def __init__(self, doc):
|
|
self.receivers = {
|
|
ANY: list()
|
|
}
|
|
self.doc = doc
|
|
|
|
def connect(self, receiver, sender=ANY):
|
|
if sender not in self.receivers:
|
|
self.receivers[sender] = list()
|
|
self.receivers[sender].append(receiver)
|
|
|
|
def connect_via(self, sender=ANY):
|
|
def decorator(fn):
|
|
self.connect(fn, sender)
|
|
return fn
|
|
|
|
return decorator
|
|
|
|
def receivers_for(self, sender):
|
|
return self.receivers.get(sender, [])
|
|
|
|
def send(self, *senders, **kwargs):
|
|
if not len(senders):
|
|
senders = list(ANY)
|
|
for sender in senders:
|
|
self.__publish(sender, **kwargs)
|
|
|
|
def __publish(self, sender, **kwargs):
|
|
for receiver in self.receivers_for(sender):
|
|
try:
|
|
receiver(sender, **kwargs)
|
|
except Exception as e:
|
|
print("send to {} kwargs error, reason {}".format(sender, kwargs))
|
|
|
|
def disconnect(self, receiver, sender=ANY):
|
|
receivers = self.receivers_for(sender)
|
|
receivers.remove(receiver)
|
|
|
|
|
|
class NamedSignal(Signal):
|
|
|
|
def __init__(self, name, doc=None):
|
|
super().__init__(doc)
|
|
self.name = name
|
|
|
|
|
|
class Namespace(dict):
|
|
|
|
def signal(self, name, doc=None):
|
|
try:
|
|
return self[name]
|
|
except KeyError:
|
|
return self.setdefault(name, NamedSignal(name, doc))
|
|
|
|
|
|
signal = Namespace().signal
|
|
|
|
|
|
class ModelDTO(object):
|
|
def model_to_dict(self, *args, **kwargs):
|
|
pass
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
return self.model_to_dict(*args, **kwargs)
|
|
|
|
|
|
class QMessageModel(ModelDTO):
|
|
def __init__(self, ms_id=None, msg_type=0xFF, message=None, sender=None, from_event=None, lock_msg=None):
|
|
self.__msg_type = msg_type
|
|
self.__message_id = ms_id
|
|
self.__message = message
|
|
self.__sender = "anonymous" if sender is None else sender
|
|
self.__from_event = from_event
|
|
self.__lock_msg = lock_msg
|
|
|
|
@property
|
|
def msg_type(self):
|
|
return self.__msg_type
|
|
|
|
@property
|
|
def lock_msg(self):
|
|
return self.__lock_msg
|
|
|
|
@property
|
|
def message_id(self):
|
|
return self.__message_id
|
|
|
|
@property
|
|
def sender(self):
|
|
return self.__sender
|
|
|
|
@property
|
|
def message(self):
|
|
return self.__message
|
|
|
|
@property
|
|
def from_event(self):
|
|
return self.__from_event
|
|
|
|
def model_to_dict(self):
|
|
return dict(message_id=self.message_id, msg_type=self.msg_type, message=self.message, sender=self.sender,
|
|
from_event=self.from_event)
|
|
|
|
|
|
class LockMsgModel(ModelDTO):
|
|
"""传输对象"""
|
|
|
|
def __init__(self, lock):
|
|
self.__lock = lock
|
|
self.__msg = dict(message=None)
|
|
|
|
@property
|
|
def msg(self):
|
|
return self.__msg
|
|
|
|
@msg.setter
|
|
def msg(self, msg):
|
|
self.__msg = msg
|
|
|
|
@property
|
|
def lock(self):
|
|
return self.__lock
|
|
|
|
def model_to_dict(self, *args, **kwargs):
|
|
return dict(lock=self.__lock, msg=self.__msg)
|
|
|
|
|
|
class AbstractService(object):
|
|
def __init__(self, sign):
|
|
self.__name = sign
|
|
|
|
self.__signal = signal(sign)
|
|
|
|
self.__event = Event(sign)
|
|
|
|
self.__em = EventManager()
|
|
|
|
self.__message_id = 0
|
|
|
|
self.__service_status = 0
|
|
|
|
self.__em.register_event(self.__event)
|
|
|
|
self.__mode = 1
|
|
|
|
def set_mode(self, mode):
|
|
self.__mode = mode
|
|
|
|
@property
|
|
def mode(self):
|
|
return self.__mode
|
|
|
|
@property
|
|
def name(self):
|
|
return self.__name
|
|
|
|
@property
|
|
def message_id(self):
|
|
return self.__message_id + 1
|
|
|
|
@property
|
|
def signal(self):
|
|
return self.__signal
|
|
|
|
def ms_id_increase(self):
|
|
if self.__message_id > 99999:
|
|
self.__message_id = 0
|
|
else:
|
|
self.__message_id += 1
|
|
return self.message_id
|
|
|
|
def _get_message(self, sender=None, msg_type=0xFF, message=None, callback=None, lock_msg=None):
|
|
if callback is not None and not callable(callback):
|
|
return None
|
|
ms_id = self.ms_id_increase()
|
|
qm = QMessageModel(ms_id=ms_id, msg_type=msg_type, message=message, sender=sender, from_event=self.__event.name,
|
|
lock_msg=lock_msg)
|
|
return qm
|
|
|
|
def _callback(self, **kwargs):
|
|
em = kwargs.get("event_message", False)
|
|
if em.msg:
|
|
msg = em.msg
|
|
try:
|
|
self.signal.send(em.msg.sender, message=msg())
|
|
except Exception as e:
|
|
success = 0
|
|
else:
|
|
success = 1
|
|
resp_data = dict(message=msg(), success=success)
|
|
if em.callback is not None:
|
|
try:
|
|
em.callback(**resp_data)
|
|
except Exception as e:
|
|
pass
|
|
if msg.lock_msg is not None:
|
|
msg.lock_msg.msg = resp_data
|
|
msg.lock_msg.lock.release()
|
|
|
|
def _clear(self, *args, **kwargs):
|
|
self.__event.clear()
|
|
|
|
def _add_default_handler(self):
|
|
self.add_handler(self._callback)
|
|
|
|
def register_event(self):
|
|
pass
|
|
|
|
def prepare_before_start(self):
|
|
pass
|
|
|
|
def prepare_before_stop(self):
|
|
pass
|
|
|
|
def start_crontab(self, *args, **kwargs):
|
|
pass
|
|
|
|
def add_handler(self, handler):
|
|
self.__event.add_handler(handler)
|
|
return handler
|
|
|
|
def add_handler_via(self):
|
|
|
|
def decorator(fn):
|
|
self.add_handler(fn)
|
|
return fn
|
|
|
|
return decorator
|
|
|
|
def send_msg_async(self, msg_type=0xFF, message=None, callback=None, sender=None):
|
|
if self.status():
|
|
qm = self._get_message(sender=sender, msg_type=msg_type, message=message, callback=callback)
|
|
self.__event.post(qm, callback=callback)
|
|
else:
|
|
return 0
|
|
|
|
def send_msg_sync(self, msg_type=0xFF, message=None, callback=None, sender=None):
|
|
if self.status():
|
|
lock = _thread.allocate_lock()
|
|
lock_msg = LockMsgModel(lock)
|
|
qm = self._get_message(sender=sender, msg_type=msg_type, message=message, callback=callback,
|
|
lock_msg=lock_msg)
|
|
self.__event.post(qm, callback=callback)
|
|
lock_msg.lock.acquire()
|
|
msg = lock_msg.msg
|
|
del lock_msg
|
|
return msg
|
|
else:
|
|
return 0
|
|
|
|
def send_msg(self, msg_type=0xFF, message=None, callback=None, sender=None, mode=None):
|
|
mode_pattern = self.mode
|
|
if mode is not None:
|
|
mode_pattern = mode
|
|
if mode_pattern:
|
|
return self.send_msg_async(msg_type=msg_type, message=message, callback=callback, sender=sender)
|
|
else:
|
|
return self.send_msg_sync(msg_type=msg_type, message=message, callback=callback, sender=sender)
|
|
|
|
def _component_start(self):
|
|
if not self.__service_status:
|
|
self.register_event()
|
|
self._add_default_handler()
|
|
self.prepare_before_start()
|
|
self.start_crontab()
|
|
|
|
def start(self):
|
|
self._component_start()
|
|
self.__service_status = self.__em.start()
|
|
return self.__service_status
|
|
|
|
def status(self):
|
|
return self.__em.status
|
|
|
|
def stop(self):
|
|
self.prepare_before_stop()
|
|
self.__service_status = self.__em.stop()
|
|
return self.__service_status
|
|
|
|
def close(self):
|
|
self._clear()
|
|
|
|
def subscribe(self, cb, sender=ANY):
|
|
self.signal.connect(cb, sender=sender)
|
|
|
|
def unsubscribe(self, cb, sender=ANY):
|
|
self.signal.disconnect(cb, sender=sender)
|
|
|
|
def publish(self, msg, sender=ANY, msg_type=0XFF):
|
|
self.send_msg(message=msg, msg_type=msg_type, sender=sender)
|
|
|
|
|
|
class TimeResolver(object):
|
|
|
|
def __init__(self):
|
|
self.output_format = "{ascdate} {asctime} {ascweek}"
|
|
self.weekday_list = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
|
|
|
|
def resolver(self, rt=None):
|
|
if rt is None:
|
|
rt = utime.localtime()
|
|
d_f = "{0:02}"
|
|
return self.output_format.format(
|
|
ascdate=str(rt[0]) + "-" + d_f.format(rt[1]) + "-" + d_f.format(rt[2])
|
|
, asctime=d_f.format(rt[3]) + ":" + d_f.format(rt[4]) + ":" + d_f.format(rt[5]),
|
|
ascweek=self.weekday_list[rt[6]])
|
|
|
|
|
|
class JsonParser(object):
|
|
DEFAULT_FILE_NAME = "config.json"
|
|
|
|
@classmethod
|
|
def composite_url(cls, url):
|
|
if not url.endswith("/"):
|
|
url += "/"
|
|
return url + cls.DEFAULT_FILE_NAME
|
|
|
|
@classmethod
|
|
def parse(cls, url):
|
|
rep_d = dict(
|
|
status=1,
|
|
data=dict()
|
|
)
|
|
try:
|
|
url = cls.composite_url(url)
|
|
with open(url, "r") as f:
|
|
rep_d["data"] = ujson.load(f)
|
|
except Exception as e:
|
|
rep_d["status"] = 0
|
|
return rep_d
|
|
else:
|
|
return rep_d
|
|
|
|
|
|
def Singleton(cls):
|
|
_instance = {}
|
|
|
|
def _singleton(*args, **kargs):
|
|
if cls not in _instance:
|
|
_instance[cls] = cls(*args, **kargs)
|
|
return _instance[cls]
|
|
|
|
return _singleton
|
|
|
|
|
|
class ServiceMonitor(object):
|
|
THRESHOLD = 3
|
|
|
|
def __init__(self, service):
|
|
self.service = service
|
|
self.__failed_count = 0
|
|
self.__level = 0
|
|
self.__timer = None
|
|
self.__ping_count = 0
|
|
self.__exception_handlers = {}
|
|
self.service.signal.connect(self.ping_handler, sender=0xFE)
|
|
|
|
def set_level(self, level):
|
|
if self.__level != level:
|
|
self.__level = level
|
|
|
|
def __timer_handle(self, *args):
|
|
"""定时器调度"""
|
|
if self.__ping_count:
|
|
self.__failed_count += 1
|
|
self.__ping_count = self.__ping_count + 1
|
|
self.service.signal.send(0xFE)
|
|
if self.__failed_count:
|
|
self.__failed_handle()
|
|
|
|
def set_exception_handlers(self, handler):
|
|
if handler is not None:
|
|
self.__exception_handlers = handler
|
|
|
|
def __failed_handle(self):
|
|
"""失败处理"""
|
|
try:
|
|
for k, v in self.__exception_handlers.items():
|
|
if k == "reboot":
|
|
if v.get("failCount") == self.__failed_count:
|
|
# 关机
|
|
Power.powerDown()
|
|
elif k == "stop":
|
|
if v.get("failCount") == self.__failed_count:
|
|
# 停止服务
|
|
self.stop()
|
|
else:
|
|
continue
|
|
except Exception as e:
|
|
print(e)
|
|
|
|
def ping_handler(self, *args, **kwargs):
|
|
self.__ping_count = 0
|
|
|
|
def start(self):
|
|
if self.__level != self.THRESHOLD:
|
|
self.service.start()
|
|
if self.__timer is None:
|
|
self.__timer = osTimer()
|
|
self.__timer.start(15000, 1, self.__timer_handle)
|
|
return self.status()
|
|
|
|
def status(self):
|
|
return self.service.status()
|
|
|
|
def clear(self):
|
|
self.__failed_count = 0
|
|
self.__level = 0
|
|
if self.__timer is not None:
|
|
self.__timer.stop()
|
|
self.__timer.delete()
|
|
self.__timer = None
|
|
self.__ping_count = 0
|
|
|
|
def stop(self):
|
|
if self.__level != self.THRESHOLD:
|
|
self.service.stop()
|
|
self.clear()
|
|
return self.status
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
return self.service
|
|
|
|
|
|
LOGGER = "LOG"
|
|
|
|
|
|
class LOG_LV:
|
|
DEBUG = "DEBUG"
|
|
INFO = "INFO"
|
|
WARNING = "WARNING"
|
|
ERROR = "ERROR"
|
|
CRITICAL = "CRITICAL"
|
|
|
|
|
|
class AbstractLogOutputUtil(object):
|
|
def open(self):
|
|
pass
|
|
|
|
def output(self, message, **kwargs):
|
|
pass
|
|
|
|
def close(self):
|
|
pass
|
|
|
|
def __call__(self, message, **kwargs):
|
|
self.output(message, **kwargs)
|
|
|
|
|
|
@Singleton
|
|
class PrintLogOutputUtil(AbstractLogOutputUtil):
|
|
def output(self, message, **kwargs):
|
|
print(message.log_format)
|
|
|
|
|
|
class AbstractFormatUtil(object):
|
|
def __init__(self):
|
|
self.time = ""
|
|
self.tag = ""
|
|
self.level = ""
|
|
self.content = ""
|
|
self.log_format = ""
|
|
|
|
|
|
class LogFormatUtil(AbstractFormatUtil):
|
|
|
|
@classmethod
|
|
def format(cls, *args, **kwargs):
|
|
self = LogFormatUtil()
|
|
self.time = args[0]
|
|
self.tag = args[1]
|
|
self.level = args[2]
|
|
self.content = args[3]
|
|
self.log_format = "{} {} [{}] - {}\n".format(self.time, self.tag, self.level, self.content)
|
|
return self
|
|
|
|
|
|
class LogServiceMonitor(ServiceMonitor):
|
|
|
|
@staticmethod
|
|
def create_monitor(config=None):
|
|
log_service = LogService()
|
|
if config is not None:
|
|
level = config.get('level')
|
|
log_service.set_level(level)
|
|
lsm = LogServiceMonitor(log_service)
|
|
if config is not None:
|
|
lsm.set_exception_handlers(config.get('exceptionHandlers', None))
|
|
return lsm
|
|
|
|
|
|
class NetServiceMonitor(ServiceMonitor):
|
|
|
|
@staticmethod
|
|
def create_monitor(config=None):
|
|
net_service = NetService()
|
|
nsm = NetServiceMonitor(net_service)
|
|
if config is not None:
|
|
nsm.set_exception_handlers(config.get('exceptionHandlers', None))
|
|
return nsm
|
|
|
|
|
|
NET = "NET"
|
|
|
|
ENABLE_ = "enable"
|
|
NET_ = "NET"
|
|
DATACALL_ = "DATACALL"
|
|
|
|
|
|
@Singleton
|
|
class NetService(AbstractService):
|
|
def __init__(self):
|
|
super().__init__(NET)
|
|
|
|
self.__data_call = dataCall
|
|
|
|
self.__net = net
|
|
|
|
self.__sim = sim
|
|
|
|
self.__net_connect_status = False
|
|
|
|
self.__data_call_status = False
|
|
|
|
self.server_status = {
|
|
DATACALL_: {ENABLE_: 1},
|
|
NET_: {ENABLE_: 0}
|
|
}
|
|
self.check_net = checkNet.CheckNetwork("QuecPython_Helios_Framework", "this latest version")
|
|
|
|
@property
|
|
def sim(self):
|
|
return self.__sim
|
|
|
|
@property
|
|
def data_call(self):
|
|
return self.__data_call
|
|
|
|
@property
|
|
def net(self):
|
|
return self.__net
|
|
|
|
def set_enable(self, sr, enable):
|
|
"""set start"""
|
|
self.server_status[sr][ENABLE_] = enable
|
|
|
|
def set_apn(self, profileIdx, ipType, apn, username, password, authType):
|
|
return self.__data_call.setApn(profileIdx, ipType, apn, username, password, authType)
|
|
|
|
def ev_dc(self, args):
|
|
if self.server_status[DATACALL_][ENABLE_]:
|
|
profile_idx = args[0]
|
|
datacall_status = args[1]
|
|
|
|
msg_dict = \
|
|
{
|
|
"sim_status": None,
|
|
"net_status": None,
|
|
"datacall_status": datacall_status,
|
|
"profile_id": profile_idx,
|
|
"ip_type": None,
|
|
"IPv4": None,
|
|
"IPv4_DNS1": None,
|
|
"IPv4_DNS2": None,
|
|
"IPv6": None,
|
|
"IPv6_DNS1": None,
|
|
"IPv6_DNS2": None,
|
|
}
|
|
|
|
sim_status = self.__sim.getStatus()
|
|
net_status = self.__net.getState()
|
|
datacall_info = self.__data_call.getInfo(profile_idx, 2)
|
|
|
|
msg_dict.update({"sim_status": sim_status})
|
|
|
|
if net_status != -1:
|
|
if net_status[0][0] == 0 or net_status[1][0] == 0:
|
|
msg_dict.update({"net_status": 0})
|
|
else:
|
|
msg_dict.update({"net_status": net_status[1][0]})
|
|
else:
|
|
msg_dict.update({"net_status": -1})
|
|
if datacall_info != -1:
|
|
if datacall_info[2][0] == 1 or datacall_info[3][0] == 1:
|
|
msg_dict.update({"datacall_status": 1})
|
|
else:
|
|
msg_dict.update({"datacall_status": 0})
|
|
msg_dict.update({"ip_type": datacall_info[1]})
|
|
msg_dict.update({"IPv4": datacall_info[2][2]})
|
|
msg_dict.update({"IPv4_DNS1": datacall_info[2][3]})
|
|
msg_dict.update({"IPv4_DNS2": datacall_info[2][4]})
|
|
msg_dict.update({"IPv6": datacall_info[3][2]})
|
|
msg_dict.update({"IPv6_DNS1": datacall_info[3][3]})
|
|
msg_dict.update({"IPv6_DNS2": datacall_info[3][4]})
|
|
self.send_msg(msg_type=1, message=msg_dict)
|
|
|
|
def ev_nc(self, args):
|
|
if self.server_status[NET_][ENABLE_]:
|
|
net_status = args[1]
|
|
self.send_msg(msg_type=0, message={"network_register_status": net_status})
|
|
|
|
def wait_connect(self, timeout):
|
|
self.check_net.poweron_print_once()
|
|
return self.check_net.wait_network_connected(timeout)
|
|
|
|
def get_net_status(self):
|
|
self.__data_call_status = self.__data_call.getInfo(1, 0)[2][0]
|
|
return self.__data_call_status
|
|
|
|
def register_event(self):
|
|
self.__data_call.setCallback(self.ev_dc)
|
|
|
|
|
|
@Singleton
|
|
class LogService(AbstractService):
|
|
|
|
def __init__(self):
|
|
super().__init__(LOGGER)
|
|
self.__reporter = [PrintLogOutputUtil(), ]
|
|
self.__tr = TimeResolver()
|
|
self.format_util = LogFormatUtil()
|
|
self.__level_map = {
|
|
LOG_LV.DEBUG: 0,
|
|
LOG_LV.INFO: 1,
|
|
LOG_LV.WARNING: 2,
|
|
LOG_LV.ERROR: 3,
|
|
LOG_LV.CRITICAL: 4
|
|
}
|
|
self.low_level = 0
|
|
|
|
def __set_report(self, report):
|
|
if isinstance(report, AbstractLogOutputUtil):
|
|
self.__reporter.append(report)
|
|
|
|
def set_output(self, out_obj):
|
|
if isinstance(out_obj, AbstractLogOutputUtil):
|
|
self.__set_report(out_obj)
|
|
else:
|
|
self.log_send(self.name, LOG_LV.ERROR, '"{}" is not extend AbstractLogOutputUtil'.format(out_obj))
|
|
raise Exception('"{}" is not extend AbstractLogOutputUtil'.format(out_obj))
|
|
|
|
def set_level(self, level):
|
|
if level in self.__level_map:
|
|
self.low_level = self.__level_map[level]
|
|
else:
|
|
self.low_level = 0
|
|
|
|
def log_send(self, sign, level, msg, mode=1):
|
|
"""send log deal"""
|
|
if self.mode is not None:
|
|
mode = self.mode
|
|
if self.__level_map[level] >= self.low_level:
|
|
if mode:
|
|
self.send_msg_async(message=self.format_msg(sign, level, msg))
|
|
else:
|
|
self.send_msg_sync(message=self.format_msg(sign, level, msg))
|
|
|
|
def format_msg(self, sign, level, msg):
|
|
return self.format_util.format(self.__tr.resolver(), sign, level, msg)
|
|
|
|
def output_msg(self, *args, **kwargs):
|
|
msg = "message"
|
|
em = kwargs.get(msg, False)
|
|
if em:
|
|
for repoter in self.__reporter:
|
|
repoter.output(em[msg])
|
|
|
|
def prepare_before_stop(self):
|
|
for repoter in self.__reporter:
|
|
repoter.close()
|
|
|
|
def prepare_before_start(self):
|
|
self.signal.connect(self.output_msg, sender="anonymous")
|
|
for repoter in self.__reporter:
|
|
repoter.open()
|
|
|
|
|
|
class LogAdapter(object):
|
|
|
|
def __init__(self, name, enable=1):
|
|
self.log_service = LogService()
|
|
self.name = name
|
|
self.enable = enable
|
|
self.mode = 1
|
|
self.tag = None
|
|
|
|
def get_tag(self):
|
|
if self.tag is None:
|
|
return self.name
|
|
else:
|
|
return self.tag
|
|
|
|
def critical(self, msg):
|
|
if self.enable:
|
|
self.log_service.log_send(self.name, LOG_LV.CRITICAL, msg, self.mode)
|
|
|
|
def debug(self, msg):
|
|
if self.enable:
|
|
self.log_service.log_send(self.name, LOG_LV.DEBUG, msg, self.mode)
|
|
|
|
def info(self, msg):
|
|
if self.enable:
|
|
self.log_service.log_send(self.name, LOG_LV.INFO, msg, self.mode)
|
|
|
|
def warning(self, msg):
|
|
if self.enable:
|
|
self.log_service.log_send(self.name, LOG_LV.WARNING, msg, self.mode)
|
|
|
|
def error(self, msg):
|
|
if self.enable:
|
|
self.log_service.log_send(self.name, LOG_LV.ERROR, msg, self.mode)
|
|
|
|
|
|
def version():
|
|
return {"GROUP_ID": __GROUP_ID, "artifact_id": __ARTIFACT_ID, "VERSION": __VERSION}
|
|
|
|
|
|
@Singleton
|
|
class Guard(object):
|
|
def __init__(self):
|
|
self.monitor_service = set()
|
|
self.timer = None
|
|
self.__status = 0
|
|
|
|
def register_monitor(self, monitor):
|
|
self.monitor_service.add(monitor)
|
|
|
|
def start(self):
|
|
for monitor in self.monitor_service:
|
|
monitor.start()
|
|
self.__status = 1
|
|
|
|
def reload_level(self):
|
|
for monitor in self.monitor_service:
|
|
monitor.set_level(0)
|
|
monitor.start()
|
|
self.__status = 1
|
|
|
|
def stop(self):
|
|
for monitor in self.monitor_service:
|
|
monitor.stop()
|
|
self.__status = 0
|
|
|
|
def status(self):
|
|
return self.__status
|
|
|
|
def upgrade(self):
|
|
pass
|
|
|
|
def monitor_map(self):
|
|
return {m.service.name: m.service for m in self.monitor_service}
|
|
|
|
|
|
@Singleton
|
|
class GuardContext(object):
|
|
|
|
def __init__(self):
|
|
self.__guard = Guard()
|
|
self.system_config = {}
|
|
self.service_config = {}
|
|
self.config_map = {
|
|
"/usr/etc/system_config": self.system_config,
|
|
"/usr/etc/app_config": self.service_config
|
|
}
|
|
self.config_parser = JsonParser()
|
|
self.monitor_map = dict()
|
|
self.error_handler = print
|
|
|
|
def servers(self):
|
|
return self.monitor_map.copy()
|
|
|
|
def get_server(self, name):
|
|
return self.monitor_map[name]()
|
|
|
|
def stop_server(self, name):
|
|
return self.monitor_map[name].stop()
|
|
|
|
@staticmethod
|
|
def get_logger(name):
|
|
return LogAdapter(name)
|
|
|
|
@staticmethod
|
|
def path_exist(check_path):
|
|
try:
|
|
os.stat(check_path)
|
|
except Exception as e:
|
|
return 0
|
|
else:
|
|
return 1
|
|
|
|
def load_config_definitions(self):
|
|
root_path = "/usr/etc/"
|
|
stat = self.path_exist(root_path)
|
|
if not stat:
|
|
return
|
|
self.load_configs(root_path)
|
|
|
|
def load_configs(self, root_path):
|
|
stat = self.path_exist(root_path)
|
|
if not stat:
|
|
self.error_handler("[ WARN ] {} path is not exist".format(root_path))
|
|
return True
|
|
for par_path in os.listdir(root_path):
|
|
abs_path = root_path + par_path
|
|
for sub_path in os.listdir(abs_path):
|
|
truth_path = abs_path + "/" + sub_path
|
|
rep_d = self.config_parser.parse(truth_path)
|
|
if rep_d["status"] == 0:
|
|
self.error_handler("[ WARN ] read {} status {}".format(truth_path, 0))
|
|
else:
|
|
self.config_map[abs_path][sub_path] = rep_d["data"]
|
|
|
|
def create_monitors(self):
|
|
# 创建monitors
|
|
monitor_map = dict()
|
|
monitor_map.update(self.create_system_monitors())
|
|
monitor_map.update(self.create_app_monitors())
|
|
self.monitor_map = monitor_map
|
|
|
|
def start(self):
|
|
self.__guard.start()
|
|
|
|
def register_monitors(self):
|
|
for k, v in self.monitor_map.items():
|
|
self.__guard.register_monitor(v)
|
|
|
|
def refresh(self):
|
|
self.load_config_definitions()
|
|
self.create_monitors()
|
|
self.register_monitors()
|
|
self.start()
|
|
|
|
def reload(self):
|
|
self.__guard.reload_level()
|
|
|
|
def create_system_monitors(self):
|
|
monitor_map = dict()
|
|
try:
|
|
LOG = "log"
|
|
log_monitor = LogServiceMonitor.create_monitor(self.system_config.get(LOG, None))
|
|
monitor_map[LOG] = log_monitor
|
|
print("[ OK ] create sys monitor log service")
|
|
except Exception as e:
|
|
self.error_handler("[ FAILED ] load log monitor error reason:{}".format(e))
|
|
try:
|
|
NET = "net"
|
|
net_monitor = NetServiceMonitor.create_monitor(self.system_config.get(NET, None))
|
|
monitor_map[NET] = net_monitor
|
|
print("[ OK ] create sys monitor net service")
|
|
except Exception as e:
|
|
# 异常重定向
|
|
self.error_handler("[ FAILED ] load net monitor error reason:{}".format(e))
|
|
return monitor_map
|
|
|
|
def create_app_monitors(self):
|
|
monitor_map = dict()
|
|
return monitor_map
|