Django 中如何优雅的记录日志,帮你解决90%的问题

fh.setLevel(logging.DEBUG)

fh.setFormatter(self.formatter)

self.logger.addHandler(fh)

创建一个StreamHandler,用于输出到控制台

ch = logging.StreamHandler()

ch.setLevel(logging.DEBUG)

ch.setFormatter(self.formatter)

self.logger.addHandler(ch)

if level == ‘info’:

self.logger.info(message)

elif level == ‘debug’:

self.logger.debug(message)

elif level == ‘warning’:

self.logger.warning(message)

elif level == ‘error’:

self.logger.error(message)

这两行代码是为了避免日志输出重复问题

self.logger.removeHandler(ch)

self.logger.removeHandler(fh)

关闭打开的文件

fh.close()

def debug(self, message):

self.__console(‘debug’, message)

def info(self, message):

self.__console(‘info’, message)

def warning(self, message):

self.__console(‘warning’, message)

def error(self, message):

self.__console(‘error’, message)

这是我在项目中还在用的一段代码,生成的文件按天进行切分。

当时写这段代码,有个问题折腾了我很久,就是显示代码报错行数的问题。当 formatter 配置 %(lineno)d 时,每次并不是显示实际的报错行,而是显示日志类中的代码行,但这样显示就失去意义了,所以也就没有配置,用了 %(name)s 来展示实际的调用文件。

其实,如果只是为了排错方便,记录一些日志,这个类基本可以满足要求。但如果要记录访问系统的所有请求日志,那就无能为力了,因为不可能手动在每个接口代码加日志,也没必要。

这个时候,很自然就能想到 Django 中间件了。

Django 中间件

中间件日志代码一共分三个部分,分别是:Filters 代码,middleware 代码,settings 配置,如下:

local = threading.local()

class RequestLogFilter(logging.Filter):

“”"

日志过滤器

“”"

def filter(self, record):

record.sip = getattr(local, ‘sip’, ‘none’)

record.dip = getattr(local, ‘dip’, ‘none’)

record.body = getattr(local, ‘body’, ‘none’)

record.path = getattr(local, ‘path’, ‘none’)

record.method = getattr(local, ‘method’, ‘none’)

record.username = getattr(local, ‘username’, ‘none’)

record.status_code = getattr(local, ‘status_code’, ‘none’)

record.reason_phrase = getattr(local, ‘reason_phrase’, ‘none’)

return True

class RequestLogMiddleware(MiddlewareMixin):

“”"

将request的信息记录在当前的请求线程上。

“”"

def init(self, get_response=None):

self.get_response = get_response

self.apiLogger = logging.getLogger(‘web.log’)

def call(self, request):

try:

body = json.loads(request.body)

except Exception:

body = dict()

if request.method == ‘GET’:

body.update(dict(request.GET))

else:

body.update(dict(request.POST))

local.body = body

local.path = request.path

local.method = request.method

local.username = request.user

local.sip = request.META.get(‘REMOTE_ADDR’, ‘’)

local.dip = socket.gethostbyname(socket.gethostname())

response = self.get_response(request)

local.status_code = response.status_code

local.reason_phrase = response.reason_phrase

self.apiLogger.info(‘system-auto’)

return response

settings.py 文件配置:

MIDDLEWARE = [

‘django.middleware.security.SecurityMiddleware’,

‘django.contrib.sessions.middleware.SessionMiddleware’,

‘django.middleware.common.CommonMiddleware’,

‘django.middleware.csrf.CsrfViewMiddleware’,

‘django.contrib.auth.middleware.AuthenticationMiddleware’,

‘django.contrib.messages.middleware.MessageMiddleware’,

‘django.middleware.clickjacking.XFrameOptionsMiddleware’,

自定义中间件添加在最后

‘lib.log_middleware.RequestLogMiddleware’

]

LOGGING = {

版本

‘version’: 1,

是否禁止默认配置的记录器

‘disable_existing_loggers’: False,

‘formatters’: {

‘standard’: {

‘format’: ‘{“time”: “%(asctime)s”, “level”: “%(levelname)s”, “method”: “%(method)s”, “username”: “%(username)s”, “sip”: “%(sip)s”, “dip”: “%(dip)s”, “path”: “%(path)s”, “status_code”: “%(status_code)s”, “reason_phrase”: “%(reason_phrase)s”, “func”: “%(module)s.%(funcName)s:%(lineno)d”, “message”: “%(message)s”}’,

‘datefmt’: ‘%Y-%m-%d %H:%M:%S’

}

},

过滤器

‘filters’: {

‘request_info’: {‘()’: ‘lib.log_middleware.RequestLogFilter’},

},

‘handlers’: {

标准输出

‘console’: {

‘level’: ‘ERROR’,

‘class’: ‘logging.StreamHandler’,

‘formatter’: ‘standard’

},

自定义 handlers,输出到文件

‘restful_api’: {

‘level’: ‘DEBUG’,

时间滚动切分

‘class’: ‘logging.handlers.TimedRotatingFileHandler’,

‘filename’: os.path.join(LOGS_DIR, ‘web-log.log’),

‘formatter’: ‘standard’,

调用过滤器

‘filters’: [‘request_info’],

每天凌晨切分

‘when’: ‘MIDNIGHT’,

保存 30 天

‘backupCount’: 30,

},

},

‘loggers’: {

‘django’: {

‘handlers’: [‘console’],

‘level’: ‘ERROR’,

‘propagate’: False

},

‘web.log’: {

‘handlers’: [‘restful_api’],

‘level’: ‘INFO’,

此记录器处理过的消息就不再让 django 记录器再次处理了

‘propagate’: False

},

}

}

通过这种方式,只要过 Django 的请求就都会有日志,不管是 web 还是 Django admin。具体记录哪些字段可以根据项目需要进行获取和配置。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
img

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django ,我们可以使用日志记录记录应用程序出现的错误信息。当应用程序发生错误时,我们可以使用 logging.error() 方法记录错误信息,并将错误信息写入到指定的日志文件。 以下是一个简单的 Django 日志配置示例,该配置指定了一个名为 "file" 的日志处理器,并将其绑定到了 "django" 这个 logger 上。在这个配置,我们设置日志级别为 ERROR,表示只有 ERROR 级别及以上的日志才会被记录下来,并将错误日志写入到指定的文件。 ```python LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { 'class': 'logging.FileHandler', 'filename': '/path/to/error.log', }, }, 'loggers': { 'django': { 'handlers': ['file'], 'level': 'ERROR', }, }, } ``` 如果我们想在代码记录错误信息,在应用程序捕获异常并使用 logging.error() 方法记录错误信息即可,例如: ```python import logging logger = logging.getLogger(__name__) def my_view(request): try: # some code that may raise an exception except Exception as e: logger.error('Error occurred: %s', e) ``` 在这个例子,我们在应用程序的某个函数使用 try/except 语句来捕获可能出现的异常,并使用 logging.error() 方法记录错误信息。在记录错误信息时,我们可以使用 %s 格式化字符串来将异常信息作为参数传递给 logging.error() 方法。 通过这种方式记录错误信息,我们可以在日志文件查看应用程序出现的错误信息,从而更好地管理和维护我们的 Django 应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值