diff --git a/neetbox/logging/_writer.py b/neetbox/logging/_writer.py index 25040c34..7eff4411 100644 --- a/neetbox/logging/_writer.py +++ b/neetbox/logging/_writer.py @@ -1,4 +1,5 @@ import datetime +import inspect import io import os import pathlib @@ -12,6 +13,11 @@ from neetbox.logging.formatting import LogStyle, colored_text, styled_text +# declare type +class LogWriter: + pass + + # declare type class __ConsoleLogWriter: pass @@ -31,20 +37,27 @@ class JsonLogWriter: class RawLog: rich_msg: str caller_identity: Any - default_style: LogStyle + style: LogStyle prefix: Optional[str] = None datetime_format: Optional[str] = None with_identifier: Optional[bool] = None with_datetime: Optional[bool] = None skip_writers: Optional[list[str]] = None - name2writerType = { - "console": __ConsoleLogWriter, - "file": FileLogWriter, - "json": JsonLogWriter, - } - def __repr__(self) -> str: - _default_style = self.default_style + def write_by(self, writer: LogWriter) -> bool: + name2writerType = { + "console": __ConsoleLogWriter, + "file": FileLogWriter, + "json": JsonLogWriter, + } + for swr in self.skip_writers: + if isinstance(writer, name2writerType[swr]): + return False # skip this writer, do not write + writer.write(self) + return False + + def json(self) -> dict: + _default_style = self.style # prefix _prefix = self.prefix or _default_style.prefix # composing datetime @@ -82,16 +95,17 @@ def __repr__(self) -> str: _whom += id_seq[i] return {"prefix": _prefix, "datetime": _datetime, "whom": _whom, "msg": self.rich_msg} - def dumps(self) -> dict: + def __repr__(self) -> str: pass - def loads(s) -> "RawLog": - # todo + def dumps(s: str): + # todo dump from str pass +# Log writer interface class LogWriter: - def write(self, massive: RawLog): + def write(self, raw_log: RawLog): pass @@ -99,14 +113,21 @@ def write(self, massive: RawLog): class __ConsoleLogWriter(metaclass=LogWriter): - def write(self, massive: RawLog): - # todo continue work - massive.default_style.pre = _style.prefix - if prefix is not None: # if using specific prefix - _prefix = prefix - console.print(massive) - - + def write(self, raw_log: RawLog): + _msg_dict = raw_log.json() + _style = raw_log.style + rich_msg = ( + _msg_dict["prefix"] + + _msg_dict["datetime"] + + _style.split_char_cmd * min(len(_msg_dict["datetime"]), 1) + + styled_text(_msg_dict["whom"], style=_style) + + _style.split_char_cmd * min(len(_msg_dict["whom"]), 1), + +_msg_dict["msg"], + ) + rprint(rich_msg) + + +# console writer singleton consoleLogWriter = __ConsoleLogWriter() @@ -266,10 +287,10 @@ def split_lock(self): class FileLogWriter: - # static variable + # class level static pool PATH_2_FILE_WRITER = {} - # non-static things + # instance level non-static things file_writer = None # assign in __init__ def __new__(cls, path, *args, **kwargs): @@ -291,17 +312,28 @@ def __new__(cls, path, *args, **kwargs): def __init__(self, path) -> None: self.file_writer = open(path, "a", encoding="utf-8", buffering=1) - def write(self, massive: RawLog): - self.file_writer.write(massive) + def write(self, raw_log: RawLog): + _msg_dict = raw_log.json() + _style = raw_log.style + text_msg = ( + _msg_dict["prefix"] + + _msg_dict["datetime"] + + _style.split_char_txt * min(len(_msg_dict["datetime"]), 1) + + _msg_dict["whom"] + + _style.split_char_txt * min(len(_msg_dict["whom"]), 1) + + _msg_dict["msg"] + + "\n" + ) + self.file_writer.write(text_msg) # ================== JSON LOG WRITER ===================== class JsonLogWriter(FileLogWriter): - def write(self, massive: RawLog): - # todo convert to json - self.file_writer.write(massive) + def write(self, raw_log: RawLog): + # todo convert to json and write + pass # ================== WS LOG WRITER ===================== @@ -311,7 +343,7 @@ class __WebSocketLogWriter(metaclass=LogWriter): def __init__(self) -> None: pass - def write(self, massive: RawLog): + def write(self, raw_log: RawLog): pass diff --git a/neetbox/logging/logger.py b/neetbox/logging/logger.py index 0c98a89c..e4c0f9d1 100644 --- a/neetbox/logging/logger.py +++ b/neetbox/logging/logger.py @@ -8,16 +8,17 @@ import os from datetime import date, datetime from enum import Enum -from inspect import isclass, iscoroutinefunction, isgeneratorfunction from random import randint -from typing import Any, Optional +from typing import Any, Optional, Union +from rich import print as rprint from rich.panel import Panel from neetbox.core import Registry from neetbox.logging._writer import ( FileLogWriter, JsonLogWriter, + RawLog, consoleLogWriter, webSocketLogWriter, ) @@ -90,28 +91,6 @@ def __call__(self, whom: Any = None, style: Optional[LogStyle] = None) -> "Logge __WHOM_2_LOGGER[whom] = Logger(whom=whom, style=style) return __WHOM_2_LOGGER[whom] - def _write(self, raw_msg): - # perform log - if into_stdout: - rprint( - _prefix - + _datetime - + _style.split_char_cmd * min(len(_datetime), 1) - + styled_text(_whom, style=_style) - + _style.split_char_cmd * min(len(_whom), 1), - _pure_str_message, - ) - if into_file and self.file_writer: - self.file_writer.write( - _prefix - + _datetime - + _style.split_char_txt * min(len(_datetime), 1) - + _whom - + _style.split_char_txt * min(len(_whom), 1) - + _pure_str_message - + "\n" - ) - def log( self, *content, @@ -119,19 +98,34 @@ def log( datetime_format: Optional[str] = None, with_identifier: Optional[bool] = None, with_datetime: Optional[bool] = None, - skip_writers: Optional[list[str]] = None, + skip_writers: Optional[Union[list[str], str]] = None, traceback=2, ): _caller_identity = get_caller_identity_traceback(traceback=traceback) - # getting style - _style = self.style - # converting args into a single string _pure_str_message = "" for msg in content: _pure_str_message += str(msg) + " " + if type(skip_writers) is str: + skip_writers = [skip_writers] + + raw_log = RawLog( + rich_msg=_pure_str_message, + caller_identity=_caller_identity, + style=self.style, + prefix=prefix, + datetime_format=datetime_format, + with_identifier=with_identifier, + with_datetime=with_datetime, + skip_writers=skip_writers, + ) + + for writer in [self.console_writer, self.ws_writer, self.file_writer]: + if writer: + raw_log.write_by(writer) + return self def ok(self, *message, flag="OK"):