Add | more formatter and some more Fix | type mis match sync pyglet Enhance | logger with Template add lib-not-dr as requirement sync pyglet sync pyglet Add | add lto=yes to nuitka_build just incase sync pyglet sync lib_not_dr Remove | external requirement lib-not-dr some logger sync lib-not-dr sync pyglet sync lib-not-dr sync lib-not-dr sync pyglet sync pyglet Fix | console thread been block Update DR rs and DR sdk sync lib not dr sync lib-not-dr sync lib-not-dr sync pyglet and lib-not-dr sync pyglet 0.1.8 sync lib not dr logger almost done? almost! sync pyglet (clicpboard support!) sync lib not dr sync lib not dr color code and sync pyglet do not show memory and progress building localy sync pyglet synclibs
268 lines
8.2 KiB
Python
268 lines
8.2 KiB
Python
# -------------------------------
|
|
# Difficult Rocket
|
|
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
# All rights reserved
|
|
# -------------------------------
|
|
|
|
import time
|
|
import inspect
|
|
from types import FrameType
|
|
from typing import List, Optional
|
|
|
|
from lib_not_dr.logger import LogLevel
|
|
from lib_not_dr.types.options import Options
|
|
from lib_not_dr.logger.structure import LogMessage
|
|
from lib_not_dr.logger.outstream import BaseOutputStream, StdioOutputStream
|
|
|
|
|
|
class Logger(Options):
|
|
name = 'Logger-v2'
|
|
|
|
outputs: List[BaseOutputStream] = [StdioOutputStream()]
|
|
|
|
log_name: str = 'root'
|
|
|
|
enable: bool = True
|
|
level: int = 20 # info
|
|
|
|
def log_for(self, level: int) -> bool:
|
|
"""
|
|
Check if logging is enabled for a specific level.
|
|
|
|
Args:
|
|
level (int): The logging level to check.
|
|
|
|
Returns:
|
|
bool: True if logging is enabled for the given level, False otherwise.
|
|
"""
|
|
return self.enable and level >= self.level
|
|
|
|
def add_output(self, output: BaseOutputStream) -> None:
|
|
"""
|
|
Add an output to the list of outputs.
|
|
|
|
Args:
|
|
output (BaseOutputStream): The output to be added.
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
self.outputs.append(output)
|
|
self.level = min(self.level, output.level)
|
|
|
|
def remove_output(self, output: BaseOutputStream) -> None:
|
|
"""
|
|
Removes the specified output from the list of outputs.
|
|
|
|
Args:
|
|
output (BaseOutputStream): The output to be removed.
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
self.outputs.remove(output)
|
|
self.level = max(self.level, *[output.level for output in self.outputs])
|
|
|
|
@property
|
|
def global_level(self) -> int:
|
|
"""
|
|
Get the global logging level.
|
|
|
|
Returns:
|
|
int: The global logging level.
|
|
"""
|
|
return self.level
|
|
|
|
@global_level.setter
|
|
def global_level(self, level: int) -> None:
|
|
"""
|
|
Set the global logging level.
|
|
|
|
Args:
|
|
level (int): The global logging level.
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
self.level = level
|
|
for output in self.outputs:
|
|
output.level = level
|
|
|
|
def make_log(self,
|
|
messages: List[str],
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
level: int = 20, # info
|
|
# log_time: Optional[float] = None,
|
|
# logger_name: str = 'root',
|
|
# logger_tag: Optional[str] = None,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
# 检查是否需要记录
|
|
if not self.log_for(level):
|
|
return
|
|
log_time = time.time_ns()
|
|
# 处理堆栈信息
|
|
if stack_trace is None:
|
|
# 尝试获取堆栈信息
|
|
if (stack := inspect.currentframe()) is not None:
|
|
# 如果可能 尝试获取上两层的堆栈信息
|
|
if (up_stack := stack.f_back) is not None:
|
|
if (upper_stack := up_stack.f_back) is not None:
|
|
stack_trace = upper_stack
|
|
else:
|
|
stack_trace = up_stack
|
|
else:
|
|
stack_trace = stack
|
|
|
|
message = LogMessage(messages=messages,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=level,
|
|
log_time=log_time,
|
|
logger_name=self.log_name,
|
|
logger_tag=tag,
|
|
stack_trace=stack_trace)
|
|
if level >= 30: # WARN
|
|
for output in self.outputs:
|
|
output.write_stderr(message)
|
|
else:
|
|
for output in self.outputs:
|
|
output.write_stdout(message)
|
|
# done?
|
|
# 20231106 00:06
|
|
|
|
@staticmethod
|
|
def get_logger_by_name(name: str) -> 'Logger':
|
|
"""
|
|
Get a logger by name.
|
|
|
|
Args:
|
|
name (str): The name of the logger.
|
|
|
|
Returns:
|
|
Logger: The logger with the specified name.
|
|
"""
|
|
return Logger(log_name=name)
|
|
|
|
def info(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.info):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.info,
|
|
stack_trace=stack_trace)
|
|
|
|
def trace(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.trace):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.trace,
|
|
stack_trace=stack_trace)
|
|
|
|
def fine(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.fine):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.fine,
|
|
stack_trace=stack_trace)
|
|
|
|
def debug(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.debug):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.debug,
|
|
stack_trace=stack_trace)
|
|
|
|
def warn(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.warn):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.warn,
|
|
stack_trace=stack_trace)
|
|
|
|
def error(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.error):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.error,
|
|
stack_trace=stack_trace)
|
|
|
|
def fatal(self,
|
|
*message,
|
|
tag: Optional[str] = None,
|
|
end: str = '\n',
|
|
split: str = ' ',
|
|
flush: bool = True,
|
|
stack_trace: Optional[FrameType] = None) -> None:
|
|
if not self.log_for(LogLevel.fatal):
|
|
return
|
|
self.make_log(messages=list(message),
|
|
tag=tag,
|
|
end=end,
|
|
split=split,
|
|
flush=flush,
|
|
level=LogLevel.fatal,
|
|
stack_trace=stack_trace)
|