Django 1.2标准日志模块出现奇怪行为时的解决方案

server/2024/10/18 16:04:13/

在 Django 1.2 中,标准日志模块有时会出现意想不到的行为,例如日志消息未按预期记录、日志级别未正确应用或日志格式错乱等。这些问题可能源于日志配置不当、日志模块被多次初始化、或日志模块被其他包覆盖等原因。下面是一些常见问题的排查方法和解决方案。

在这里插入图片描述

1、问题背景

在 Django 1.2 中,使用标准日志模块记录信息时遇到了一个奇怪的问题。有时候它可以正常工作,而有时候它却无法记录信息。

2、解决方案

为了解决这个问题,我们采取了以下步骤:

  1. 首先,我们检查了代码结构。代码结构如下:
/mysite/ (Django root)my_logging.py (logging configuration)settings.pyviews.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
  1. 接着,我们检查了 my_logging.py 的代码:
import logging
import logging.handlers
from django.conf import settingsis_initialized = Falsedef init_logger():"""Initializes the logging for the application. Configure the rootlogger and creates the handlers following the settings. This function shouldnot be used directly from outside the module and called only once."""# Create the loggerserver_logger = logging.getLogger()server_logger.setLevel(logging.DEBUG)# Set the logging format for filesfiles_formatter = logging.Formatter(settings.LOGGING_FORMAT_FILE)# Rotating file handler for errorserror_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 infoinfo_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 loggerserver_logger.addHandler(info_handler)server_logger.addHandler(error_handler)# Init once at first import
if not is_initialized:init_logger()is_initialized = True
  1. 然后,我们检查了 uploader/views.py 中的部分代码:
#...
import mysite.my_logging
import logging
#... 
# The messages in the following view are written correctly :
@login_required
def delete(request, file_id):"""Delete the file corresponding to the given ID and confirm the deletion tothe user.@param request: the HTTP request object@type request: django.http.HttpRequest@return: django.http.HttpResponse - the response to the client (html)"""# Get the file object form the database and raise a 404 if not foundf = get_object_or_404(VideoFile, pk=file_id)# TODO: check if the deletion is successful# Get the video directorydir_path = os.path.dirname(f.file.path)# Delete the filef.delete()try:# Delete the video directory recursivelyshutil.rmtree(dir_path)logging.info("File \"%(file)s\" and its directory have been deleted by %(username)s",{'file': f.title,'username': request.user.username})messages.success(request, _('The video file "%s" has been successfully deleted.') % f.title)except OSError:logging.warning("File \"%(id)d\" directory cannot be completely deleted. Some files may still be there.",{'id': f.id,})messages.warning(request, _("The video file \"%s\" has been successfully deleted, but not its directory. There should not be any problem but useless disk usage.") % f.title)return HttpResponseRedirect(reverse('mysite.uploader.views.list'))
#...
# The messages in the following view are NOT written at all:
@csrf_exempt
def get_thumblist(request,file_id):"""This view can be called only by POST and with the id of a videofile ready for the scene editor.@param request: the HTTP request object. Must have POST as method.@type request: django.http.HttpRequest@return: django.http.HttpResponse - the response to the client (json)"""#TODO: Security, TESTlogging.info("Demand of metadata for file %(id)d received.",{'id': file_id,})if request.method == 'POST':if file_id:# Get the video file object form the database and raise a 404 if not foundvid = get_object_or_404(VideoFile, pk=file_id)# ...try:# ... file operationsexcept IOError:logging.error("Error when trying to read index file for file %(id)d !",{'id': file_id,})except TypeError:logging.error("Error when trying to parse index file JSON for file %(id)d !",{'id': file_id,})# ...logging.info("Returning metadata for file %(id)d.",{'id': file_id,})return HttpResponse(json,content_type="application/json")else:logging.warning("File %(id)d is not ready",{'id': file_id,})return HttpResponseBadRequest('file_not_ready')else:logging.warning("bad POST parameters")return HttpResponseBadRequest('bad_parameters')else:logging.warning("The GET method is not allowed")return HttpResponseNotAllowed(['POST'])
  1. 最后,我们检查了 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"
  1. 通过对以上代码的检查,我们发现问题出现在 uploader/views.py 中的 get_thumblist 函数中。该函数中使用 logging.info('Demand of metadata for file %(id)d received.') 语句记录信息,但由于没有使用 logger 对象,导致信息没有被记录下来。

  2. 为了解决这个问题,我们将 get_thumblist 函数中的 logging.info('Demand of metadata for file %(id)d received.') 语句改为 logger.info('Demand of metadata for file %(id)d received.'),其中 logger 是一个 logging.getLogger() 函数返回的日志对象。

  3. 修改后的代码如下:

