py.lib
2023-01-30
Parent:6f8bea109183
44:bfc3a109c06c tip Browse Files
. Убираем лишние форматированные строки * Проблема с созданием вложенных журналов в сложных ситуациях с локами и ротируемым журналом.
1.1 --- a/log/log_confile.py Sat Jan 28 16:39:53 2023 +0300 1.2 +++ b/log/log_confile.py Mon Jan 30 23:31:46 2023 +0300 1.3 @@ -15,7 +15,7 @@ 1.4 from traceback import extract_tb, extract_stack 1.5 from sys import exc_info, stderr, stdout 1.6 from typing import Optional, TextIO, Any 1.7 -from os.path import join as p_join, abspath 1.8 +from os.path import join as p_join, abspath, split as p_split 1.9 from threading import RLock 1.10 1.11 1.12 @@ -128,7 +128,7 @@ 1.13 self.fd = file_obj 1.14 1.15 if self.fd is None: 1.16 - raise ValueError(f'Не задан файл для записи журналов') 1.17 + raise ValueError('Не задан файл для записи журналов') 1.18 1.19 def flush(self, time_mark: float = None): 1.20 if time_mark is None: 1.21 @@ -187,14 +187,30 @@ 1.22 1.23 1.24 class LogrotateFile(FileLog): 1.25 - def __init__(self, directory: str = '.', prefix: str = 'main', time_to_flush: int = TIME_TO_FLUSH): 1.26 + def __init__(self, 1.27 + file_base: str, 1.28 + file_obj: Optional[TextIO] = None, 1.29 + prefix: str = 'main', 1.30 + time_to_flush: int = TIME_TO_FLUSH): 1.31 + 1.32 d = date.today() 1.33 + if file_obj is None: 1.34 + super().__init__(prefix=prefix, file_name=f'{file_base}-{d}.log', time_to_flush=time_to_flush) 1.35 + else: 1.36 + super().__init__(prefix=prefix, file_obj=file_obj, time_to_flush=time_to_flush) 1.37 + 1.38 + self.logrotate_base = file_base 1.39 + self.logrotate_date = d 1.40 + 1.41 + @classmethod 1.42 + def make(cls, directory: str = '.', prefix: str = 'main', time_to_flush: int = TIME_TO_FLUSH): 1.43 + if len(p_split(prefix)) > 1: 1.44 + raise ValueError(f'Префикс журналирования не должен быть похож ' 1.45 + f'на пусть файловой системы, убери знак разделения директорий: {prefix}') 1.46 + 1.47 directory = abspath(directory) 1.48 - file_name = p_join(directory, f'{prefix}-{d}.log') 1.49 - 1.50 - super().__init__(prefix, file_name=file_name, time_to_flush=time_to_flush) 1.51 - self.logrotate_base = p_join(directory, f'{prefix}') 1.52 - self.logrotate_date = d 1.53 + file_base = p_join(directory, prefix) 1.54 + return cls(file_base=file_base, prefix=prefix, time_to_flush=time_to_flush) 1.55 1.56 def flush(self, time_mark: float = None, no_rotate: bool = False): 1.57 if not no_rotate: 1.58 @@ -213,10 +229,21 @@ 1.59 self.logrotate_date = d 1.60 self.flush(no_rotate=True) 1.61 1.62 + def sub_log(self, name: str): 1.63 + return self.__class__( 1.64 + file_base=self.logrotate_base, 1.65 + file_obj=self.fd, prefix=f'{self.prefix}/{name}', 1.66 + time_to_flush=self.time_to_flush 1.67 + ) 1.68 + 1.69 1.70 class ThreadSafeFileLog(FileLog): 1.71 - def __int__(self, *a, **kwa): 1.72 - super().__init__(*a, **kwa) 1.73 + def __int__(self, prefix: str = 'main', 1.74 + file_name: Optional[str] = None, 1.75 + file_obj: Optional[TextIO] = None, 1.76 + time_to_flush: int = TIME_TO_FLUSH 1.77 + ): 1.78 + super().__init__(prefix=prefix, file_name=file_name, file_obj=file_obj, time_to_flush=time_to_flush) 1.79 self.thread_safe_lock = RLock() 1.80 1.81 def _write(self, mark: str, msg: Any): 1.82 @@ -227,10 +254,20 @@ 1.83 with self.thread_safe_lock: 1.84 super().flush(time_mark) 1.85 1.86 + def sub_log(self, name: str): 1.87 + if self.fd is None: 1.88 + raise ValueError('Попытка использовать закрытый файл журнала') 1.89 + 1.90 + obj = self.__class__(prefix=f'{self.prefix}/{name}', file_obj=self.fd, time_to_flush=self.time_to_flush) 1.91 + obj.thread_safe_lock = self.thread_safe_lock 1.92 + return obj 1.93 + 1.94 1.95 class ThreadSafeLogrotateFile(LogrotateFile): 1.96 - def __init__(self, directory: str = '.', prefix: str = 'main', time_to_flush: int = TIME_TO_FLUSH): 1.97 - super().__init__(directory=directory, prefix=prefix, time_to_flush=time_to_flush) 1.98 + def __init__(self, file_base: str, file_obj: Optional[TextIO] = None, prefix: str = 'main', 1.99 + time_to_flush: int = TIME_TO_FLUSH): 1.100 + 1.101 + super().__init__(file_base=file_base, file_obj=file_obj, prefix=prefix, time_to_flush=time_to_flush) 1.102 self.thread_safe_lock = RLock() 1.103 1.104 def _write(self, mark: str, msg: Any): 1.105 @@ -244,3 +281,16 @@ 1.106 def logrotate_rotate(self): 1.107 with self.thread_safe_lock: 1.108 super().logrotate_rotate() 1.109 + 1.110 + def sub_log(self, name: str): 1.111 + if self.fd is None: 1.112 + raise ValueError('Попытка использовать закрытый файл журнала') 1.113 + 1.114 + obj = self.__class__(file_base=self.logrotate_base, 1.115 + file_obj=self.fd, 1.116 + prefix=f'{self.prefix}/{name}', 1.117 + time_to_flush=self.time_to_flush 1.118 + ) 1.119 + 1.120 + obj.thread_safe_lock = self.thread_safe_lock 1.121 + return obj