欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-29 10:18:49
通过传入日志文件参数的方式来改变日志的存放位置。废话不多说,直接上代码:from logging import getLogger, FileHandler, Formatter, StreamHandler, \ raiseExceptions, INFO, DEBUG, WARN, ERRORfrom logging.handlers import RotatingFileHandler, TimedRotatingFileHandlerimport osimport syslog...

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

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