当前位置: 移动技术网 > IT编程>脚本编程>Python > python 自定义log文件,并储存到指定的位置

python 自定义log文件,并储存到指定的位置

2020年07月16日  | 移动技术网IT编程  | 我要评论

通过传入日志文件参数的方式来改变日志的存放位置。
废话不多说,直接上代码:

from logging import getLogger, FileHandler, Formatter, StreamHandler, \
    raiseExceptions, INFO, DEBUG, WARN, ERROR
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
import os
import sys

loggers = {}


# The background is set with 40 plus the number of the color, and the foreground with 30

def prepareLogging(name, logDir):
    global loggers
    if loggers.get(name):
        return loggers.get(name)
    else:
        logger = getLogger(name)
        # dir must exist, so create dir
        # FIXME: if no absolute path is assigned, logs directory will be in the same directory with  mainPictureServer.py - use the relative path first.
        # any better solution?
        if not os.path.exists(logDir):
            os.makedirs(logDir)

        # TimedRotatingFileHandler : when - (s)econd|(m)inute|(h)our|(d)ay|w0-26(0-monday)|midnight
        hdlr = TimedRotatingFileHandler(logDir + "/" + name + ".txt", when="d", interval=1, backupCount=30)
        # hdlr = RotatingFileHandler(logDir+"/"+name+".txt", maxBytes=1024<<10, backupCount=30)
        # formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        formatter = Formatter(
            '%(thread)-6.6s %(asctime)s.%(msecs)02.2d %(filename)-12.12s_%(lineno)03d %(levelname)-3.3s] %(message)s',
            '%m-%d %H:%M:%S')

        hdlr.setFormatter(formatter)
        logger.addHandler(hdlr)

        ch = StreamHandler()
        ch.setLevel(INFO)
        formatter = Formatter(
            '%(thread)-4.4s %(asctime)s.%(msecs)02.2d %(filename)-12.12s_%(lineno)03d] %(levelname)-2.2s] %(message)s',
            '%M:%S')
        ch.setFormatter(formatter)
        # logger.propagate = False #without this, message will be duplicated
        logger.addHandler(ch)

        loggers[name] = logger

        logger.setLevel(INFO)
        return logger


if hasattr(sys, 'frozen'):  # support for py2exe
    _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
elif __file__[-4:].lower() in ['.pyc', '.pyo']:
    _srcfile = __file__[:-4] + '.py'
else:
    _srcfile = __file__
_srcfile = os.path.normcase(_srcfile)

if hasattr(sys, '_getframe'):
    currentframe = lambda: sys._getframe(3)
else:  # pragma: no cover
    def currentframe():
        """Return the frame object for the caller's stack frame."""
        try:
            raise Exception
        except Exception:
            return sys.exc_info()[2].tb_frame.f_back


class MyLogger(object):
    # as the caller will be MyLogger, so need copy logger implement for info(), warning, error()

    def __init__(self, logger):
        self.logger = logger

    def debug(self, msg, *args, **kwargs):
        if self.logger.isEnabledFor(DEBUG):
            self._log(DEBUG, msg, args, **kwargs)

    def info(self, msg, *args, **kwargs):
        if self.logger.isEnabledFor(INFO):
            self._log(INFO, msg, args, **kwargs)

    def warn(self, msg, *args, **kwargs):
        if self.logger.isEnabledFor(WARN):
            self._log(WARN, msg, args, **kwargs)

    def error(self, msg, *args, **kwargs):
        if self.logger.isEnabledFor(ERROR):
            self._log(ERROR, msg, args, **kwargs)

    def _log(self, level, msg, args, exc_info=None, extra=None):
        """
        Low-level logging routine which creates a LogRecord and then calls
        all the handlers of this logger to handle the record.
        """
        # Add wrapping functionality here.
        if _srcfile:
            # IronPython doesn't track Python frames, so findCaller throws an
            # exception on some versions of IronPython. We trap it here so that
            # IronPython can use logging.
            try:
                fn, lno, func = self.findCaller()
            except ValueError:
                fn, lno, func = "(unknown file)", 0, "(unknown function)"
        else:
            fn, lno, func = "(unknown file)", 0, "(unknown function)"
        if exc_info:
            if not isinstance(exc_info, tuple):
                exc_info = sys.exc_info()
        record = self.logger.makeRecord(
            self.logger.name, level, fn, lno, msg, args, exc_info, func, extra)
        self.logger.handle(record)

    def findCaller(self):
        """
        Find the stack frame of the caller so that we can note the source
        file name, line number and function name.
        """
        f = currentframe()
        # On some versions of IronPython, currentframe() returns None if
        # IronPython isn't run with -X:Frames.
        if f is not None:
            f = f.f_back
        rv = "(unknown file)", 0, "(unknown function)"
        while hasattr(f, "f_code"):
            co = f.f_code
            filename = os.path.normcase(co.co_filename)
            if filename == _srcfile:
                f = f.f_back
                continue
            rv = (co.co_filename, f.f_lineno, co.co_name)
            break
        return rv

    def log(self, level, msg, *args, **kwargs):
        """
        Log 'msg % args' with the integer severity 'level'.

        To pass exception information, use the keyword argument exc_info with
        a true value, e.g.

        logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
        """
        if not isinstance(level, int):
            if raiseExceptions:
                raise TypeError("level must be an integer")
            else:
                return
        if self.logger.isEnabledFor(level):
            self._log(level, msg, args, **kwargs)

    def _prefix(self, elevId):
        if str(elevId) == '1':
            prefix = ''
        else:
            prefix = ' ' * 30
        return prefix

    def infoE(self, elevId, msg, *args, **kwargs):
        self.info("{}{}".format(self._prefix(elevId), msg), *args, **kwargs)

    def warnE(self, elevId, msg, *args, **kwargs):
        self.warn("{}{}".format(self._prefix(elevId), msg), *args, **kwargs)

    def errorE(self, elevId, msg, *args, **kwargs):
        self.error("{}{}".format(self._prefix(elevId), msg), *args, **kwargs)

    def print0(self, msg, *args, **kwargs):
        method_name = sys._getframe(1).f_code.co_name
        line_no = sys._getframe(1).f_lineno
        _m = "{}_{}:{}{}".format(method_name, line_no, "", msg)
        print(_m)
        self.debug(_m, *args, **kwargs)

    def printE(self, elevId, msg, *args, **kwargs):
        p = self._prefix(elevId)
        method_name = sys._getframe(1).f_code.co_name
        line_no = sys._getframe(1).f_lineno
        _m = "{}_{}:{}{}".format(method_name, line_no, p, msg)
        print(p + msg)
        self.debug(p + msg, *args, **kwargs)


def logtt(logger):
    logger.info('hello logs')


if __name__ == '__main__':
    logger = MyLogger(prepareLogging("hello", './logs'))
    logtt(logger)

本文地址:https://blog.csdn.net/qq_43030934/article/details/107339983

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网