From 299a1f6a213cd49939a36c536858967d111fabf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaxsen=20Xu=28=E8=AE=B8=E6=B6=A6=E6=9D=B0=29?= Date: Fri, 29 Oct 2021 14:50:41 +0800 Subject: [PATCH] update binliker min to reduce size of file and delete other that we do not used code and update log service to support ali code commint --- code/usr/bin/components/blinker_min.py | 538 ++----------------------- code/usr/bin/log_service.py | 71 +++- 2 files changed, 88 insertions(+), 521 deletions(-) diff --git a/code/usr/bin/components/blinker_min.py b/code/usr/bin/components/blinker_min.py index 69a118b..0ad5493 100644 --- a/code/usr/bin/components/blinker_min.py +++ b/code/usr/bin/components/blinker_min.py @@ -1,523 +1,53 @@ -# -*- coding: utf-8; fill-column: 76 -*- - -import gc - -__all__ = ["signal", "Signal"] - - -class attrgetter: - __slots__ = ('_attrs', '_call') - - def __init__(self, attr, *attrs): - if not attrs: - if not isinstance(attr, str): - raise TypeError('attribute name must be a string') - self._attrs = (attr,) - names = attr.split('.') - - def func(obj): - for name in names: - obj = getattr(obj, name) - return obj - - self._call = func - else: - self._attrs = (attr,) + attrs - getters = tuple(map(attrgetter, self._attrs)) - - def func(obj): - return tuple(getter(obj) for getter in getters) - - self._call = func - - def __call__(self, obj): - return self._call(obj) - - def __repr__(self): - return '%s.%s(%s)' % (self.__class__.__module__, - self.__class__.__qualname__, - ', '.join(map(repr, self._attrs))) - - -class ReferenceType(object): - - def __new__(cls, *args, **kwargs): - return super(ReferenceType, cls).__new__(cls) - - def __call__(self, *args, **kwargs): - return - - def __init__(self, *args, **kwargs): - self.params = dict() - - def __setitem__(self, key, value): - self.__dict__[key] = value - - def __getitem__(self, key): - if key not in self.__dict__: - self.__dict__[key] = None - return self.__dict__[key] - - __callback__ = property(lambda self: object(), lambda self, v: None, lambda self: None) # default - - -ref = ReferenceType - - -class KeyedRef(ref): - __slots__ = "key", - - def __new__(type, ob, callback, key): - self = ref.__new__(type, ob, callback) - self.key = key - return self - - def __init__(self, ob, callback, key): - super().__init__(ob, callback) - - -class WeakValueDictionary(dict): - def __init__(self, dict=None): - self.data = {} - - def remove(k, selfref=ref(self)): - self = selfref() - if self is not None: - if self._iterating: - self._pending_removals.append(k) - else: - del self.data[k] - - self._remove = remove - self._pending_removals = [] - self._iterating = set() - self._dirty_len = False - if dict is not None: - self.update(dict) - - def _commit_removals(self): - gc.collect() - - def __getitem__(self, key): - if self._pending_removals: - self._commit_removals() - o = self.data[key]() - if o is None: - raise KeyError(key) - else: - return o - - def __setitem__(self, key, value): - if self._pending_removals: - self._commit_removals() - self.data[key] = KeyedRef(value, self._remove, key) - - def get(self, key, default=None): - if self._pending_removals: - self._commit_removals() - try: - wr = self.data[key] - except KeyError: - return default - else: - o = wr() - if o is None: - return default - else: - return o - - def update(self, other=None, **kwargs): - if self._pending_removals: - self._commit_removals() - d = self.data - if other is not None: - if not hasattr(other, "items"): - other = dict(other) - for key, o in other.items(): - d[key] = KeyedRef(o, self._remove, key) - for key, o in kwargs.items(): - d[key] = KeyedRef(o, self._remove, key) - - -try: - callable -except NameError: - def callable(object): - return hasattr(object, '__call__') - -get_self = attrgetter('__self__') -get_func = attrgetter('__func__') - - -class BoundMethodWeakref(object): - _all_instances = WeakValueDictionary() - - def __new__(cls, target, on_delete=None, *arguments, **named): - key = cls.calculate_key(target) - current = cls._all_instances.get(key) - if current is not None: - current.deletion_methods.append(on_delete) - return current - else: - base = super(BoundMethodWeakref, cls).__new__(cls) - cls._all_instances[key] = base - base.__init__(target, on_delete, *arguments, **named) - return base - - def __init__(self, target, on_delete=None): - def remove(self=self): - methods = self.deletion_methods[:] - del self.deletion_methods[:] - try: - del self.__class__._all_instances[self.key] - except KeyError: - pass - for function in methods: - try: - if callable(function): - function(self) - except Exception as e: - print('Exception during saferef %s ' - 'cleanup function %s: %s' % (self, function, e)) - - self.deletion_methods = [on_delete] - self.key = self.calculate_key(target) - im_self = get_self(target) - im_func = get_func(target) - self.weak_self = ref(im_self, remove) - self.weak_func = ref(im_func, remove) - self.self_name = str(im_self) - self.func_name = str(im_func.__name__) - - def calculate_key(cls, target): - return (id(get_self(target)), id(get_func(target))) - - calculate_key = classmethod(calculate_key) - - def __str__(self): - return "%s(%s.%s)" % ( - self.__class__.__name__, - self.self_name, - self.func_name, - ) - - __repr__ = __str__ - - def __call__(self): - target = self.weak_self() - if target is not None: - function = self.weak_func() - if function is not None: - return function.__get__(target) - return None - - -class defaultdict(object): - params = dict() - - def __init__(self, default_factory=None, *a, **kw): - super().__init__(*a, **kw) - self.default_factory = default_factory - - def __getitem__(self, key): - try: - result = self.params[key] - return result - except KeyError: - return self.__missing__(key) - - def __setitem__(self, key, value): - try: - self.params[key] = set(value) - except TypeError: - return "Type error" - - def __missing__(self, key): - if self.default_factory is None: - raise KeyError(key) - self.params[key] = value = self.default_factory() - return value - - def __reduce__(self): - if self.default_factory is None: - args = tuple() - else: - args = self.default_factory, - return type(self), args, None, None, self.items() - - def copy(self): - return self.__copy__() - - def pop(self, key, default): - return self.params.pop(key, default) - - def values(self): - return self.params.values() - - def items(self): - return self.params.items() - - def clear(self): - return self.params.clear() - - def __copy__(self): - return type(self)(self.default_factory, self) - - def __repr__(self): - return 'defaultdict(%s, %s)' % (self.default_factory, - dict.__repr__(self)) - - def __contains__(self, key): - if key in self.params: - return True - else: - return False - - -class _symbol(object): - - def __init__(self, name): - self.__name__ = self.name = name - - def __reduce__(self): - return symbol, (self.name,) - - def __repr__(self): - return self.name - - -_symbol.__name__ = 'symbol' - - -class symbol(object): - symbols = {} - - def __new__(cls, name): - try: - return cls.symbols[name] - except KeyError: - return cls.symbols.setdefault(name, _symbol(name)) - - -try: - text = (str, unicode) -except NameError: - text = str - - -def hashable_identity(obj): - if hasattr(obj, '__func__'): - return (id(obj.__func__), id(obj.__self__)) - elif isinstance(obj, text): - return obj - else: - return id(obj) - - -WeakTypes = (ref, BoundMethodWeakref) - - -class annotatable_weakref(ref): - """A weakref.ref that supports custom instance attributes.""" - - -def reference(object, callback=None, **annotations): - if callable(object): - weak = callable_reference(object, callback) - else: - weak = annotatable_weakref(object, callback) - for key, value in annotations.items(): - setattr(weak, key, value) - return weak - - -def callable_reference(object, callback=None): - if hasattr(object, 'im_self') and object.im_self is not None: - return BoundMethodWeakref(target=object, on_delete=callback) - elif hasattr(object, '__self__') and object.__self__ is not None: - return BoundMethodWeakref(target=object, on_delete=callback) - return annotatable_weakref(object, callback) - - -ANY = symbol('ANY') -ANY.__doc__ = 'Token for "any sender".' -ANY_ID = 0 +ANY = "anonymous" class Signal(object): - ANY = ANY - def receiver_connected(self): - return Signal(doc="Emitted after a receiver connects.") + def __init__(self, doc): + self.receivers = { + ANY: list() + } + self.doc = doc - def receiver_disconnected(self): - return Signal(doc="Emitted after a receiver disconnects.") + def connect(self, receiver, sender=ANY): + if sender not in self.receivers: + self.receivers[sender] = list() + self.receivers[sender].append(receiver) - def __init__(self, doc=None): - self.receivers = {} - self._by_receiver = defaultdict(default_factory=set) - self._by_sender = defaultdict(default_factory=set) - self._weak_senders = {} - - def __repr__(self): - return "<%s at %#x>" % (self.__class__.__name__, id(self)) - - def connect(self, receiver, sender=ANY, weak=False): - receiver_id = hashable_identity(receiver) - weak = False - receiver_ref = receiver - if sender is ANY: - sender_id = ANY_ID - else: - sender_id = hashable_identity(sender) - self.receivers.setdefault(receiver_id, receiver_ref) - self._by_sender[sender_id].add(receiver_id) - self._by_receiver[receiver_id].add(sender_id) - del receiver_ref - - if sender is not ANY and sender_id not in self._weak_senders: - try: - sender_ref = reference(sender, self._cleanup_sender) - sender_ref.sender_id = sender_id - except TypeError: - pass - else: - self._weak_senders.setdefault(sender_id, sender_ref) - del sender_ref - - if ('receiver_connected' in self.__dict__ and - self.receiver_connected.receivers): - try: - self.receiver_connected.send(self, - receiver=receiver, - sender=sender, - weak=weak) - except: - self.disconnect(receiver, sender) - raise - if receiver_connected.receivers and self is not receiver_connected: - try: - receiver_connected.send(self, - receiver_arg=receiver, - sender_arg=sender, - weak_arg=weak) - except: - self.disconnect(receiver, sender) - raise - return receiver - - def connect_via(self, sender=ANY, weak=False): + def connect_via(self, sender=ANY): def decorator(fn): - self.connect(fn, sender, weak) + self.connect(fn, sender) return fn return decorator - def send(self, *sender, **kwargs): - if len(sender) == 0: - sender = None - elif len(sender) > 1: - raise TypeError('send() accepts only one positional argument, ' - '%s given' % len(sender)) - else: - sender = sender[0] - if not self.receivers: - return [] - else: - return [(receiver, receiver(sender, **kwargs)) - for receiver in self.receivers_for(sender)] - - def has_receivers_for(self, sender): - if not self.receivers: - return False - if self._by_sender[ANY_ID]: - return True - if sender is ANY: - return False - return hashable_identity(sender) in self._by_sender - def receivers_for(self, sender): - if self.receivers: - sender_id = hashable_identity(sender) - if sender_id in self._by_sender: - ids = (self._by_sender[ANY_ID] | - self._by_sender[sender_id]) - else: - ids = self._by_sender[ANY_ID].copy() - for receiver_id in ids: - receiver = self.receivers.get(receiver_id) - if receiver is None: - continue - if isinstance(receiver, WeakTypes): - strong = receiver() - if strong is None: - self._disconnect(receiver_id, ANY_ID) - continue - receiver = strong - yield receiver + 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): - if sender is ANY: - sender_id = ANY_ID - else: - sender_id = hashable_identity(sender) - receiver_id = hashable_identity(receiver) - self._disconnect(receiver_id, sender_id) - - if ('receiver_disconnected' in self.__dict__ and - self.receiver_disconnected.receivers): - self.receiver_disconnected.send(self, - receiver=receiver, - sender=sender) - - def _disconnect(self, receiver_id, sender_id): - if sender_id == ANY_ID: - if self._by_receiver.pop(receiver_id, False): - for bucket in self._by_sender.values(): - bucket.discard(receiver_id) - self.receivers.pop(receiver_id, None) - else: - self._by_sender[sender_id].discard(receiver_id) - self._by_receiver[receiver_id].discard(sender_id) - - def _cleanup_receiver(self, receiver_ref): - self._disconnect(receiver_ref.receiver_id, ANY_ID) - - def _cleanup_sender(self, sender_ref): - sender_id = sender_ref.sender_id - assert sender_id != ANY_ID - self._weak_senders.pop(sender_id, None) - for receiver_id in self._by_sender.pop(sender_id, ()): - self._by_receiver[receiver_id].discard(sender_id) - - def _cleanup_bookkeeping(self): - for mapping in (self._by_sender, self._by_receiver): - for _id, bucket in list(mapping.items()): - if not bucket: - mapping.pop(_id, None) - - def _clear_state(self): - self._weak_senders.clear() - self.receivers.clear() - self._by_sender.clear() - self._by_receiver.clear() - - -receiver_connected = Signal("""\ -Sent by a :class:`Signal` after a receiver connects. -""") + receivers = self.receivers_for(sender) + receivers.remove(receiver) class NamedSignal(Signal): def __init__(self, name, doc=None): - Signal.__init__(self, doc) + super().__init__(doc) self.name = name - def __repr__(self): - base = Signal.__repr__(self) - return "%s; %r>" % (base[:-1], self.name) - class Namespace(dict): @@ -529,13 +59,3 @@ class Namespace(dict): signal = Namespace().signal -if __name__ == '__main__': - dice_roll = signal('dice_roll') - - - def odd_subscriber(sender, **kwargs): - print("Observed dice roll %r. %r" % (sender, kwargs)) - - - dice_roll.connect(odd_subscriber, sender=0x03) - result = dice_roll.send(3) diff --git a/code/usr/bin/log_service.py b/code/usr/bin/log_service.py index 51bf881..3edae7d 100644 --- a/code/usr/bin/log_service.py +++ b/code/usr/bin/log_service.py @@ -3,7 +3,7 @@ from usr.utils.service_utils import Singleton from usr.utils.resolver import TimeResolver from usr.bin.components.monitor import ServiceMonitor from machine import UART -import uos +import uos, ujson LOGGER = "LOG" @@ -42,7 +42,7 @@ class UartLogOutputUtil(AbstractLogOutputUtil): @Singleton class PrintLogOutputUtil(AbstractLogOutputUtil): def output(self, message, **kwargs): - print(message) + print(message.log_format) @Singleton @@ -55,6 +55,40 @@ class MqttLogOutputUtil(AbstractLogOutputUtil): pass +class AliCloudLogOutPut(AbstractLogOutputUtil): + def __init__(self, server): + self.server = server + self.topic = "/sys/{}/{}/thing/log/post".format(self.server.productKey, self.server.DeviceName) + self.id = 0 + super().__init__() + + def get_id(self): + if self.id > 999999: + self.id = 0 + self.id += 1 + + def output(self, message, **kwargs): + content = { + "utcTime": "T".join(message.time.split(" ")[:-1]) + "+0800", + "logLevel": message.level, + "module": message.tag, + "code": message.level, + "logContent": message.content + } + if message.level == "ERROR": + content["traceContext"] = message.content + reply = { + "id": str(self.get_id()), + "version": "1.0", + "sys": { + "ack": 0 + }, + "params": [content], + "method": "thing.log.post" + } + self.server.publish(self.topic, ujson.dumps(reply)) + + @Singleton class ConsoleLogOutputUtil(AbstractLogOutputUtil): def __init__(self): @@ -89,14 +123,26 @@ class FileLogOutputUtil(AbstractLogOutputUtil): class AbstractFormatUtil(object): + def __init__(self): + self.time = "" + self.tag = "" + self.level = "" + self.content = "" + self.log_format = "" + def format(self, *args, **kwargs): pass class LogFormatUtil(AbstractFormatUtil): + def format(self, *args, **kwargs): - log_format = "{} {} [{}] - {}\n".format(args[0], args[1], args[2], args[3]) - return log_format + 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): @@ -122,7 +168,7 @@ class LogService(AbstractService): def __init__(self): super().__init__(LOGGER) - self.__reporter = PrintLogOutputUtil() + self.__reporter = [PrintLogOutputUtil(), ] self.__tr = TimeResolver() self.format_util = LogFormatUtil() self.__level_map = { @@ -136,13 +182,11 @@ class LogService(AbstractService): def __set_report(self, report): if isinstance(report, AbstractLogOutputUtil): - self.__reporter = report + self.__reporter.append(report) def set_output(self, out_obj): if isinstance(out_obj, AbstractLogOutputUtil): - self.__reporter.close() - self.__reporter = out_obj - self.__reporter.open() + 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)) @@ -174,14 +218,17 @@ class LogService(AbstractService): msg = "message" em = kwargs.get(msg, False) if em: - self.__reporter.output(em[msg]) + for repoter in self.__reporter: + repoter.output(em[msg]) def prepare_before_stop(self): - self.__reporter.close() + for repoter in self.__reporter: + repoter.close() def prepare_before_start(self): self.signal.connect(self.output_msg, sender="anonymous") - self.__reporter.open() + for repoter in self.__reporter: + repoter.open() class LogAdapter(object):