py.lib

Yohn Y. 2023-01-30 Parent:6f8bea109183

44:bfc3a109c06c tip Browse Files

. Убираем лишние форматированные строки * Проблема с созданием вложенных журналов в сложных ситуациях с локами и ротируемым журналом.

log/log_confile.py

     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