Add and use LogLevel

This commit is contained in:
shenjack 2023-11-06 00:19:39 +08:00
parent 3775ef6d7a
commit ae3de0b4b7
Signed by: shenjack
GPG Key ID: 7B1134A979775551
7 changed files with 125 additions and 84 deletions

View File

@ -15,7 +15,7 @@ from lib_not_dr.logger.formatter import (StdFormatter,
if __name__ == '__main__': if __name__ == '__main__':
levels = (0, 2, 5, 7, 10, 30, 50, 90) levels = (0, 5, 7, 10, 20, 30, 40, 50)
log_message = LogMessage(messages=['Hello World!'], log_message = LogMessage(messages=['Hello World!'],
level=7, level=7,
@ -29,7 +29,7 @@ if __name__ == '__main__':
std_format = StdFormatter() std_format = StdFormatter()
std_format.default_template = "${log_time}|${logger_name}|${logger_tag}|${log_source}:${log_line}|${log_function}|${level}|${messages}" std_format.default_template = "${log_time}|${logger_name}|${logger_tag}|${log_source}:${log_line}|${log_function}|${level}|${messages}"
test_levels = (0, 2, 5, 7, 10, 30, 50, 90) test_levels = (0, 5, 7, 10, 20, 30, 40, 50)
print("with color") print("with color")

View File

@ -26,9 +26,11 @@ if __name__ == '__main__':
file_cache.write_stdout(log_message) file_cache.write_stdout(log_message)
stdio.write_stdout(log_message) stdio.write_stdout(log_message)
# wait for 10 sec # wait for 10 sec
print('wait for 11 sec') print('wait for 10 sec')
time.sleep(11) time.sleep(10)
print('finish') print('look at the ./logs/test.log (sleep 5 sec)')
time.sleep(5)
print('go on')
# write 10 lines # write 10 lines
for i in range(10): for i in range(10):

View File

@ -5,6 +5,8 @@
# ------------------------------- # -------------------------------
import sys import sys
from lib_not_dr.types.options import Options
COLOR_SUPPORT = True COLOR_SUPPORT = True
if sys.platform == "win32": if sys.platform == "win32":
@ -17,3 +19,15 @@ if sys.platform == "win32":
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
except OSError: # pragma: no cover except OSError: # pragma: no cover
COLOR_SUPPORT = False COLOR_SUPPORT = False
class LogLevel(Options):
name = 'LogLevel'
notset: int = 0
trace: int = 5
fine: int = 7
debug: int = 10
info: int = 20
warn: int = 30
error: int = 40
fatal: int = 50

View File

@ -9,6 +9,7 @@ from pathlib import Path
from string import Template from string import Template
from typing import List, Union, Optional, Dict, Tuple, TYPE_CHECKING from typing import List, Union, Optional, Dict, Tuple, TYPE_CHECKING
from lib_not_dr.logger import LogLevel
from lib_not_dr.types.options import Options from lib_not_dr.types.options import Options
from lib_not_dr.logger.structure import LogMessage, FormattingMessage from lib_not_dr.logger.structure import LogMessage, FormattingMessage
@ -120,24 +121,24 @@ class LevelFormatter(BaseFormatter):
level_get_higher: bool = True level_get_higher: bool = True
level_name_map = { level_name_map = {
0: 'NOTSET', LogLevel.notset: 'NOTSET',
5: 'TRACE', LogLevel.trace: 'TRACE',
7: 'FINE', LogLevel.fine: 'FINE',
10: 'DEBUG', LogLevel.debug: 'DEBUG',
20: 'INFO', LogLevel.info: 'INFO',
30: 'WARN', LogLevel.warn: 'WARN',
40: 'ERROR', LogLevel.error: 'ERROR',
50: 'FATAL' LogLevel.fatal: 'FATAL',
} }
name_level_map = { name_level_map = {
'NOTSET': 0, 'NOTSET': LogLevel.notset,
'TRACE': 5, 'TRACE': LogLevel.trace,
'FINE': 7, 'FINE': LogLevel.fine,
'DEBUG': 10, 'DEBUG': LogLevel.debug,
'INFO': 20, 'INFO': LogLevel.info,
'WARN': 30, 'WARN': LogLevel.warn,
'ERROR': 40, 'ERROR': LogLevel.error,
'FATAL': 50 'FATAL': LogLevel.fatal,
} }
@classmethod @classmethod
@ -266,7 +267,7 @@ if __name__ == '__main__':
std_format = StdFormatter() std_format = StdFormatter()
std_format.default_template = "${log_time}|${logger_name}|${logger_tag}|${log_source}:${log_line}|${log_function}|${level}|${messages}" std_format.default_template = "${log_time}|${logger_name}|${logger_tag}|${log_source}:${log_line}|${log_function}|${level}|${messages}"
test_levels = (0, 2, 5, 7, 10, 30, 50, 90) test_levels = (0, 5, 7, 10, 20, 30, 40, 50)
print("with color") print("with color")

View File

@ -6,10 +6,10 @@
from typing import Dict, Tuple from typing import Dict, Tuple
from lib_not_dr.logger import LogLevel
from lib_not_dr.logger.formatter import BaseFormatter from lib_not_dr.logger.formatter import BaseFormatter
from lib_not_dr.logger.structure import FormattingMessage from lib_not_dr.logger.structure import FormattingMessage
__all__ = [ __all__ = [
'BaseColorFormatter', 'BaseColorFormatter',
@ -30,21 +30,21 @@ class BaseColorFormatter(BaseFormatter):
# TODO 迁移老 logger 颜色 # TODO 迁移老 logger 颜色
color = { color = {
# Notset: just black # Notset: just black
0: '', LogLevel.notset: '',
# Trace: blue # Trace: blue
2: '\033[0;34m', LogLevel.trace: '\033[0;34m',
# Fine: green # Fine: green
5: '\033[0;32m', LogLevel.fine: '\033[0;32m',
# Debug: cyan # Debug: cyan
7: '\033[0;36m', LogLevel.debug: '\033[0;36m',
# Info: white # Info: white
10: '\033[0;37m', LogLevel.info: '\033[0;37m',
# Warn: yellow # Warn: yellow
30: '\033[0;33m', LogLevel.warn: '\033[0;33m',
# Error: red # Error: red
50: '\033[0;31m', LogLevel.error: '\033[0;31m',
# Fatal: red background # Fatal: red background
90: '\033[0;41m' LogLevel.fatal: '\033[0;41m'
} }
def get_color(self, message: FormattingMessage) -> str: def get_color(self, message: FormattingMessage) -> str:
@ -61,21 +61,21 @@ class LevelColorFormatter(BaseColorFormatter):
# TODO 迁移老 logger 颜色 # TODO 迁移老 logger 颜色
color = { color = {
# Notset: just black # Notset: just black
0: '', LogLevel.notset: '',
# Trace: blue # Trace: blue
2: '\033[0;34m', LogLevel.trace: '\033[0;34m',
# Fine: green # Fine: green
5: '\033[0;32m', LogLevel.fine: '\033[0;32m',
# Debug: cyan # Debug: cyan
7: '\033[0;36m', LogLevel.debug: '\033[0;36m',
# Info: white # Info: white
10: '\033[0;37m', LogLevel.info: '\033[0;37m',
# Warn: yellow # Warn: yellow
30: '\033[0;33m', LogLevel.warn: '\033[0;33m',
# Error: red # Error: red
50: '\033[0;31m', LogLevel.error: '\033[0;31m',
# Fatal: red background # Fatal: red background
90: '\033[0;41m' LogLevel.fatal: '\033[0;41m'
} }
@classmethod @classmethod
@ -99,21 +99,21 @@ class LoggerColorFormatter(BaseColorFormatter):
# TODO 迁移老 logger 颜色 # TODO 迁移老 logger 颜色
color = { color = {
# Notset: just black # Notset: just black
0: '', LogLevel.notset: '',
# Trace: blue # Trace: blue
2: '\033[0;34m', LogLevel.trace: '\033[0;34m',
# Fine: green # Fine: green
5: '\033[0;32m', LogLevel.fine: '\033[0;32m',
# Debug: cyan # Debug: cyan
7: '\033[0;36m', LogLevel.debug: '\033[0;36m',
# Info: white # Info: white
10: '\033[0;37m', LogLevel.info: '\033[0;37m',
# Warn: yellow # Warn: yellow
30: '\033[0;33m', LogLevel.warn: '\033[0;33m',
# Error: red # Error: red
50: '\033[0;31m', LogLevel.error: '\033[0;31m',
# Fatal: red background # Fatal: red background
90: '\033[38;2;245;189;230m', LogLevel.fatal: '\033[38;2;245;189;230m',
} }
@classmethod @classmethod
@ -139,21 +139,21 @@ class TimeColorFormatter(BaseColorFormatter):
# TODO 迁移老 logger 颜色 # TODO 迁移老 logger 颜色
color = { color = {
# Notset: just black # Notset: just black
0: '', LogLevel.notset: '',
# Trace: blue # Trace: blue
2: '\033[0;34m', LogLevel.trace: '\033[0;34m',
# Fine: green # Fine: green
5: '\033[0;32m', LogLevel.fine: '\033[0;32m',
# Debug: cyan # Debug: cyan
7: '\033[0;36m', LogLevel.debug: '\033[0;36m',
# Info: white # Info: white
10: '\033[0;37m', LogLevel.info: '\033[0;37m',
# Warn: yellow # Warn: yellow
30: '\033[0;33m', LogLevel.warn: '\033[0;33m',
# Error: red # Error: red
50: '\033[0;31m', LogLevel.error: '\033[0;31m',
# Fatal: red background # Fatal: red background
90: '\033[0;41m', LogLevel.fatal: '\033[0;41m',
} }
@classmethod @classmethod
@ -177,21 +177,21 @@ class TraceColorFormatter(BaseColorFormatter):
# TODO 迁移老 logger 颜色 # TODO 迁移老 logger 颜色
color = { color = {
# Notset: just black # Notset: just black
0: '\033[38;2;0;255;180m', LogLevel.notset: '\033[38;2;0;255;180m',
# Trace: blue # Trace: blue
2: '\033[38;2;0;255;180m', LogLevel.trace: '\033[38;2;0;255;180m',
# Fine: green # Fine: green
5: '\033[38;2;0;255;180m', LogLevel.fine: '\033[38;2;0;255;180m',
# Debug: cyan # Debug: cyan
7: '\033[38;2;0;255;180m', LogLevel.debug: '\033[38;2;0;255;180m',
# Info: white # Info: white
10: '\033[38;2;0;255;180m', LogLevel.info: '\033[38;2;0;255;180m',
# Warn: yellow # Warn: yellow
30: '\033[38;2;0;255;180m', LogLevel.warn: '\033[38;2;0;255;180m',
# Error: red # Error: red
50: '\033[38;2;0;255;180m', LogLevel.error: '\033[38;2;0;255;180m',
# Fatal: red background # Fatal: red background
90: '\033[38;2;0;255;180m', LogLevel.fatal: '\033[38;2;0;255;180m',
} }
@classmethod @classmethod
@ -222,21 +222,21 @@ class MessageColorFormatter(BaseColorFormatter):
color = { color = {
# Notset: just black # Notset: just black
0: '', LogLevel.notset: '',
# Trace: blue # Trace: blue
2: '\033[38;2;138;173;244m', LogLevel.trace: '\033[38;2;138;173;244m',
# Fine: blue # Fine: blue
5: '\033[38;2;138;173;244m', LogLevel.fine: '\033[38;2;138;173;244m',
# Debug: blue # Debug: blue
7: '\033[38;2;138;173;244m', LogLevel.debug: '\033[38;2;138;173;244m',
# Info: no color # Info: no color
10: '', LogLevel.info: '',
# Warn: yellow # Warn: yellow
30: '\033[0;33m', LogLevel.warn: '\033[0;33m',
# Error: red # Error: red
50: '\033[0;31m', LogLevel.error: '\033[0;31m',
# Fatal: red background # Fatal: red background
90: '\033[38;2;255;255;0;48;2;120;10;10m', LogLevel.fatal: '\033[38;2;255;255;0;48;2;120;10;10m',
} }
@classmethod @classmethod

View File

@ -9,15 +9,17 @@ import inspect
from types import FrameType from types import FrameType
from typing import List, Optional from typing import List, Optional
from lib_not_dr.logger.structure import LogMessage
from lib_not_dr.logger.outstream import BaseOutputStream
from lib_not_dr.types.options import Options 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): class Logger(Options):
name = 'Logger-v2' name = 'Logger-v2'
outputs: List[BaseOutputStream] = [] outputs: List[BaseOutputStream] = [StdioOutputStream()]
log_name: str = 'root'
enable: bool = True enable: bool = True
level: int = 20 # info level: int = 20 # info
@ -62,20 +64,19 @@ class Logger(Options):
def make_log(self, def make_log(self,
messages: List[str], messages: List[str],
tag: Optional[str] = None,
end: str = '\n', end: str = '\n',
split: str = ' ', split: str = ' ',
flush: bool = True, flush: bool = True,
level: int = 20, level: int = 20, # info
log_time: Optional[float] = None, # log_time: Optional[float] = None,
logger_name: str = 'root', # logger_name: str = 'root',
logger_tag: Optional[str] = None, # logger_tag: Optional[str] = None,
stack_trace: Optional[FrameType] = None) -> None: stack_trace: Optional[FrameType] = None) -> None:
# 检查是否需要记录 # 检查是否需要记录
if not self.log_for(level): if not self.log_for(level):
return return
# 处理时间 log_time = time.time_ns()
if log_time is None:
log_time = time.time_ns()
# 处理堆栈信息 # 处理堆栈信息
if stack_trace is None: if stack_trace is None:
# 尝试获取堆栈信息 # 尝试获取堆栈信息
@ -95,6 +96,29 @@ class Logger(Options):
flush=flush, flush=flush,
level=level, level=level,
log_time=log_time, log_time=log_time,
logger_name=logger_name, logger_name=self.log_name,
logger_tag=logger_tag, logger_tag=tag,
stack_trace=stack_trace) 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.
"""

View File

@ -13,7 +13,7 @@ from lib_not_dr.logger.structure import LogMessage
class FormatterTest(unittest.TestCase): class FormatterTest(unittest.TestCase):
test_levels = (0, 2, 5, 7, 10, 30, 50, 90) test_levels = (0, 5, 7, 10, 20, 30, 40, 50)
def test_create_message(self): def test_create_message(self):
message = LogMessage(messages=['test'], message = LogMessage(messages=['test'],