• 24.自定义python日志handler


    自定义logger

    功能

    可实现日志打印在控制台的同时,输出到文件中
    且文件根据%Y%m%d或者%Y%m%d%H自动决定按天还是按小时分割
    代码比较简单,比直接用自带的方便一些

    代码

    import sys
    import traceback
    
    import os as _os
    import logging as _logging
    import time as _time
    import threading as _threading
    
    
    _file_lock = _threading.RLock()
    class DateRotatingFileHandler(_logging.StreamHandler):
        """
        按天分片的LogHandler
        """
        def __init__(self, file_path, surfix="%Y%m%d%H"):
            """
            :param file_path: 日志路径(不含后缀)
            :type file_path: str
            :param surfix: 时间后缀, 可以使用python的dateformat参数. 默认为%Y%m%d%H
            :type surfix: str
            """
            _logging.StreamHandler.__init__(self)
            self.stream = None
            self._filePath = file_path
            self._surfix = surfix
            _file_lock.acquire()
            try:
                if _os.path.exists(self._filePath):
                    mtime = _os.stat(self._filePath).st_mtime
                    d_fmt = _time.strftime(self._surfix, _time.localtime(mtime))
                    self.stream = open(_os.path.join(self._filePath), "a")
                    self._currentSurfix = d_fmt
                else:
                    self._currentSurfix = ""
            finally:
                _file_lock.release()
            self.setFormatter(_logging.Formatter("%(asctime)s [%(levelname)s]\t%(message)s", "%Y-%m-%d %H:%M:%S"))
    
        def _checkFile(self, ts):
            d_fmt = _time.strftime(self._surfix, _time.localtime(ts))
            if d_fmt != self._currentSurfix:
                _file_lock.acquire()
                try:
                    if not self.stream is None:
                        self.flush()
                        self.stream.close()
                        _os.rename(self._filePath, self._filePath + "." + self._currentSurfix)
                    self.stream = open(_os.path.join(self._filePath), "a")
                    self._currentSurfix = d_fmt
                finally:
                    _file_lock.release()
    
        def emit(self, record):
            self._checkFile(record.created)
            msg = self.format(record)
            sys.stdout.write(msg+"\n")
            sys.stdout.flush()
            _logging.StreamHandler.emit(self, record)
    
        def flush(self):
            if self.stream and hasattr(self.stream, "flush") and not self.stream.closed:
                _logging.StreamHandler.flush(self)
    
        def writeRAW(self, line):
            self._checkFile(_time.time())
            self.stream.write(line)
            self.stream.flush()
    
        def close(self):
            super(DateRotatingFileHandler, self).close()
            if not self.stream is None:
                try:
                    self.stream.close()
                except:
                    traceback.print_exc()
    
    h = DateRotatingFileHandler("./pg.log")
    formatter = _logging.Formatter('\033[33m%(asctime)s - %(process)d - %(threadName)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(funcName)s - %(message)s\033[0m')
    h.setFormatter(formatter)
    logger = _logging.getLogger("[TEST]")
    logger.setLevel(_logging.DEBUG)
    logger.handlers.clear()
    logger.addHandler(h)
    logger.info("tttttttttttt")
    
    
    
    

    逻辑说明

    • 生成pg.log文件
    • 第二天的时候将pg.log重命名为 pg.log.%Y%m%d (%Y%m%d)
    • 依次类推
  • 相关阅读:
    SGPT: GPT Sentence Embeddings for Semantic Search
    应用层协议(HTTP协议)
    增删查改dom节点的操作
    Android 桌面小组件使用
    pandas入门 数据结构
    网站优化要搞什么工作?网站关键词优化的技巧
    背景固定上面文字可以移动以及代码的复合写法(节约代码)
    第五章《类的继承》第2节:子类对象的构建过程
    如何做好水库大坝实时安全监测
    Linux命令总结
  • 原文地址:https://blog.csdn.net/qq_36066039/article/details/139751158