Logger implment

This commit is contained in:
shenjack 2023-11-05 19:54:34 +08:00
parent d1d4860ddc
commit 2ed3bdce68
Signed by: shenjack
GPG Key ID: 7B1134A979775551
3 changed files with 71 additions and 24 deletions

View File

@ -0,0 +1,41 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
import time
import inspect
from lib_not_dr.logger.structure import LogMessage
from lib_not_dr.logger.outstream import FileCacheOutputStream, StdioOutputStream
if __name__ == '__main__':
log_message = LogMessage(messages=['Hello World!'],
level=20,
stack_trace=inspect.currentframe(),
logger_tag='tester',
logger_name='test')
file_cache = FileCacheOutputStream(file_name='test.log')
stdio = StdioOutputStream()
print(file_cache.as_markdown())
print(stdio.as_markdown())
file_cache.write_stdout(log_message)
stdio.write_stdout(log_message)
# wait for 10 sec
print('wait for 11 sec')
time.sleep(11)
print('finish')
# write 10 lines
for i in range(10):
log_message.log_time = time.time_ns()
file_cache.write_stdout(log_message)
stdio.write_stdout(log_message)
print('write 10 lines')
time.sleep(3)
print('exit')

View File

@ -12,20 +12,23 @@ import atexit
import threading
from pathlib import Path
from typing import Optional
from lib_not_dr.types.options import Options
from lib_not_dr.logger.structure import LogMessage
from lib_not_dr.logger.formatter import BaseFormatter, StdFormatter
__all__ = [
'BaseOutputStream'
'BaseOutputStream',
'StdioOutputStream',
'FileCacheOutputStream'
]
class BaseOutputStream(Options):
name = 'BaseOutputStream'
level: int = 20
level: int = 10
enable: bool = True
formatter: BaseFormatter
@ -46,6 +49,7 @@ class BaseOutputStream(Options):
class StdioOutputStream(BaseOutputStream):
name = 'StdioOutputStream'
level: int = 10
formatter: BaseFormatter = StdFormatter()
def write_stdout(self, message: LogMessage) -> None:
@ -77,8 +81,8 @@ class StdioOutputStream(BaseOutputStream):
class FileCacheOutputStream(BaseOutputStream):
name = 'FileCacheOutputStream'
level: int = 10
formatter: BaseFormatter = StdFormatter(enable_color=False)
text_cache: io.StringIO = None
flush_counter: int = 0
@ -88,12 +92,13 @@ class FileCacheOutputStream(BaseOutputStream):
flush_lock: threading.Lock = None
flush_timer: threading.Timer = None
file_path: Path = Path('./logs')
file_path: Optional[Path] = Path('./logs')
file_name: str
# file mode: always 'a'
file_encoding: str = 'utf-8'
# do file swap or not
file_swap: bool = False
at_exit_register: bool = False
file_swap_counter: int = 0
file_swap_name_template: str = '${name}-${counter}.log'
@ -111,17 +116,11 @@ class FileCacheOutputStream(BaseOutputStream):
file_swap_on_both: bool = False # swap file when both size and time limit reached
def init(self, **kwargs) -> bool:
if self.text_cache is None:
# ( 其实我也不确定为啥这么写 反正按照 "规范" 来说, StringIO 算是 "file" )
return True
self.flush_lock = threading.Lock()
return False
def load_file(self) -> bool:
self.file_start_time = round(time.time())
if self.text_cache is None:
self.text_cache = io.StringIO()
return True
self.flush_lock = threading.Lock()
return False
def _write(self, message: LogMessage) -> None:
"""
@ -132,15 +131,17 @@ class FileCacheOutputStream(BaseOutputStream):
"""
self.text_cache.write(self.formatter.format_message(message))
self.flush_counter += 1
if message.flush or self.flush_counter >= self.flush_count_limit or \
(0 < self.flush_time_limit <= time.time() - self.file_start_time):
if message.flush or self.flush_counter >= self.flush_count_limit:
self.flush()
else:
if self.flush_time_limit > 0:
if not self.flush_timer.is_alive() or self.flush_timer is None:
if self.flush_timer is None or not self.flush_timer.is_alive():
self.flush_timer = threading.Timer(self.flush_time_limit, self.flush)
self.flush_timer.daemon = True
self.flush_timer.start()
atexit.register(self.flush)
if not self.at_exit_register:
atexit.register(self.flush)
self.at_exit_register = True
return None
def write_stdout(self, message: LogMessage) -> None:
@ -165,15 +166,18 @@ class FileCacheOutputStream(BaseOutputStream):
:return:
"""
if (current_file := self.current_file_name) is None:
if self.file_start_time is None:
self.file_start_time = round(time.time())
if not self.file_swap:
# 直接根据 file name 生成文件
current_file = Path(self.file_path) / self.file_name
self.current_file_name = str(current_file)
return current_file
template = string.Template(self.file_swap_name_template)
file_name = template.safe_substitute(name=self.file_name,
counter=self.file_swap_counter,
log_time=round(time.time()),
start_time=self.file_start_time)
current_file = Path(self.file_path) / file_name
self.current_file_name = str(current_file.absolute())
self.current_file_name = str(current_file)
else:
current_file = Path(current_file)
return current_file
@ -214,8 +218,10 @@ class FileCacheOutputStream(BaseOutputStream):
if text == '':
return None
current_file = self.check_flush()
current_file.touch(mode=0o666, exist_ok=True)
with open(current_file, 'a', encoding=self.file_encoding) as f:
if not current_file.exists():
current_file.parent.mkdir(parents=True, exist_ok=True)
current_file.touch()
with current_file.open('a', encoding=self.file_encoding) as f:
f.write(text)
return None

View File

@ -24,7 +24,7 @@ class LogMessage(Options):
split: str = ' '
# 消息的属性
flush: bool = True
flush: bool = None
level: int = 20
log_time: float = None # time.time_ns()
logger_name: str = 'root'
@ -35,7 +35,7 @@ class LogMessage(Options):
messages: Optional[List[str]] = None,
end: Optional[str] = '\n',
split: Optional[str] = ' ',
flush: Optional[bool] = True,
flush: Optional[bool] = None,
level: Optional[int] = 20,
log_time: Optional[float] = None,
logger_name: Optional[str] = 'root',
@ -70,7 +70,7 @@ class LogMessage(Options):
def init(self, **kwargs) -> bool:
if self.log_time is None:
self.log_time = time.time_ns()
if not isinstance(self.flush, bool):
if not isinstance(self.flush, bool) and self.flush is not None:
self.flush = True if self.flush else False
return False