最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Flask中logging的单例初始化出错:AttributeError: ‘Formatter’ object has no attribute find

Flask crifan 5785浏览 0评论

折腾:

【已解决】把Flask中的app的logger改造成单例以避免循环引用和多次初始化Flask的实例

期间,之前是Flask的app.logger的初始化:

def create_log(app):

    print("create_log: before init log: app.logger=%s" % app.logger)

    logFormatter = logging.Formatter(settings.LOG_FORMAT)

    fileHandler = RotatingFileHandler(

        settings.LOG_FILE_FILENAME,

        maxBytes=settings.LOG_FILE_MAX_BYTES,

        backupCount=settings.LOG_FILE_BACKUP_COUNT,

        encoding="UTF-8")

    fileHandler.setLevel(settings.LOG_LEVEL)

    fileHandler.setFormatter(logFormatter)

    app.logger.addHandler(fileHandler)

    # Note: should NOT set StreamHandler here, otherwise will duplicate debug log

    app.logger.setLevel(settings.LOG_LEVEL)  # set root log level

    log = app.logger

    log.info("app=%s", app)

    # log.debug("app.config=%s", app.config)

    print("create_log: after init log: app.logger=%s" % app.logger)

    return log

是没问题的:

log尽可以输出到file文件,也可以输出到console中

现在去改为:

common/FlaskLogSingleton.py

import logging

from logging.handlers import RotatingFileHandler

from conf.app import settings

from common.ThreadSafeSingleton import ThreadSafeSingleton

