加了一个还没写好的test 稍微用enum完善一下logger

This commit is contained in:
shenjack 2022-10-01 12:47:48 +08:00
parent 2912747cc2
commit 1a17326ac5
10 changed files with 3589 additions and 2681 deletions

1
.gitignore vendored
View File

@ -150,3 +150,4 @@ other things/
.git-/ .git-/
*cmake-build-debug *cmake-build-debug
libs/utils/logger.html

View File

@ -15,4 +15,3 @@ gitee: @shenjackyuanjie
from .delivery import Delivery from .delivery import Delivery
# lazy之后之前全部导入的(太多了写不动__all__了 # lazy之后之前全部导入的(太多了写不动__all__了
from .scientific_unit import *

View File

@ -1,42 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
class Units:
"""
base class of all units
"""
def __init__(self):
pass
class _Newton(Units):
pass
newton = _Newton()
class _Metre(Units):
pass
metre = _Metre()
class _Second(Units):
pass
second = _Second()

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +1,252 @@
"""
:author shenjackyuanjie
:contact 3695888:qq.com
"""
# ------------------------------- # -------------------------------
# Difficult Rocket # Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com # Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
import re
import os
import time
import enum
import atexit
import inspect
import threading import threading
from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, FATAL
from types import FrameType from types import FrameType
from typing import Union, List, Optional, Iterable from typing import Optional, Union, Dict, Iterable, Tuple, Any, List
os.system('')
# print(os.path.abspath(os.curdir))
# 如果想要直接使用 logger 来 logging
# 直接调用 logger.debug() 即可
# 默认配置会有
# ----------
# 配置方式一
# 直接使用 logger.Logger()
# 将会创建一个空 logger
# 可以自行通过
# 配置方式二
color_reset_suffix = "\033[0m"
""" 只是用来重置颜色的后缀 """
re_find_color_code = r'\033\[[^\f\n\r\t\vm]*m'
re_color_code = re.compile(re_find_color_code)
"""
OFF > FATAL > ERROR > WARN > INFO > FINE > FINER > DEBUG > TRACE > ALL
logging.py
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
"""
ALL = NOTSET
TRACE = 5
FINE = 7
class LoggingLevel(enum.IntEnum):
""" 存储 logger 级别的 enum 类"""
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
FINE = 7
TRACE = 5
NOTSET = 0
ALL = NOTSET
level_name_map = ...
name_level_map = ...
logger_configs = ...
class ThreadLock: class ThreadLock:
# with ThreadLock """一个用来 with 的线程锁"""
def __init__(self, the_lock: threading.Lock, time_out: Union[float, int] = 1 / 60) -> None: ... def __init__(self, the_lock: threading.Lock, time_out: Union[float, int] = 1 / 60) -> None: ...
def __enter__(self) -> "ThreadLock": ... def __enter__(self): ...
def __exit__(self, exc_type, exc_val, exc_tb) -> None: ... def __exit__(self, exc_type, exc_val, exc_tb): ...
class ListCache: class ListCache:
"""一个线程安全的列表缓存""" """一个线程安全的列表缓存"""
def __init__(self, lock: ThreadLock) -> None: ... def __init__(self, lock: ThreadLock): ...
def __call__(self, *args, **kwargs) -> List[str]: ...
# ListCache()
def __iter__(self) -> "ListCache": ...
def __next__(self) -> str: ...
# support for x in ListCache
def __bool__(self) -> bool: ...
# True if have cache
def __getitem__(self, item: int) -> str: ...
# ListCache[int]
def append(self, value: Union[str, Iterable[str]]): ... def append(self, value: Union[str, Iterable[str]]): ...
# ListCache.append('abc' | ['abc']) def __getitem__(self, item) -> str: ...
def __call__(self, *args, **kwargs) -> List[str]: ...
def __iter__(self): ...
def __next__(self): ...
def __bool__(self): ...
@property @property
def cache(self) -> List[str]: ... def cache(self): ...
# ListCache.cache def clear(self): ...
def clear(self) -> None: ...
# ListCache.clear()
class LogFileCache: class LogFileCache:
... """日志文件缓存"""
def __init__(self, file_conf: dict):
"""
:param file_conf: 日志文件配置
"""
def file_setup(self) -> None: ...
def end_thread(self) -> None:
"""结束日志写入进程,顺手把目前的缓存写入"""
def start_thread(self) -> None: ...
@property
def logfile_name(self) -> str: ...
@logfile_name.setter
def logfile_name(self, value: str) -> None: ...
def _log_file_time_write(self, thread: bool = False) -> None: ...
def write_logs(self, string: str, flush: bool = False) -> None: ...
class Logger: class Logger:
... """shenjack logger"""
def __init__(self,
name: str = 'root',
level: int = DEBUG,
file_conf: List[LogFileCache] = None,
colors: Dict[Union[int, str], Dict[str, str]] = None,
formats=None) -> None:
"""
配置模式: 使用 kwargs 配置
:param name: logger 名称 默认为 root
:param level: logging 输出等级 默认为 DEBUG(10)
:param file_conf: logger 的文件处理配置
:param colors: dict 颜色配置
:param formats: 格式化配置
"""
def add_file(self, handler: LogFileCache) -> Nones: ...
def remove_file(self, handler: LogFileCache) -> None: ...
def make_log(self, *values: object,
level: int,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def format_text(self, level: int, text: str, frame: Optional[FrameType]) -> str: ...
def trace(self, *values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def fine(self, *values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def debug(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def info(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def warning(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def error(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def fatal(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def test_logger(the_logger: Logger) -> None:
...
def get_key_from_dict(a_dict: Dict, key: Any, default: Any = None) -> Optional[Any]: ...
def format_str(text: str) -> str: ...
def len_without_color_maker(text: str) -> int: ...
def gen_file_conf(file_name: str,
file_level: int = DEBUG,
file_mode: str = 'a',
file_encoding: str = 'utf-8',
file_cache_len: int = 10,
file_cache_time: Union[int, float] = 1) -> dict:
"""
生成一个文件配置
:param file_name: 日志文件名
:param file_level: 日志文件记录级别
:param file_mode: 文件模式
:param file_encoding: 文件编码
:param file_cache_len: 文件缓存长度
:param file_cache_time: 文件缓存时间
:return: 生成的配置
"""
return {'file_name': file_name,
'level': file_level,
'mode': file_mode,
'encoding': file_encoding,
'cache_len': file_cache_len,
'cache_time': file_cache_time}
def gen_color_conf(color_name: str = None, **colors) -> dict: ...
def logger_with_default_settings(name: str,
level: int = DEBUG,
file_conf: dict = None,
colors: dict = None,
formats: dict = None) -> Logger:
return Logger(name=name,
level=level,
file_conf=[LogFileCache(gen_file_conf(**file_conf))],
colors=gen_color_conf(**colors),
formats=logger_configs['Formatter'].copy().update(formats))
def add_file_config(conf_name: str,
file_name: str,
file_level: int = DEBUG,
file_mode: str = 'a',
file_encoding: str = 'utf-8',
file_cache_len: int = 10,
file_cache_time: Union[int, float] = 1) -> None:
"""
logger config 里添加一个文件配置
:param conf_name: 文件配置名称
:param file_name: 日志文件名
:param file_level: 日志文件记录级别
:param file_mode: 文件模式
:param file_encoding: 文件编码
:param file_cache_len: 文件缓存长度
:param file_cache_time: 文件缓存时间
:return: None
"""
logger_configs['File'][conf_name] = {'file_name': file_name,
'level': file_level,
'mode': file_mode,
'encoding': file_encoding,
'cache_len': file_cache_len,
'cache_time': file_cache_time}
def get_logger(name: str = 'root') -> Logger: def get_logger(name: str = 'root') -> Logger:
... """
此函数用于从 global_config 中取出对应的配置建立一个相应的 logger
:param name: logger的名称 默认为 root
:return: 创建好的 logger
"""
def test_logger(the_logger: Logger) -> None: ...

View File

@ -11,7 +11,7 @@
import re import re
import os import os
import time import time
import cython import enum
import atexit import atexit
import inspect import inspect
import threading import threading
@ -59,6 +59,21 @@ cdef int ALL = NOTSET
cdef int TRACE = 5 cdef int TRACE = 5
cdef int FINE = 7 cdef int FINE = 7
class LoggingLevel(enum.IntEnum):
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
FINE = 7
TRACE = 5
NOTSET = 0
ALL = NOTSET
cdef dict level_name_map = { cdef dict level_name_map = {
ALL: 'ALL', # NOTSET ALL: 'ALL', # NOTSET
TRACE: 'TRACE', TRACE: 'TRACE',
@ -257,8 +272,8 @@ class LogFileCache:
def file_setup(self): def file_setup(self):
cdef int cache_time = 0 cdef int cache_time = 0
cdef str file_type = self.logfile_name[self.logfile_name.rfind('.'):] cdef char file_type = self.logfile_name[self.logfile_name.rfind('.'):]
cdef str file_pure_name = self.logfile_name[:self.logfile_name.rfind('.')] cdef char file_pure_name = self.logfile_name[:self.logfile_name.rfind('.')]
while os.path.isfile(self.logfile_name): while os.path.isfile(self.logfile_name):
cache_time += 1 cache_time += 1
self.logfile_name = f'{file_pure_name}-{cache_time}{file_type}' self.logfile_name = f'{file_pure_name}-{cache_time}{file_type}'

View File

@ -10,6 +10,7 @@
import re import re
import os import os
import time import time
import enum
import atexit import atexit
import inspect import inspect
import threading import threading
@ -56,6 +57,21 @@ ALL = NOTSET
TRACE = 5 TRACE = 5
FINE = 7 FINE = 7
class LoggingLevel(enum.IntEnum):
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
FINE = 7
TRACE = 5
NOTSET = 0
ALL = NOTSET
level_name_map = { level_name_map = {
ALL: 'ALL', # NOTSET ALL: 'ALL', # NOTSET
TRACE: 'TRACE', TRACE: 'TRACE',

393
libs/utils/py_logger.pyi Normal file
View File

@ -0,0 +1,393 @@
"""
:author shenjackyuanjie
:contact 3695888:qq.com
"""
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
import re
import os
import time
import enum
import atexit
import inspect
import threading
from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, FATAL
from types import FrameType
from typing import Optional, Union, Dict, Iterable, Tuple, Any, List
os.system('')
# print(os.path.abspath(os.curdir))
# 如果想要直接使用 logger 来 logging
# 直接调用 logger.debug() 即可
# 默认配置会有
# ----------
# 配置方式一
# 直接使用 logger.Logger()
# 将会创建一个空 logger
# 可以自行通过
# 配置方式二
color_reset_suffix = "\033[0m"
""" 只是用来重置颜色的后缀 """
re_find_color_code = r'\033\[[^\f\n\r\t\vm]*m'
re_color_code = re.compile(re_find_color_code)
"""
OFF > FATAL > ERROR > WARN > INFO > FINE > FINER > DEBUG > TRACE > ALL
logging.py
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
"""
ALL = NOTSET
TRACE = 5
FINE = 7
class LoggingLevel(enum.IntEnum):
""" 存储 logger 级别的 enum 类"""
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
FINE = 7
TRACE = 5
NOTSET = 0
ALL = NOTSET
level_name_map = {
ALL: 'ALL', # NOTSET
TRACE: 'TRACE',
FINE: 'FINE',
DEBUG: 'DEBUG',
INFO: 'INFO',
WARNING: 'WARNING', # WARN
ERROR: 'ERROR',
FATAL: 'FATAL'
}
name_level_map = {
'NOTSET': ALL,
'ALL': ALL,
'TRACE': TRACE,
'FINE': FINE,
'DEBUG': DEBUG,
'INFO': INFO,
'WARNING': WARNING,
'WARN': WARNING,
'ERROR': ERROR,
'CRITICAL': FATAL,
'FATAL': FATAL
}
logger_configs = {
'Logger': {
'root': {
'level': TRACE,
'color': 'main_color',
'file': 'main_log_file',
},
'client': {
'level': TRACE,
'color': 'main_color',
# 'file': 'main_log_file',
},
'server': {
'level': TRACE,
'color': 'DiGua_color',
'file': 'main_log_file',
},
},
'Color': {
'main_color': {
'file_time': '\033[38;2;201;222;56m',
'main_time': '\033[38;2;201;222;56m',
'file_name': '\033[38;2;0;255;180m',
'code_line': '\033[38;2;0;255;180m',
'logger': '\033[0m',
TRACE: {'info': '\033[38;2;138;173;244m', 'message': '\033[38;2;138;173;244m'},
FINE: {'info': '\033[35;48;2;44;44;54m', 'message': '\033[35m'},
DEBUG: {'info': '\033[38;2;133;138;149m', 'message': '\033[38;2;133;138;149m'},
INFO: {'info': '\033[0m', 'message': '\033[0m'},
WARNING: {'info': '\033[33m', 'message': '\033[33m'},
ERROR: {'info': '\033[31m', 'message': '\033[31m'},
FATAL: {'info': '\033[38;2;255;255;0;48;2;120;10;10m', 'message': '\033[38;2;255;255;0;48;2;120;10;10m'}
},
'DiGua_color': {
# catppuccin Macchiato
'file_time': '\033[38;2;238;212;159m',
'main_time': '\033[38;2;202;211;245m',
'file_name': '\033[38;2;139;213;202m',
'code_line': '\033[38;2;166;218;149m',
'logger': '\033[0m',
TRACE: {'info': '\033[38;2;138;173;244m', 'message': '\033[38;2;138;173;244m'},
FINE: {'info': '\033[38;2;198;160;246m', 'message': '\033[38;2;198;160;246m'},
DEBUG: {'info': '\033[38;2;133;138;149m', 'message': '\033[38;2;133;138;149m'},
INFO: {'info': '\033[0m', 'message': '\033[0m'},
WARNING: {'info': '\033[38;2;245;169;127m', 'message': '\033[38;2;245;169;127m'},
ERROR: {'info': '\033[38;2;237;135;150m', 'message': '\033[38;2;237;135;150m'},
FATAL: {'info': '\033[38;2;255;255;0;48;2;120;10;10m', 'message': '\033[38;2;255;255;0;48;2;120;10;10m', 'logger': '\033[38;2;245;189;230m'}
}
},
'File': {
'main_log_file': {
'mode': 'a',
'encoding': 'utf-8',
'level': TRACE,
'file_name': './logs/{file_time}_logs.md',
'cache_len': 10,
'cache_time': 1
},
},
'Formatter': {
'MESSAGE': {
'format': '[{main_time}] [{logger_name}] {level} | {file_name}:{code_line} | {message}'
},
'file_name': 'no frame',
'code_line': 'no frame',
'file_time': {'strftime': '%Y-%m-%d %H-%M'},
'main_time': {'strftime': '%Y-%m-%d %H-%M-%S:%%S'}, # %%S 三位毫秒
...: ...
}
}
class ThreadLock:
"""一个用来 with 的线程锁"""
def __init__(self, the_lock: threading.Lock, time_out: Union[float, int] = 1 / 60) -> None: ...
def __enter__(self): ...
def __exit__(self, exc_type, exc_val, exc_tb): ...
class ListCache:
"""一个线程安全的列表缓存"""
def __init__(self, lock: ThreadLock): ...
def append(self, value: Union[str, Iterable[str]]): ...
def __getitem__(self, item) -> str: ...
def __call__(self, *args, **kwargs) -> List[str]: ...
def __iter__(self): ...
def __next__(self): ...
def __bool__(self): ...
:property
def cache(self): ...
def clear(self): ...
class LogFileCache:
"""日志文件缓存"""
def __init__(self, file_conf: dict):
"""
:param file_conf: 日志文件配置
"""
def file_setup(self) -> None: ...
def end_thread(self) -> None:
"""结束日志写入进程,顺手把目前的缓存写入"""
def start_thread(self) -> None: ...
:property
def logfile_name(self) -> str: ...
:logfile_name.setter
def logfile_name(self, value: str) -> None: ...
def _log_file_time_write(self, thread: bool = False) -> None: ...
def write_logs(self, string: str, flush: bool = False) -> None: ...
class Logger:
"""shenjack logger"""
def __init__(self,
name: str = 'root',
level: int = DEBUG,
file_conf: List[LogFileCache] = None,
colors: Dict[Union[int, str], Dict[str, str]] = None,
formats=None) -> None:
"""
配置模式: 使用 kwargs 配置
:param name: logger 名称 默认为 root
:param level: logging 输出等级 默认为 DEBUG(10)
:param file_conf: logger 的文件处理配置
:param colors: dict 颜色配置
:param formats: 格式化配置
"""
def add_file(self, handler: LogFileCache) -> Nones: ...
def remove_file(self, handler: LogFileCache) -> None: ...
def make_log(self, *values: object,
level: int,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def format_text(self, level: int, text: str, frame: Optional[FrameType]) -> str: ...
def trace(self, *values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def fine(self, *values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def debug(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def info(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def warning(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def error(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def fatal(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False,
frame: Optional[FrameType] = None) -> None: ...
def get_key_from_dict(a_dict: Dict, key: Any, default: Any = None) -> Optional[Any]: ...
def format_str(text: str) -> str: ...
def len_without_color_maker(text: str) -> int: ...
def gen_file_conf(file_name: str,
file_level: int = DEBUG,
file_mode: str = 'a',
file_encoding: str = 'utf-8',
file_cache_len: int = 10,
file_cache_time: Union[int, float] = 1) -> dict:
"""
生成一个文件配置
:param file_name: 日志文件名
:param file_level: 日志文件记录级别
:param file_mode: 文件模式
:param file_encoding: 文件编码
:param file_cache_len: 文件缓存长度
:param file_cache_time: 文件缓存时间
:return: 生成的配置
"""
return {'file_name': file_name,
'level': file_level,
'mode': file_mode,
'encoding': file_encoding,
'cache_len': file_cache_len,
'cache_time': file_cache_time}
def gen_color_conf(color_name: str = None, **colors) -> dict: ...
def logger_with_default_settings(name: str,
level: int = DEBUG,
file_conf: dict = None,
colors: dict = None,
formats: dict = None) -> Logger:
return Logger(name=name,
level=level,
file_conf=[LogFileCache(gen_file_conf(**file_conf))],
colors=gen_color_conf(**colors),
formats=logger_configs['Formatter'].copy().update(formats))
def add_file_config(conf_name: str,
file_name: str,
file_level: int = DEBUG,
file_mode: str = 'a',
file_encoding: str = 'utf-8',
file_cache_len: int = 10,
file_cache_time: Union[int, float] = 1) -> None:
"""
logger config 里添加一个文件配置
:param conf_name: 文件配置名称
:param file_name: 日志文件名
:param file_level: 日志文件记录级别
:param file_mode: 文件模式
:param file_encoding: 文件编码
:param file_cache_len: 文件缓存长度
:param file_cache_time: 文件缓存时间
:return: None
"""
logger_configs['File'][conf_name] = {'file_name': file_name,
'level': file_level,
'mode': file_mode,
'encoding': file_encoding,
'cache_len': file_cache_len,
'cache_time': file_cache_time}
def get_logger(name: str = 'root') -> Logger:
"""
此函数用于从 global_config 中取出对应的配置建立一个相应的 logger
:param name: logger的名称 默认为 root
:return: 创建好的 logger
"""
def test_logger(the_logger: Logger) -> None: ...

View File

@ -12,11 +12,9 @@ gitee: @shenjackyuanjie
""" """
import os import os
import cProfile import unittest
os.chdir('..') os.chdir('../../..')
os.chdir('..')
os.chdir('..')
from client.guis.format import html from client.guis.format import html
@ -31,15 +29,11 @@ try_texts = [
] ]
def main_test():
for text in try_texts: class HtmlFormatTest(unittest.TestCase):
print(text) def test1_format_texts(self):
print(html.decode_text2HTML(text)) self.assertEqual(html.decode_text2HTML('明天天气很好'), '<font face="" color=white>明天天气很好</font>')
print('------')
check = True if __name__ == '__main__':
if check: unittest.main()
cProfile.run('main_test()', sort='calls')
else:
main_test()

15
test/utils/loggers.py Normal file
View File

@ -0,0 +1,15 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
import unittest
class LoggerTest(unittest.TestCase):
def check_a_logger(self, logger):
...
def test_1_py_logger(self):
...