#...
import mysite.my_logging
import logging
logger = logging.getLogger('MySite.views')
#... 
# The messages in the following view are written correctly :
@login_required
def delete(request, file_id):"""Delete the file corresponding to the given ID and confirm the deletion tothe user.@param request: the HTTP request object@type request: django.http.HttpRequest@return: django.http.HttpResponse - the response to the client (html)"""# Get the file object form the database and raise a 404 if not foundf = get_object_or_404(VideoFile, pk=file_id)# TODO: check if the deletion is successful# Get the video directorydir_path = os.path.dirname(f.file

以上方法可以帮助解决 Django 1.2 中标准日志模块的异常行为问题。通过合理配置和调整日志模块,可以确保日志记录功能稳定、可靠地运行。


http://www.ppmy.cn/server/131113.html

相关文章

网络安全产品类型

1. 防火墙(Firewall) 功能:防火墙是网络安全的第一道防线,通过检查进出网络的流量来阻止未经授权的访问。它可以基于预定义的安全规则,过滤数据包和阻止恶意通信。 类型: 硬件防火墙:以专用设备…

Pandas库

一、安装 Pandas是一个基于Python构建的专门进行数据操作和分析的开源软件库,它提供了高效的数据结构和丰富的数据操作工具。 安装 pip install pandas 二、核心数据结构 Pandas库中最常用的数据类型是Series和DataFrame: Series:一维数…

大数据毕业设计选题推荐-B站热门视频数据分析-Python数据可视化-Hive-Hadoop-Spark

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

Perl 子程序(函数)

Perl 子程序(函数) Perl 是一种高级、解释型、动态编程语言,广泛用于CGI脚本、系统管理、网络编程、 finance, bioinformatics, 以及其他领域。在Perl中,子程序(也称为函数)是组织代码和重用代码块的重要方…

6、Spring Boot 3.x集成RabbitMQ动态交换机、队列

一、前言 本篇主要是围绕着 Spring Boot 3.x 与 RabbitMQ 的动态配置集成,比如动态新增 RabbitMQ 交换机、队列等操作。二、默认RabbitMQ中的exchange、queue动态新增及监听 1、新增RabbitMQ配置 RabbitMQConfig.java import org.springframework.amqp.rabbit.a…

NR PDSCH资源分配与DM-RS和PT-RS参考信号

本文的写作目的是为了汉化MATLAB关于 NR PDSCH 资源分配的Document,帮助大家更快的掌握PDSCH中资源的分配问题。来张时频资源图镇楼。 文章目录 1. PDSCH2. DM-RS2.1 控制时域资源的参数2.2 控制频域资源的参数 3. 序列生成4. PT-RS4.1 控制时域资源的参数4.2 控制…

【HTML格式PPT离线到本地浏览】

文章目录 概要实现细节小结 概要 最近在上课时总是出现网络不稳定导致的PPT无法浏览的情况出现,就想到下载到电脑上。但是PPT是一个HTML的网页,无法通过保存网页(右键另存为mhtml只能保存当前页)的形式全部下载下来,试…

针对Ubuntu20.04 中的 Docker 配置可用镜像源(包含国内可用镜像源)

文章目录 写在前面一、Docker 官方源二、更换Docker 国内可用镜像源 (推荐使用)参考链接 写在前面 自己的测试环境: Ubuntu20.04,docker-27.3.1 一、Docker 官方源 打开 /etc/docker/daemon.json文件: sudo gedit …