Django logging
Contents
要想放心的在生产环境下使用 Django,其 Logging 的配置和使用是不可或缺的。
这篇文章整体参考 django-logging-right-way 这片文章即可,其他的辅助查看 logging 文档 就可理解不少,这里将我觉得几个值得注意的点摘取出来。
知识点
在
setting
里配置字典LOGGING
即可配置 logging可以配置多种 handlers 如 console、file、sentry、ELK
logger = logging.getLogger(__name__)
是以当前模块名获取在LOGIING
里名如apps.article.views
loggers
如果在
LOGGING
没有配置该模块名的 logger,默认采用空名的 root logger 如'': {'level': 'WARNING', 'handlers': ['console',]}
,如果没有 root logger 将不会记录,如果存在 root logger 其格式里的%(name)
会是模块名,这一点比%{pathname}
信息更加简单一些。如果同时存在 root logger 和获取的模块名的 logger,两个 logger 都会记录。可以在需要模块名 logger 的配置下加上
'propagate': False
阻止 log 的继续传播。logger 的配置里的 handlers 是数组,也就是可以允许进行多个 handler 同时进行记录如:想将记录发到日志服务器,同时也想输出到控制台方便调试可以
'handlers': ['console', 'sentry'],
django 采用的是 Python 内置的 logging 模块,日志记录的格式占位符的意义参考 logrecord-attributes
要想 override 默认 runserver 的请求日志,可以在
LOGGING
里重新配置django.server
的 loggerlog 的级别,
loggers
里定义的级别决定其记录的下限级别,低于该级别的不再记录- debug: Info not needed for regular operation, but useful in development.
- info: Info that’s helpful during regular operation.
- warning: Info that could be problematic, but is non-urgent.
- error: Info that is important and likely requires prompt attention.
- critical: I don’t find myself using this in practice, but if you need one higher than error, here it is
logger 除了对应等级的 debug, info 等等记录,还可以记录异常,如
logger.exception(exception)
,记录时候可以使用函数提供的占位符如logger.info("The value of var is %s", var)
logger 的 handler 使用 ELK 和 sentry 收集日志。使用 Google 可以得到很多不错的文章,当容器化 django 应用时候我推荐的是将日志输出到 console 然后由 k8s 收集,之后使用在 node 上使用 filebeat 收集发送到 Kibana 上,而不是一个 pod 使用一个 Logstash 发送。
使用 logging 记录 SQL
在开发过程中经常遇到需要记录 SQL 语句,分析 ORM 的情况,除了直接设置 MySQL 的 loglevel 。在 Django 里其实可以使用 logger 来调试打印 SQL 语句。
方法也很简单,在 setting
文件里加上下面的语句。
|
|
这里用到了上面给出的 console handler,相比 使用 MySQL 的日志文件记录大量的 SQL 语句,而且更改配置后需要重启 MySQL 服务,使用起来非常不灵活。如果使用 Django 的 logger 来记录,可以随时关闭打开其记录,而且可以方便的更改其输出到文件或者控制台,输出到控制台时候还可以方便与其他调试信息联调。
参考 LOGGING 和用法
这里给出 setting.py 里我常用的 logging 的配置:
|
|
在使用的时候就可以这样:
|
|
有时候多个地方需要使用某个 logger 但是,其 format 里的 %{name}
是 logger 名,无法定位产生 log 的地方,不像使用 root 时候那样方便,但是也不能使用 root。这样就可以使用下面的方法,在获取 logger 之后重新命名下。
|
|