Python Django 1.2:奇怪的日志记录行为

Python Django 1.2:奇怪的日志记录行为,python,django,logging,Python,Django,Logging,我对django视图中使用的标准日志模块有一个非常奇怪的问题。有时它工作正常,有时不记录消息 以下是我的代码结构: /mysite/ (Django root) my_logging.py (logging configuration) settings.py views.py (global views) data_objects.py (objects only containing data, similar to POJO) uploader/ (

我对django视图中使用的标准日志模块有一个非常奇怪的问题。有时它工作正常,有时不记录消息

以下是我的代码结构:

/mysite/ (Django root)
    my_logging.py (logging configuration)
    settings.py
    views.py (global views)
    data_objects.py (objects only containing data, similar to POJO)
    uploader/ (application)
        views.py (uploader views) --> This is where I have problems
以下是my_logging.py的代码:

import logging
import logging.handlers
from django.conf import settings

is_initialized = False

def init_logger():
    """
    Initializes the logging for the application. Configure the root
    logger and creates the handlers following the settings. This function should
    not be used directly from outside the module and called only once.
    """
    # Create the logger
    server_logger = logging.getLogger()
    server_logger.setLevel(logging.DEBUG)

     # Set the logging format for files
    files_formatter = logging.Formatter(settings.LOGGING_FORMAT_FILE)

     # Rotating file handler for errors
    error_handler = logging.handlers.RotatingFileHandler(
        settings.LOGGING_ERROR_FILE,
        maxBytes=settings.LOGGING_ERROR_FILE_SIZE,
        backupCount=settings.LOGGING_ERROR_FILE_COUNT,
    )
    error_handler.setLevel(logging.WARNING)
    error_handler.setFormatter(files_formatter)

    # Rotating file handler for info
    info_handler = logging.handlers.RotatingFileHandler(
        settings.LOGGING_INFO_FILE,
        maxBytes=settings.LOGGING_INFO_FILE_SIZE,
        backupCount=settings.LOGGING_INFO_FILE_COUNT,
    )
    info_handler.setLevel(logging.INFO)
    info_handler.setFormatter(files_formatter)

    # Add the handlers to the logger
    server_logger.addHandler(info_handler)
    server_logger.addHandler(error_handler)

# Init once at first import
if not is_initialized:
    init_logger()
    is_initialized = True
以下是uploader/views.py(#…=跳过的代码)的部分内容:

还有settings.py的有趣部分:

# ---------------------------------------
# Logging settings
# ---------------------------------------

#: Minimum level for logging messages. If logging.NOTSET, logging is disabled
LOGGING_MIN_LEVEL = logging.DEBUG

#: Error logging file path. Can be relative to the root of the project or absolute.
LOGGING_ERROR_FILE = os.path.join(DIRNAME,"log/error.log")

#: Size (in bytes) of the error files
LOGGING_ERROR_FILE_SIZE = 10485760 # 10 MiB

#: Number of backup error logging files
LOGGING_ERROR_FILE_COUNT = 5

#: Info logging file path. Can be relative to the root of the project or absolute.
LOGGING_INFO_FILE = os.path.join(DIRNAME,"log/info.log")

#: Size (in bytes) of the info files
LOGGING_INFO_FILE_SIZE = 10485760 # 10 MiB

#: Number of backup error info files
LOGGING_INFO_FILE_COUNT = 5

#: Format for the log files
LOGGING_FORMAT_FILE = "%(asctime)s:%(name)s:%(levelname)s:%(message)s"
请注意,除了日志记录之外,一切正常。可以以JSON格式正确返回数据。我认为代码的其余部分没有错误


请询问您是否需要更多信息。很抱歉,我删除了代码,但出于保密考虑,我不得不这样做。

我建议您使用如下语法,而不是使用
logging.info('My statement')

import logging
logger = logging.getLogger('MySite')
logger.info('My statement')
也就是说,对记录器对象调用日志语句,而不是直接调用日志模块。同样,您必须调整my_logging.py以配置该记录器:

# Create the logger
server_logger = logging.getLogger('MySite')
server_logger.setLevel(logging.DEBUG)
在视图中,您可以根据
logging.getLogger('MySite')
logging.getLogger('MySite.views')
等进行登录。。任何以“MySite”开头的记录器都将继承您的配置

另外,虽然您通过设置和检查
是否已初始化
有正确的想法,但我认为这种方法不起作用。每次导入my_logging.py时,该变量都将设置为False,从而破坏其用途。您可以在settings.py中使用以下命令来确保日志记录只配置一次:

# Init once at first import
if not hasattr(my_logging, 'is_initialized'):
    my_logging.is_initialized = False

if not my_logging.is_initialized:
    my_logging.init_logger()
    my_logging.is_initialized = True
我用以下两行代码启动所有模块(settings.py除外):

import logging
logging.getLogger('MySite.ModuleInit').debug('Initializing %s' % str(__name__))

如果您仍然有问题,请添加这些行,然后发布站点的模块初始化顺序。根据导入的顺序,可能会有一个奇怪的怪癖。

我建议您使用如下语法,而不是使用
logging.info('My statement')

import logging
logger = logging.getLogger('MySite')
logger.info('My statement')
也就是说,对记录器对象调用日志语句,而不是直接调用日志模块。同样,您必须调整my_logging.py以配置该记录器:

# Create the logger
server_logger = logging.getLogger('MySite')
server_logger.setLevel(logging.DEBUG)
在视图中,您可以根据
logging.getLogger('MySite')
logging.getLogger('MySite.views')
等进行登录。。任何以“MySite”开头的记录器都将继承您的配置

另外,虽然您通过设置和检查
是否已初始化
有正确的想法,但我认为这种方法不起作用。每次导入my_logging.py时,该变量都将设置为False,从而破坏其用途。您可以在settings.py中使用以下命令来确保日志记录只配置一次:

# Init once at first import
if not hasattr(my_logging, 'is_initialized'):
    my_logging.is_initialized = False

if not my_logging.is_initialized:
    my_logging.init_logger()
    my_logging.is_initialized = True
我用以下两行代码启动所有模块(settings.py除外):

import logging
logging.getLogger('MySite.ModuleInit').debug('Initializing %s' % str(__name__))

如果您仍然有问题,请添加这些行,然后发布站点的模块初始化顺序。根据您的进口顺序,可能有一个奇怪的怪癖。

谢谢您的回答。在试图解决该问题时,我已经用getLogger替换了它。不过,我没有考虑is_初始化的问题。我明天会试试这个(我现在在日本,23:00^^)。我将报告它是否有效,并验证您的答案是否正确。我刚刚发现我的错误,这真的很愚蠢:(.我将文件_id视为整数,但Django将参数视为字符串,即使它与整数匹配。记录器无法格式化字符串,消息被静默删除。但是,我想知道为什么我第一次在apache error.log中没有看到它。我将验证此答案,因为它帮助我找到了问题。感谢您的帮助回答。在试图解决问题时,我已将其替换为getLogger。但我没有考虑is_初始化问题。我明天将尝试此功能(我目前在日本,现在是23:00^^)。我将报告它是否有效,并验证您的回答是否正确。我刚刚发现错误,这真是太愚蠢了:(.我将文件_id视为整数,但Django将参数视为字符串,即使它与整数匹配。记录器无法格式化字符串,消息被悄悄删除。但是,我想知道为什么第一次在apache error.log中看不到它。我将验证此答案,因为它帮助我找到了问题。