def init_logger(flask_settings, enableConsole=True):

    print("init_logger")

    flaskAppLogger = logging.getLogger(flask_settings.FLASK_APP_NAME) # <Logger RobotQA (WARNING)>

    print("flaskAppLogger=%s" % flaskAppLogger)

    logFormatter = logging.Formatter(flask_settings.LOG_FORMAT)

    fileHandler = RotatingFileHandler(

        flask_settings.LOG_FILE_FILENAME,

        maxBytes=flask_settings.LOG_FILE_MAX_BYTES,

        backupCount=flask_settings.LOG_FILE_BACKUP_COUNT,

        encoding="UTF-8")

    fileHandler.setLevel(flask_settings.LOG_LEVEL_FILE)

    fileHandler.setFormatter(logFormatter)

    flaskAppLogger.addHandler(fileHandler)

    # Note: should NOT set StreamHandler here, otherwise will duplicate debug log

    flaskAppLogger.setLevel(flask_settings.LOG_LEVEL_FILE)  # set root log level

    if enableConsole :

        # define a Handler which writes INFO messages or higher to the sys.stderr

        console = logging.StreamHandler()

        console.setLevel(flask_settings.LOG_LEVEL_CONSOLE)

        # set a format which is simpler for console use

        formatter = logging.Formatter(

            # fmt=logFormatter)

            fmt=logFormatter,

            datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

        # tell the handler to use this format

        console.setFormatter(formatter)

        flaskAppLogger.addHandler(console)

    print("init_logger: after init flaskAppLogger%s" % flaskAppLogger)

    return flaskAppLogger

class LoggerSingleton(metaclass=ThreadSafeSingleton):

    curLog = ""

    def __init__(self):

        self.curLog = init_logger(settings)

        # Note: during __init__, AVOID use log, otherwise will deadlock

        # log.info("LoggerSingleton __init__: curLog=%s", self.curLog)

        print("LoggerSingleton __init__: curLog=%s" % self.curLog)

logSingleton = LoggerSingleton()

log = logSingleton.curLog

log.info("LoggerSingleton inited, logSingleton=%s", logSingleton) # <factory.LoggerSingleton object at 0x10cbcafd0>

log.info("log=%s", log) # <Logger RobotQA (DEBUG)>

# # debug for singleton log

# log2 = LoggerSingleton()

# print("log2=%s" % log2)

其中配置是:

conf/app/settings.py

# Flask app name

FLASK_APP_NAME = "RobotQA"

# Log File

LOG_LEVEL_FILE = logging.DEBUG

LOG_FILE_FILENAME = "logs/" + FLASK_APP_NAME + ".log"

LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

LOG_FILE_MAX_BYTES = 2 * 1024 * 1024

LOG_FILE_BACKUP_COUNT = 10

# Log Console

LOG_LEVEL_CONSOLE = logging.INFO

LOG_CONSOLE_DATA_FORMAT = ‘%Y%m%d %I:%M:%S’

结果是可以输出到文件的,但是输出到console时出错:

<span style="font-family: Monaco; font-size: 12px; color: rgb(51, 51, 51);"–<- Logging error —

Traceback (most recent call last):

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 992, in emit

    msg = self.format(record)

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 838, in format

    return fmt.format(record)

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 576, in format

    if self.usesTime():

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 544, in usesTime

    return self._style.usesTime()

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 388, in usesTime

    return self._fmt.find(self.asctime_search) >= 0

AttributeError: ‘Formatter’ object has no attribute ‘find’

Call stack:

  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1664, in <module>

    main()

  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1658, in main

    globals = debugger.run(setup[‘file’], None, None, is_module)

  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1068, in run

    pydev_imports.execfile(file, globals, locals)  # execute the script

  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile

    exec(compile(contents+"\n", file, ‘exec’), glob, loc)

  File "/Users/crifan/dev/dev_root/xxx/app.py", line 2, in <module>

    from factory import create_app

  File "<frozen importlib._bootstrap>", line 971, in _find_and_load

  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked

  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked

  File "<frozen importlib._bootstrap_external>", line 678, in exec_module

  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed

  File "/Users/crifan/dev/dev_root/xxx/factory.py", line 14, in <module>

    from common.FlaskLogSingleton import log

  File "<frozen importlib._bootstrap>", line 971, in _find_and_load

  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked

  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked

  File "<frozen importlib._bootstrap_external>", line 678, in exec_module

  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed

  File "/Users/crifan/dev/xxx/common/FlaskLogSingleton.py", line 55, in <module>

    log.info("log=%s", log) # <Logger RobotQA (DEBUG)>

Message: ‘log=%s’

Arguments: (<Logger RobotQA (DEBUG)>,)

去搜:

python logging console AttributeError: ‘Formatter’ object has no attribute ‘find’

Python logging module having a formatter causes AttributeError – Stack Overflow

去加上:

from sys import stdout

试试:

from sys import stdout

console = logging.StreamHandler(stdout)

调试:

结果:问题依旧。

另外,上面代码是参考自己之前的代码:

#!/usr/bin/python

# -*- coding: utf-8 -*-

"""

Filename: crifanLogging.py

Function: crifanLib’s logging related functions.

Version: v1.3 20180609

Note:

1. latest version and more can found here:

https://github.com/crifan/crifanLib/blob/master/python/crifanLib

"""

__author__ = "Crifan Li ([email protected])"

__version__ = "v1.3"

__copyright__ = "Copyright (c) 2018, Crifan Li"

__license__ = "GPL"

import logging

################################################################################

# Config

################################################################################

LOG_FORMAT_FILE = "%(asctime)s %(filename)s:%(lineno)-4d %(levelname)-7s %(message)s"

LOG_LEVEL_FILE = logging.DEBUG

LOG_FORMAT_CONSOLE = "%(asctime)s %(filename)s:%(lineno)-4d %(levelname)-7s %(message)s"

LOG_LEVEL_CONSOLE = logging.INFO

################################################################################

# Constant

################################################################################

CURRENT_LIB_FILENAME = "crifanLogging"

################################################################################

# Logging

################################################################################

def loggingInit(filename = None,

                fileLogLevel = LOG_LEVEL_FILE,

                fileLogFormat = LOG_FORMAT_FILE,

                fileLogDateFormat = ‘%Y/%m/%d %I:%M:%S’,

                enableConsole = True,

                consoleLogLevel = LOG_LEVEL_CONSOLE,

                consoleLogFormat = LOG_FORMAT_CONSOLE,

                consoleLogDateFormat = ‘%Y%m%d %I:%M:%S’,

                ):

    """

    init logging for both log to file and console

    :param logFilename: input log file name

        if not passed, use current lib filename

    :return: none

    """

    logFilename = ""

    if filename:

        logFilename = filename

    else:

        # logFilename = __file__ + ".log"

        # ‘/Users/crifan/dev/dev_root/company/xxx/crifanLogging.py.log’

        logFilename = CURRENT_LIB_FILENAME + ".log"

    # logging.basicConfig(

    #                 level    = fileLogLevel,

    #                 format   = fileLogFormat,

    #                 datefmt  = fileLogDateFormat,

    #                 filename = logFilename,

    #                 encoding = "utf-8",

    #                 filemode = ‘w’)

    # rootLogger = logging.getLogger()

    rootLogger = logging.getLogger("")

    rootLogger.setLevel(fileLogLevel)

    fileHandler = logging.FileHandler(

        filename=logFilename,

        mode=’w’,

        encoding="utf-8")

    fileHandler.setLevel(fileLogLevel)

    fileFormatter = logging.Formatter(

        fmt=fileLogFormat,

        datefmt=fileLogDateFormat

    )

    fileHandler.setFormatter(fileFormatter)

    rootLogger.addHandler(fileHandler)

    if enableConsole :

        # define a Handler which writes INFO messages or higher to the sys.stderr

        console = logging.StreamHandler()

        console.setLevel(consoleLogLevel)

        # set a format which is simpler for console use

        formatter = logging.Formatter(

            fmt=consoleLogFormat,

            datefmt=consoleLogDateFormat)

        # tell the handler to use this format

        console.setFormatter(formatter)

        rootLogger.addHandler(console)

################################################################################

# Test

################################################################################

def testLogging():

    loggingInit("testLogging.log")

    # loggingInit()

    logging.debug("log debug")

    logging.info("log info")

    logging.warning("log waring")

    logging.error("log error")

    logging.critical("log critical")

    logging.exception("log exception") # NoneType: None

if __name__ == ‘__main__’:

    # print("[crifanLib-%s] %s" % (__file__, __version__))

    print("[crifanLib-%s] %s" % (CURRENT_LIB_FILENAME, __version__))

    testLogging()

改造的,之前是正常运行的。

不知道为何此处不对。

Error using python logging from Pydev – Stack Overflow

Python logging error – potentially related to variable scope – Stack Overflow

python – Suspend the formatting of the logger, then go back to it – Stack Overflow

把初始化顺序变一下:

def init_logger(flask_settings, enableConsole=True):

    print("init_logger")

    flaskAppLogger = logging.getLogger(flask_settings.FLASK_APP_NAME) # <Logger RobotQA (WARNING)>

    print("flaskAppLogger=%s" % flaskAppLogger)

    flaskAppLogger.setLevel(flask_settings.LOG_LEVEL_FILE)

    logFormatter = logging.Formatter(flask_settings.LOG_FORMAT)

    fileHandler = RotatingFileHandler(

        flask_settings.LOG_FILE_FILENAME,

        maxBytes=flask_settings.LOG_FILE_MAX_BYTES,

        backupCount=flask_settings.LOG_FILE_BACKUP_COUNT,

        encoding="UTF-8")

    fileHandler.setLevel(flask_settings.LOG_LEVEL_FILE)

    fileHandler.setFormatter(logFormatter)

    flaskAppLogger.addHandler(fileHandler)

    if enableConsole :

        # define a Handler which writes INFO messages or higher to the sys.stderr

        console = logging.StreamHandler()

        # console = logging.StreamHandler(stdout)

        console.setLevel(flask_settings.LOG_LEVEL_CONSOLE)

        # set a format which is simpler for console use

        formatter = logging.Formatter(

            # fmt=logFormatter)

            fmt=logFormatter,

            datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

        # tell the handler to use this format

        console.setFormatter(formatter)

        flaskAppLogger.addHandler(console)

    print("init_logger: after init flaskAppLogger%s" % flaskAppLogger)

    return flaskAppLogger

结果:

问题依旧。

python logging   AttributeError: ‘Formatter’ object has no attribute ‘find’

logging   AttributeError: ‘Formatter’ object has no attribute ‘find’

Issue 16368: error when logging message – Python tracker

AttributeError: Logger instance has no attribute ‘setFormatter’

去掉console的初始化:

def init_logger(flask_settings, enableConsole=True):

    print("init_logger")

    flaskAppLogger = logging.getLogger(flask_settings.FLASK_APP_NAME) # <Logger RobotQA (WARNING)>

    print("flaskAppLogger=%s" % flaskAppLogger)

    flaskAppLogger.setLevel(flask_settings.LOG_LEVEL_FILE)

    logFormatter = logging.Formatter(flask_settings.LOG_FORMAT)

    fileHandler = RotatingFileHandler(

        flask_settings.LOG_FILE_FILENAME,

        maxBytes=flask_settings.LOG_FILE_MAX_BYTES,

        backupCount=flask_settings.LOG_FILE_BACKUP_COUNT,

        encoding="UTF-8")

    fileHandler.setLevel(flask_settings.LOG_LEVEL_FILE)

    fileHandler.setFormatter(logFormatter)

    flaskAppLogger.addHandler(fileHandler)

    # if enableConsole :

    #     # define a Handler which writes INFO messages or higher to the sys.stderr

    #     console = logging.StreamHandler()

    #     # console = logging.StreamHandler(stdout)

    #     console.setLevel(flask_settings.LOG_LEVEL_CONSOLE)

    #     # set a format which is simpler for console use

    #     formatter = logging.Formatter(

    #         # fmt=logFormatter)

    #         fmt=logFormatter,

    #         datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

    #     # tell the handler to use this format

    #     console.setFormatter(formatter)

    #     flaskAppLogger.addHandler(console)

    print("init_logger: after init flaskAppLogger%s" % flaskAppLogger)

    return flaskAppLogger

就是正常的:

感觉是Console的log有问题。

pycharm StreamHandler  AttributeError: ‘Formatter’ object has no attribute ‘find’

pycharm StreamHandler  AttributeError: ‘Formatter’

python StreamHandler  AttributeError: ‘Formatter’

python – AttributeError: ‘Logger’ object has no attribute ‚WARNING’ – Stack Overflow

Usage example doesn’t work · Issue #31 · borntyping/python-colorlog

logging.getLogger Python Example

难道此处PyCharm的console很特殊?

重启PyCharm试试

问题依旧。

仔细看log输出:

<span style="font-family: Monaco; font-size: 12px; color: rgb(51, 51, 51);"–<- Logging error —

Traceback (most recent call last):

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 992, in emit

    msg = self.format(record)

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 838, in format

    return fmt.format(record)

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 576, in format

    if self.usesTime():

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 544, in usesTime

    return self._style.usesTime()

  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/__init__.py", line 388, in usesTime

    return self._fmt.find(self.asctime_search) >= 0

AttributeError: ‘Formatter’ object has no attribute ‘find’

Call stack:

  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1664, in <module>

    main()

  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1658, in main

    globals = debugger.run(setup[‘file’], None, None, is_module)

  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1068, in run

    pydev_imports.execfile(file, globals, locals)  # execute the script

  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile

    exec(compile(contents+"\n", file, ‘exec’), glob, loc)

  File "/Users/crifan/dev/dev_root/xxx/app.py", line 2, in <module>

    from factory import create_app

  File "<frozen importlib._bootstrap>", line 971, in _find_and_load

  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked

  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked

  File "<frozen importlib._bootstrap_external>", line 678, in exec_module

  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed

  File "/Users/crifan/dev/dev_root/xxx/factory.py", line 14, in <module>

    from common.FlaskLogSingleton import log

  File "<frozen importlib._bootstrap>", line 971, in _find_and_load

  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked

  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked

  File "<frozen importlib._bootstrap_external>", line 678, in exec_module

  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed

  File "/Users/crifan/dev/dev_root/xxx/FlaskLogSingleton.py", line 53, in <module>

    log.info("LoggerSingleton inited, logSingleton=%s", logSingleton) # <factory.LoggerSingleton object at 0x10cbcafd0>

Message: ‘LoggerSingleton inited, logSingleton=%s’

Arguments: (<common.FlaskLogSingleton.LoggerSingleton object at 0x104bd4048>,)

难道只是此处的LoggerSingleton是特殊的单例,而导致无法正常在console中输出?

看看后续普通的变量能否正常输出

问题依旧:

pycharm console StreamHandler  AttributeError: ‘Formatter’

python self._fmt.find(self.asctime_search)

再去看代码,感觉是代码搞错了,改为:

# fmt=logFormatter,

fmt=flask_settings.LOG_FORMAT,

变成:

LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

def init_logger(flask_settings, enableConsole=True):

    print("init_logger")

    flaskAppLogger = logging.getLogger(flask_settings.FLASK_APP_NAME) # <Logger RobotQA (WARNING)>

    print("flaskAppLogger=%s" % flaskAppLogger)

    flaskAppLogger.setLevel(flask_settings.LOG_LEVEL_FILE)

    logFormatter = logging.Formatter(flask_settings.LOG_FORMAT)

    fileHandler = RotatingFileHandler(

        flask_settings.LOG_FILE_FILENAME,

        maxBytes=flask_settings.LOG_FILE_MAX_BYTES,

        backupCount=flask_settings.LOG_FILE_BACKUP_COUNT,

        encoding="UTF-8")

    fileHandler.setLevel(flask_settings.LOG_LEVEL_FILE)

    fileHandler.setFormatter(logFormatter)

    flaskAppLogger.addHandler(fileHandler)

    if enableConsole :

        # define a Handler which writes INFO messages or higher to the sys.stderr

        console = logging.StreamHandler()

        # console = logging.StreamHandler(stdout)

        console.setLevel(flask_settings.LOG_LEVEL_CONSOLE)

        # set a format which is simpler for console use

        formatter = logging.Formatter(

            # fmt=logFormatter)

            # fmt=logFormatter,

            fmt=flask_settings.LOG_FORMAT,

            datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

        # tell the handler to use this format

        console.setFormatter(formatter)

        flaskAppLogger.addHandler(console)

    print("init_logger: after init flaskAppLogger%s" % flaskAppLogger)

    return flaskAppLogger

结果:

终于可以正常输出了:

【总结】

此处是不小心把:

logging.Formatter返回的变量logFormatter,类型是class Formatter(object)

传递给了console初始化时候的:

formatter = logging.Formatter(

    fmt=logFormatter,

    datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

导致后续console的log打印日志出错。

改为正常的,传递普通的字符串:

LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

formatter = logging.Formatter(

    # fmt=logFormatter,

    fmt=LOG_FORMAT,

    datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

就可以正常初始化file和console的log了。

正常在console和file中都能看到自己想要的日志了。

附上相关代码:

common/FlaskLogSingleton.py

import logging

from logging.handlers import RotatingFileHandler

from conf.app import settings

from common.ThreadSafeSingleton import ThreadSafeSingleton

# from sys import stdout

def init_logger(flask_settings, enableConsole=True):

    print("init_logger")

    flaskAppLogger = logging.getLogger(flask_settings.FLASK_APP_NAME) # <Logger RobotQA (WARNING)>

    print("flaskAppLogger=%s" % flaskAppLogger)

    flaskAppLogger.setLevel(flask_settings.LOG_LEVEL_FILE)

    logFormatter = logging.Formatter(flask_settings.LOG_FORMAT)

    fileHandler = RotatingFileHandler(

        flask_settings.LOG_FILE_FILENAME,

        maxBytes=flask_settings.LOG_FILE_MAX_BYTES,

        backupCount=flask_settings.LOG_FILE_BACKUP_COUNT,

        encoding="UTF-8")

    fileHandler.setLevel(flask_settings.LOG_LEVEL_FILE)

    fileHandler.setFormatter(logFormatter)

    flaskAppLogger.addHandler(fileHandler)

    if enableConsole :

        # define a Handler which writes INFO messages or higher to the sys.stderr

        console = logging.StreamHandler()

        # console = logging.StreamHandler(stdout)

        console.setLevel(flask_settings.LOG_LEVEL_CONSOLE)

        # set a format which is simpler for console use

        formatter = logging.Formatter(

            # fmt=logFormatter)

            # fmt=logFormatter,

            fmt=flask_settings.LOG_FORMAT,

            datefmt=flask_settings.LOG_CONSOLE_DATA_FORMAT)

        # tell the handler to use this format

        console.setFormatter(formatter)

        flaskAppLogger.addHandler(console)

    print("init_logger: after init flaskAppLogger%s" % flaskAppLogger)

    return flaskAppLogger

class LoggerSingleton(metaclass=ThreadSafeSingleton):

    curLog = ""

    def __init__(self):

        self.curLog = init_logger(settings)

        # Note: during __init__, AVOID use log, otherwise will deadlock

        # log.info("LoggerSingleton __init__: curLog=%s", self.curLog)

        print("LoggerSingleton __init__: curLog=%s" % self.curLog)

logSingleton = LoggerSingleton()

log = logSingleton.curLog

log.info("LoggerSingleton inited, logSingleton=%s", logSingleton) # <factory.LoggerSingleton object at 0x10cbcafd0>

log.info("log=%s", log) # <Logger RobotQA (DEBUG)>

# # debug for singleton log

# log2 = LoggerSingleton()

# print("log2=%s" % log2)

相关配置:

conf/app/settings.py

# Flask app name

FLASK_APP_NAME = "RobotQA"

# Log File

LOG_LEVEL_FILE = logging.DEBUG

LOG_FILE_FILENAME = "logs/" + FLASK_APP_NAME + ".log"

LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

LOG_FILE_MAX_BYTES = 2 * 1024 * 1024

LOG_FILE_BACKUP_COUNT = 10

# Log Console

LOG_LEVEL_CONSOLE = logging.INFO

LOG_CONSOLE_DATA_FORMAT = ‘%Y%m%d %I:%M:%S’

转载请注明:在路上 » 【已解决】Flask中logging的单例初始化出错:AttributeError: ‘Formatter’ object has no attribute find

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.175 seconds, using 22.24MB memory