继续完善logger

This commit is contained in:
shenjack 2022-09-04 13:02:58 +08:00
parent 029fdb1f47
commit fc734a62cb
8 changed files with 135 additions and 401 deletions

View File

@ -14,7 +14,6 @@ gitee: @shenjackyuanjie
# 单独导入的(或者就这一个有用的) # 单独导入的(或者就这一个有用的)
from .delivery import Delivery from .delivery import Delivery
# lazy之后之前全部导入的(太多了写不动__all__了) # lazy之后之前全部导入的(太多了写不动__all__了
from .calculation import *
from .scientific_unit import * from .scientific_unit import *

View File

@ -1,307 +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
"""
import math
import decimal
from typing import List, Optional, Union
from decimal import Decimal
# linear_algebra
def C_R_P(position: List, degrees: List): # stand for calculation
"""
very thanks for lenny from pyglet developer
https://github.com/LennyPhoenix
this part of code is write by him
"""
radians = degrees * (math.pi / 180)
cos = math.cos(radians)
sin = math.sin(radians)
rotated_pos = (position[0] * cos - position[1] * sin, position[0] * sin + position[1] * cos)
return rotated_pos
"""
Physics calculation
"""
def is_decimal(A: any) -> bool:
if isinstance(A, decimal.Decimal):
return False
else:
return True
def F_D(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A / B
def F_Mu(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A * B
def F_Mi(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A - B
def F_A(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A + B
def D_C(listA: list, listB: list): # stand for Duplicate check
"""
usage:\n
input two list\n
the fun will do duplicate check and sort then\n
the fun won't return any thing just change the list now
"""
for unit in listB:
if unit in listA:
listA.remove(unit)
listB.remove(unit)
else:
continue
listA.sort()
listB.sort()
def S_C_float_check(SC): # stand for Scientific notation's float check
"""
formats:
SC list format:docs.basic_config.json:basic_number"""
while SC[0] >= 10:
SC[0] = F_D(SC[0], 10)
SC[1] += 1
while SC[0] < 1:
SC[0] = F_Mu(SC[0], 10)
SC[1] -= 1
def S_N_M(*SN): # stand for Scientific notation multiple
"""
formats:
A & B & C list format:docs.basic_config.json:basic_number"""
if len(SN) < 2:
raise TypeError('it need more than 1!')
elif len(SN) == 2:
return __S_N_M(SN[0], SN[1])
else:
R = __S_N_M(SN[0], SN[1])
for A in SN[2:]:
R = __S_N_M(R, A)
return R
def __S_N_M(A, B):
"""
formats:
A & B list format:docs.basic_config.json:basic_number"""
R = [F_Mu(A[0], B[0]), A[1] + B[1]]
S_C_float_check(R)
Unit1, Unit2 = A[2] + B[2], A[3] + B[3]
if Unit1 is None:
Unit1 = []
D_C(Unit1, Unit2)
R += [Unit1, Unit2]
return R
def S_N_D(A, B): # stand for Scientific notation divided
"""
formats:
A & B list format:docs.basic_config:basic_number"""
R = [F_D(A[0], B[0]), A[1] - B[1]]
S_C_float_check(R)
Unit1, Unit2 = A[2] + B[3], A[3] + B[2]
if Unit1 is None:
Unit1 = []
D_C(Unit1, Unit2)
R += [Unit1, Unit2]
return R
def G_C(M, m, R, G): # stand for gravity calculation
"""
formats:
M : ship's mass
m : planet's mass
R : distance to the planet
G : Gravitational constant
M & m & R format: docs.basic_config:basic_number
"""
g = basic_force()
A = S_N_M(M, m, G)
g = S_N_D(A, S_N_M(R, R))
return g
def distance(A, B):
"""
formats:
A & B format: docs.basic_config:basic_poi
"""
poi_dis = basic_poi()
for x in A, B:
x = decimal.Decimal(str(x))
xd = A[0] - B[0]
yd = A[1] - B[1]
poi_dis[0] = xd
poi_dis[1] = yd
# 勾股定理
poi_dis[0] **= 2
poi_dis[1] **= 2
poi_dis.append(poi_dis[0] + poi_dis[1])
poi_dis[2] **= 0.5
return poi_dis[2]
def _BasicNumber(int_num=0, float_num=1, unit1=None, unit2=None) -> list:
if unit1 is None:
unit1 = []
if unit2 is None:
unit2 = []
if is_decimal(float_num): # is decimal class?
return [int_num, float_num, unit1, unit2] # is just return
else:
return [int_num, decimal.Decimal(str(float_num)), unit1, unit2] # no create a decimal class
def BasicNumber(int_num=0, float_num=1, unit1=None, unit2=None, num=1) -> list:
numbers = []
if num > 1:
for x in range(0, num, 1):
numbers.append(_BasicNumber(int_num, float_num, unit1, unit2))
elif num == 1:
return _BasicNumber(int_num, float_num, unit1, unit2)
else: # num < 1
raise TypeError('you should give me a num with >= 1!')
return numbers
class BasicNumberClass:
def __init__(self, int_num=0, float_num=1, unit1=None, unit2=None):
self.int = int_num
self.float = decimal.Decimal(str(float_num))
if unit1:
self.units1 = unit1
else:
self.units1 = []
if unit2:
self.units2 = unit2
else:
self.units2 = []
def sort(self):
self.units1.sort()
self.units2.sort()
def float_int_check(self, int_=None, float_=None):
if not int_:
int_ = 1
if not float_:
float_ = decimal.Decimal(1.0)
while float_ > 10:
float_ / 10
int_ + 1
else:
while float_ < 0.1:
float_ * 10
int_ - 1
return [int_, float_]
def units(self) -> list or bool:
if (self.units1 == []) and (self.units2 == []):
return None
data = self.units1
data.append(self.units2)
return data
def __str__(self):
return [self.float, self.int, self.units1, self.units2]
def __add__(self, other):
o_type = type(other)
if o_type == type(self):
self.sort()
other.sort()
if self.units() == other.units():
self_num = self.float * (10 ** self.int)
other_num = other.float * (10 ** other.float)
r_float = self_num + other_num
check = self.float_int_check(1, r_float)
self.float = check[0]
self.int = check[1]
elif o_type == type(decimal.Decimal('1.0')) and not self.units():
pass
def __radd__(self, other):
self.__add__(self)
def __mul__(self, other):
pass
def __rmul__(self, other):
self.__mul__(self)
def __truediv__(self, other):
pass
def basic_poi(poi_type=None) -> list:
if poi_type is None:
return BasicNumber(unit1='m', num=2)
if poi_type == 'chunk':
return [BasicNumber(unit1='chunk', num=2), BasicNumber(unit1='m', num=2)]
def basic_force() -> list:
return BasicNumber(unit1='N', num=2)
class ScientificNumber:
"""
A class of Scientific notation
give float and integer and unit
"""
def __init__(self,
小数: Union[float, Decimal] = 1.0,
指数: int = 0,
乘单位: list = list,
除单位: list = list):
if not isinstance(小数, Decimal):
self.小数 = Decimal(小数)
else:
self.小数 = 小数
self.指数 = 指数
self.乘单位 = 乘单位
self.除单位 = 除单位
self.check()
def check(self):
while self.小数 > 10:
self.小数 /= 10
self.指数 += 1
while self.小数 < 1:
self.小数 *= 10
self.指数 -= 1
self.除单位.sort()
self.乘单位.sort()

View File

@ -4,25 +4,17 @@
""" """
import re import re
import os import os
import sys
import time import time
import atexit import atexit
import inspect import inspect
import threading import threading
# from inspect import F
from os import PathLike
from time import strftime from time import strftime
from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, FATAL from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, FATAL
from types import FrameType from types import FrameType
from typing import Optional, Union, Dict, Iterable, Tuple, Any, List, Callable from typing import Optional, Union, Dict, Iterable, Tuple, Any
print(os.path.abspath(os.curdir)) # print(os.path.abspath(os.curdir))
os.chdir('../../')
sys.path.append('D:/githubs/DR')
sys.path.append(os.path.abspath('./Difficult_Rocket'))
from Difficult_Rocket.utils.thread import ThreadLock
# 如果想要直接使用 logger 来 logging # 如果想要直接使用 logger 来 logging
# 直接调用 logger.debug() 即可 # 直接调用 logger.debug() 即可
@ -101,9 +93,24 @@ logger_configs = {
}, },
'Color': { 'Color': {
'main_color': { 'main_color': {
'date': '\033[38;2;201;222;56m', 'file_time': '\033[38;2;201;222;56m',
'file': '\033[38;2;0;255;180m', 'main_time': '\033[38;2;201;222;56m',
'line': '\033[38;2;0;255;180m', '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;40;40;70m'},
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': {
'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', 'logger': '\033[0m',
TRACE: {'info': '\033[34;48;2;44;44;54m', 'message': '\033[34;48;2;40;40;70m'}, TRACE: {'info': '\033[34;48;2;44;44;54m', 'message': '\033[34;48;2;40;40;70m'},
FINE: {'info': '\033[35;48;2;44;44;54m', 'message': '\033[35m'}, FINE: {'info': '\033[35;48;2;44;44;54m', 'message': '\033[35m'},
@ -119,13 +126,17 @@ logger_configs = {
'mode': 'a', 'mode': 'a',
'encoding': 'utf-8', 'encoding': 'utf-8',
'level': TRACE, 'level': TRACE,
'file_name': './logs/{file_time}_logs.md' 'file_name': './logs/{file_time}_logs.md',
'cache_len': 10,
'cache_time': 1
}, },
}, },
'Formatter': { 'Formatter': {
'MESSAGE': { 'MESSAGE': {
'format': '[{main_time}] [{logger_name}] {level} | {file_name}:{code_line} | {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'}, 'file_time': {'strftime': '%Y-%m-%d %H-%M'},
'main_time': {'strftime': '%Y-%m-%d %H-%M-%S:%%S'}, # %%S 三位毫秒 'main_time': {'strftime': '%Y-%m-%d %H-%M-%S:%%S'}, # %%S 三位毫秒
...: ... ...: ...
@ -133,6 +144,23 @@ logger_configs = {
} }
class ThreadLock:
def __init__(self, the_lock: threading.Lock, time_out: Union[float, int] = 1 / 60) -> None:
self.lock = the_lock
self.time_out = time_out
def __enter__(self):
self.lock.acquire(timeout=self.time_out)
if not self.lock.locked():
raise RuntimeError(f'Lock time Out with {self.time_out}')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self.lock.locked():
self.lock.release()
class ListCache: class ListCache:
"""一个线程安全的列表缓存""" """一个线程安全的列表缓存"""
@ -189,24 +217,23 @@ class ListCache:
class LogFileCache: class LogFileCache:
"""日志文件缓存""" """日志文件缓存"""
def __init__(self, file_conf: Dict, flush_time: Optional[Union[int, float]] = 1, log_cache_lens_max: int = 10): def __init__(self, file_conf: dict, ):
""" """
@param file_conf: 日志文件配置 @param file_conf: 日志文件配置
@param flush_time: 刷新日志缓存写入文件的时长间隔
@param log_cache_lens_max: 日志缓存在自动写入前的最大缓存长度
""" """
# 配置相关 # 配置相关
self._logfile_name = os.path.abspath(format_str(file_conf['file_name'])) # log 文件名称 self._logfile_name = os.path.abspath(format_str(file_conf['file_name'])) # log 文件名称
self.level = get_key_from_dict(file_conf, 'level', DEBUG) self.level = get_key_from_dict(file_conf, 'level', DEBUG)
self.file_conf = file_conf self.file_conf = file_conf
self.flush_time = flush_time # 缓存刷新时长 self.flush_time = file_conf['cache_time'] # 缓存刷新时长
self.cache_entries_num = log_cache_lens_max self.cache_entries_num = file_conf['cache_len']
self.started = False self.started = True
self.running = False
# 同步锁 # 同步锁
self.cache_lock = threading.Lock() # 主锁 self.cache_lock = threading.Lock() # 主锁
self.time_limit_lock = ThreadLock(self.cache_lock, time_out=1 / 60) # 直接用于 with 的主锁 self.time_limit_lock = ThreadLock(self.cache_lock, time_out=1 / 60) # 直接用于 with 的主锁
self.threaded_write = threading.Timer(1, self._log_file_time_write) # 基于 timer 的多线程 self.threaded_write = threading.Timer(1, self._log_file_time_write, kwargs={'thread': True}) # 基于 timer 的多线程
# 日志缓存表 # 日志缓存表
self.log_cache = ListCache(self.time_limit_lock) self.log_cache = ListCache(self.time_limit_lock)
self.file_setup() self.file_setup()
@ -222,7 +249,9 @@ class LogFileCache:
def end_thread(self) -> None: def end_thread(self) -> None:
"""结束日志写入进程,顺手把目前的缓存写入""" """结束日志写入进程,顺手把目前的缓存写入"""
self.cache_lock.acquire(blocking=True) self.cache_lock.acquire(blocking=True)
if self.running:
self.threaded_write.cancel() self.threaded_write.cancel()
self.running = False
self.started = False self.started = False
self._log_file_time_write() self._log_file_time_write()
atexit.unregister(self.end_thread) atexit.unregister(self.end_thread)
@ -230,20 +259,22 @@ class LogFileCache:
def start_thread(self) -> None: def start_thread(self) -> None:
self.threaded_write.start() self.threaded_write.start()
self.started = True self.started = True
self.running = True
atexit.register(self.end_thread) atexit.register(self.end_thread)
@property @property
def logfile_name(self) -> PathLike: def logfile_name(self) -> str:
self._logfile_name: PathLike self._logfile_name: str
return self._logfile_name return self._logfile_name
@logfile_name.setter @logfile_name.setter
def logfile_name(self, value: PathLike) -> None: def logfile_name(self, value: str) -> None:
with self.time_limit_lock: with self.time_limit_lock:
self._logfile_name = value self._logfile_name = value
def _log_file_time_write(self) -> None: def _log_file_time_write(self, thread: bool = False) -> None:
"""使用 threading.Timer 调用的定时写入日志文件的函数""" """使用 threading.Timer 调用的定时写入日志文件的函数"""
print(f'write! {thread}{self.log_cache.cache}')
if self.log_cache: if self.log_cache:
with self.time_limit_lock: with self.time_limit_lock:
if self.log_cache: if self.log_cache:
@ -252,6 +283,8 @@ class LogFileCache:
mode=get_key_from_dict(self.file_conf, 'mode', 'a')) as log_file: mode=get_key_from_dict(self.file_conf, 'mode', 'a')) as log_file:
log_file.writelines(self.log_cache.cache.copy()) log_file.writelines(self.log_cache.cache.copy())
self.log_cache.clear() self.log_cache.clear()
if thread:
self.running = False
def write_logs(self, string: str, flush: bool = False) -> None: def write_logs(self, string: str, flush: bool = False) -> None:
self.log_cache.append(string) self.log_cache.append(string)
@ -260,25 +293,36 @@ class LogFileCache:
return None return None
if flush: if flush:
self._log_file_time_write() self._log_file_time_write()
if self.started and not self.running:
self.threaded_write = threading.Timer(1, self._log_file_time_write, kwargs={'thread': True}) # 基于 timer 的多线程
self.threaded_write.start()
self.running = True
class Logger: class Logger:
"""shenjack logger""" """shenjack logger"""
def __init__(self, name: str = None, level: int = None, file_conf: Dict = None, colors: Dict[Union[int, str], Dict[str, str]] = None, formats=None, **kwargs) -> None: def __init__(self,
name: str = None,
level: int = None,
file_conf: Dict = None,
colors: Dict[Union[int, str], Dict[str, str]] = None,
formats=None) -> None:
""" """
配置模式: 使用 kwargs 配置 配置模式: 使用 kwargs 配置
@param name: logger 名称 默认为 root @param name: logger 名称 默认为 root
@param level: logging 输出等级 默认为 DEBUG(10) @param level: logging 输出等级 默认为 DEBUG(10)
@param file_name: logging 写入文件名称 默认为 None(不写入) @param file_conf: logger 的文件处理配置
@param colors: dict 颜色配置
@param formats: 格式化配置
""" """
self.name = name or 'root' self.name = name or 'root'
self.level = level if level is not None else DEBUG self.level = level if level is not None else DEBUG
self.colors = colors or logger_configs['Color']['main_color'] self.colors = colors or logger_configs['Color']['main_color']
self.formats = formats or logger_configs['Formatter'] self.formats = formats or logger_configs['Formatter'].copy()
self.formats['logger_name'] = f'{self.colors["logger"]}{self.name}{color_reset_suffix}'
if file_conf: if file_conf:
self.file_cache = LogFileCache(file_conf=file_conf) self.file_cache = LogFileCache(file_conf=file_conf)
self.file_cache.start_thread()
else: else:
self.file_cache = False self.file_cache = False
self.warn = self.warning self.warn = self.warning
@ -293,6 +337,7 @@ class Logger:
# self.file_cache.level if self.file_cache else False, # self.file_cache.level if self.file_cache else False,
# level >= self.level, # level >= self.level,
# self.file_cache and (level >= self.file_cache.level)) # self.file_cache and (level >= self.file_cache.level))
self.file_cache: Union[bool, LogFileCache]
if level < self.level and self.file_cache and (level < self.file_cache.level): if level < self.level and self.file_cache and (level < self.file_cache.level):
return None return None
if not frame: if not frame:
@ -311,26 +356,20 @@ class Logger:
return None return None
def format_text(self, level: int, text: str, frame: Optional[FrameType]) -> str: def format_text(self, level: int, text: str, frame: Optional[FrameType]) -> str:
from Difficult_Rocket import DR_option, DR_runtime
level_with_color = f"[{self.colors[level]['info']}{level_name_map[level]}{color_reset_suffix}]" level_with_color = f"[{self.colors[level]['info']}{level_name_map[level]}{color_reset_suffix}]"
level_with_color = f"{level_with_color}{' ' * (9 - len_without_color_maker(level_with_color))}" level_with_color = f"{level_with_color}{' ' * (9 - len_without_color_maker(level_with_color))}"
formats = self.formats.copy() formats = self.formats.copy()
formats.pop('MESSAGE') if frame is not None:
if frame is None: formats['file_name'] = f"{self.colors['file_name']}{os.path.split(frame.f_code.co_filename)[-1]}{color_reset_suffix}"
formats['file_name'] = 'no frame' formats['code_line'] = f"{self.colors['code_line']}{frame.f_lineno}{color_reset_suffix}"
formats['code_line'] = 'no frame'
else:
formats['file_name'] = f"{self.colors['file']}{os.path.split(frame.f_code.co_filename)[-1]}{color_reset_suffix}"
formats['code_line'] = f"{self.colors['line']}{frame.f_lineno}{color_reset_suffix}"
now_time = str(time.time()) now_time = str(time.time())
for key, value in formats.items(): for key, value in formats.items():
if isinstance(value, dict): if isinstance(value, dict):
if 'strftime' in value: if 'strftime' in value:
value['strftime']: str value['strftime']: str
formats[key] = f"{self.colors['date']}{strftime(value['strftime'].replace('%%S', now_time[now_time.find('.') + 1:now_time.find('.') + 4]))}{color_reset_suffix}" formats[key] = f"{self.colors[key]}{strftime(value['strftime'].replace('%%S', now_time[now_time.find('.') + 1:now_time.find('.') + 4]))}{color_reset_suffix}"
print_text = self.formats['MESSAGE']['format'].format(level_with_color=level_with_color, print_text = self.formats['MESSAGE']['format'].format(level_with_color=level_with_color,
level=level_with_color, message=text, level=level_with_color, message=text,
logger_name=self.name,
**formats) **formats)
return print_text return print_text
@ -420,8 +459,36 @@ def logging_color() -> Dict:
return {'info': ..., 'message': ...} return {'info': ..., 'message': ...}
def setup_logger() -> None: 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:
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(**colors) -> dict:
default_color = logger_configs['Color']['main_color'].copy()
default_color.update(colors)
return default_color
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=gen_file_conf(**file_conf),
colors=gen_color_conf(**colors),
formats=logger_configs['Formatter'].copy().update(formats))
def add_dict_config_to_global(some_dict: Union[dict, list, str], name: str) -> dict: def add_dict_config_to_global(some_dict: Union[dict, list, str], name: str) -> dict:
@ -437,15 +504,6 @@ def add_dict_config_to_global(some_dict: Union[dict, list, str], name: str) -> d
return logger_configs # 修改过的 logger 配置 return logger_configs # 修改过的 logger 配置
def add_kwargs_to_global(**kwargs) -> dict:
"""
@param kwargs: 你要改的 logger配置
@return: 修改过的 logger 配置
"""
...
def get_logger(name: str = 'root') -> Logger: def get_logger(name: str = 'root') -> Logger:
""" """
此函数用于从 global_config 中取出对应的配置建立一个相应的 logger 此函数用于从 global_config 中取出对应的配置建立一个相应的 logger
@ -456,41 +514,38 @@ def get_logger(name: str = 'root') -> Logger:
the_config = logger_configs['Logger'][name] the_config = logger_configs['Logger'][name]
else: else:
the_config = logger_configs['Logger']['root'] the_config = logger_configs['Logger']['root']
a_logger = Logger(name=name, return Logger(name=name,
level=the_config['level'], level=the_config['level'],
file_conf=logger_configs['File'][the_config['file']] if 'file' in the_config else None, file_conf=logger_configs['File'][the_config['file']] if 'file' in the_config else None,
colors=logger_configs['Color'][get_key_from_dict(the_config, 'color', 'main_color')], colors=logger_configs['Color'][get_key_from_dict(the_config, 'color', 'main_color')],
formats=logger_configs['Formatter']) formats=logger_configs['Formatter'])
return a_logger
def test_logger(the_logger: Logger):
the_logger.trace('tracing')
the_logger.fine('some fine!')
the_logger.debug('debugging')
the_logger.info("Hello World!!")
the_logger.warn('warning')
the_logger.error('error haaaa')
the_logger.fatal('oh no')
if __name__ == "__main__": if __name__ == "__main__":
os.chdir('githubs/DR') os.chdir('D:/githubs/DR')
# 在这里可以使用 add_kwargs_to_global
logger = Logger(name="Main", level=NOTSET) logger = Logger(name="Main", level=NOTSET)
for x in range(5): logger.info('my name is:', logger.name)
logger.trace('tracing')
logger.fine('some fine!')
logger.debug('debugging')
logger.info("Hello World!!")
logger.warn('warning')
logger.error('error haaaa')
logger.fatal('oh no')
a_logger = get_logger('client') a_logger = get_logger('client')
a_logger.trace('tracing') a_logger.trace('tracing')
# time.sleep(5) time.sleep(1.1)
a_logger.fine('some fine!') a_logger.fine('some fine!')
a_logger.debug('debugging') a_logger.debug('debugging')
# time.sleep(5) time.sleep(1.1)
a_logger.info("Hello World!!") a_logger.info("Hello World!!")
a_logger.warn('warning') a_logger.warn('warning')
a_logger.error('error haaaa') a_logger.error('error haaaa')
a_logger.fatal('oh no') a_logger.fatal('oh no')
logger.info('my name is:', logger.name)
for x in range(5): for x in range(5):
a_logger.trace('tracing') test_logger(logger)
a_logger.fine('some fine!') test_logger(a_logger)
a_logger.debug('debugging')
a_logger.info("Hello World!!")
a_logger.warn('warning')
a_logger.error('error haaaa')
a_logger.fatal('oh no')

View File

@ -16,13 +16,13 @@ import threading
from typing import Union from typing import Union
from threading import Lock from threading import Lock
from Difficult_Rocket import crash from Difficult_Rocket import DR_option, crash
from Difficult_Rocket.exception.threading import LockTimeOutError from Difficult_Rocket.exception.threading import LockTimeOutError
class Threads(threading.Thread): class Threads(threading.Thread):
def run(self): def run(self):
if crash.record_thread: if DR_option.record_thread:
crash.all_thread.append(self) crash.all_thread.append(self)
super().run() super().run()
@ -34,27 +34,14 @@ class ThreadLock:
self.time_out = time_out self.time_out = time_out
def __enter__(self): def __enter__(self):
# print('enter!')
self.lock.acquire(timeout=self.time_out) self.lock.acquire(timeout=self.time_out)
if not self.lock.locked(): if not self.lock.locked():
raise LockTimeOutError('') raise LockTimeOutError(f'Lock time Out with {self.time_out}')
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
if self.lock.locked(): if self.lock.locked():
self.lock.release() self.lock.release()
if (exc_type is None) and (exc_val is None) and (exc_tb is None):
# 没有出 bug
# print('exit with no error')
return None
else:
# 出 bug 了
# print(f'exit with error {exc_type} {exc_val}')
return None
# def __del__(self):
# print('del me!')
# self.__del__()
if __name__ == "__main__": if __name__ == "__main__":