Django中的logging

栏目: Python · 发布时间: 7年前

内容简介:对网站、微服务来说,log(日志)是比较重要的运维工具。以下为在log中,通过在

对网站、微服务来说,log(日志)是比较重要的运维工具。 Django 的log,主要是复用 Python 标准库中的 logging 模块,在 settings.py 中进行配置。 此外,也提供了一些独特的扩展。

完整示例

以下为 settings.py 的片段:

TIME_ZONE = 'Asia/Shanghai'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{asctime} {module}.{funcName} {lineno:3} {levelname:7} => {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'formatter': 'verbose',
            'filename': '/tmp/django.log',
            'maxBytes': 4194304,  # 4 MB
            'backupCount': 10,
            'level': 'DEBUG',
        },
    },
    'loggers': {
        '': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
        'django': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
            'propagate': False,
        },
    },
}

设置时间与时区

在log中,通过在 format 设置 {asctime} ,可以看到时间。 时间很可能是log最重要的一个属性。 而对中国用户来说,默认时区是个必须关注的问题,否则时间和当地时间差距较大。 需要在 settings.py 中,做 TIME_ZONE 配置。

TIME_ZONE = 'Asia/Shanghai'

有这个配置在,可以不用修改系统的配置。

formatters

'formatters': {
        'verbose': {
            'format': '{asctime} {module}.{funcName} {lineno:3} {levelname:7} => {message}',
            'style': '{',
        },
    },

format

Formatter就是log格式化的样式。 这里只定义了一种formatter,那就是 verbose 。

  • {asctime} :默认的日期与时间,形式大概是 2018-11-15 20:41:56,868 。这个形式可以修改,通过 datefmt 。
  • {module} 是模块名。
  • {funcName} 是函数名。
  • {lineno:3} 是行号,至少显示3个字符,少则补空格。
  • {levelname:7} 是log级别, INFO 、 ERROR 这些。
  • {message} 是log内容。

其它可选字段,详见 logrecord 。

style

这里 style 选择 { ,是指 {asctime} 这种形式。 如果选择 % ,则是 %(asctime)s 这种形式。 还有一种选择,是 $ ,是 $asctime 或 ${asctime} 这种形式。 详见 Use of alternative formatting styles 。

datefmt

Django 自带模块默认的格式化形式,打印出来,日期时间的形式大致是这样: 16/Nov/2018 09:03:22 。 相当于设置了下面的 datefmt 。

'formatters': {
        'default': {
            ...
            'style': '{',
            'datefmt': '%d/%b/%Y %H:%M:%S',
        },
    },

其中,各个组成部分的含义与其它可选内容见下表:

Directive Meaning Notes
%a Locale’s abbreviated weekday name.
%A Locale’s full weekday name.
%b Locale’s abbreviated month name.
%B Locale’s full month name.
%c Locale’s appropriate date and time representation.
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%I Hour (12-hour clock) as a decimal number [01,12].
%j Day of the year as a decimal number [001,366].
%m Month as a decimal number [01,12].
%M Minute as a decimal number [00,59].
%p Locale’s equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6].
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locale’s appropriate date representation.
%X Locale’s appropriate time representation.
%y Year without century as a decimal number [00,99].
%Y Year with century as a decimal number.
%z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].
%Z Time zone name (no characters if no time zone exists).
%% A literal '%' character.

logging 默认格式中, asctime 的逗号 , 后面是三位毫秒(milliseconds),在以上格式中并不存在。 因此,如果修改为自定义格式,毫秒信息丢失。 如果要额外添加,需要指定 {msecs:03d} 。

所以,如果需要毫秒信息,一般不改默认格式。

handlers

'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'formatter': 'verbose',
            'filename': '/tmp/django.log',
            'maxBytes': 4194304,  # 4 MB
            'backupCount': 10,
            'level': 'DEBUG',
        },
    },

formatter

formatter 是指定一个格式化方式,也就是前面 formatters 定义的那些。 这里选择了前面定义的 verboase 。

level

level 是选择log的最低等级。 由低到高,列出如下,需要按需选择。

  • DEBUG: Low level system information for debugging purposes.
  • INFO: General system information.
  • WARNING: Information describing a minor problem that has occurred.
  • ERROR: Information describing a major problem that has occurred.
  • CRITICAL: Information describing a critical problem that has occurred.

class

class 是指定处理log的类,在Python里 logging.handlers 中。

可选 class 列出如下,详见 Useful Handlers 。

class 功能
StreamHandler 输出到Stream。通常用来打印到标准输出。
FileHandler 打印到文件。
NullHandler 不格式化也不打印。主要是为了避免 No handlers could be found for logger XXX 的设计。
WatchedFileHandler 自动重开log文件,配合别的会自动切分的log文件使用。
RotatingFileHandler 自动按大小切分的log文件。
TimedRotatingFileHandler 按时间自动切分的log文件。
SocketHandler 向Socket打log,基于TCP协议。
DatagramHandler 向Socket打log,基于UDP协议。
SysLogHandler 在Unix-like系统打印到remote或local的Unix syslog。
NTEventLogHandler 在Windows系统打印到微软的event log。
SMTPHandler 通过email发送log。
MemoryHandler 打印到内存buffer。
HTTPHandler 通过HTTP协议向服务器发送log。
QueueHandler 打log到Queue中,适合多进程( multiprocessing )场景。

这里主要选择了StreamHandler和RotatingFileHandler。 既能在 ./manage.py runserver 时打印在前台,又能在部署后打印到文件,方便前期开发和后期运维。

此外, Django 额外定义了一个handler—— AdminEmailHandler ,向管理员发送邮件。

'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'email_backend': 'django.core.mail.backends.filebased.EmailBackend',
            'include_html': True,
        }
    },

有需要可以添加,但要确保邮件SMTP服务器的通畅。

loggers

'loggers': {
        '': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
        'django': {
            'handlers': ['console', 'file'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
            'propagate': False,
        },
    },

到了 loggers 模块,最重要的是选择设置哪些logger。 这里设置了 '' (root)和 'django' 。 前者是为了方便地使用 logging ,所以设了root的logger,这也是默认的logger。 后者是打印所有 Django 自身的logger。

Django 额外提供的 loggers 扩展如下:

  • django
  • django.request
  • django.server
  • django.template
  • django.db.backends
  • django.security.*
    • django.security.DisallowedHost
    • django.security.SuspiciousOperation
    • django.security.SuspiciousOperation
    • django.security.DisallowedHost
  • django.db.backends.schema

propagate 是设定是否向父logger传播信息。 对root来说,这一条可有可无。 但在本例中,root被使用了,所以 'django' logger必须设置为 'propagate': False, ,否则会打印两次。

其它

现在 dictConfig 只有一个 version ,那就是 1 。

disable_existing_loggers 默认是 True ,禁用已经存在的logger。 被禁用的logger仍然存在,只是不接收任何输入,包括其父logger也得不到信息 ——这种行为可能导致一些问题,因此这一条通常固定设为 False 。

Django 还支持一些 Filters ,在打log到指定目标时预先过滤一些内容。 这里不使用,也未介绍。

代码示例

import logging as log

log.debug('Hello %s', 'world')
log.info('I am here!')

配置好一切后,使用起来就是这么简单。

当然,这里是因为使用了root这个logger,才不需要使用 loggging.getLogger() 。 如果是写提供给别人使用的库或Django App,需要考虑更有层次的log策略。

参考


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Effective JavaScript

Effective JavaScript

赫尔曼 (David Herman) / 黄博文、喻杨 / 机械工业出版社 / 2014-1-1 / CNY 49.00

Effective 系列丛书经典著作,亚马逊五星级畅销书,Ecma 的JavaScript 标准化委员会著名专家撰写,JavaScript 语言之父、Mozilla CTO —— Brendan Eich 作序鼎力推荐!作者凭借多年标准化委员会工作和实践经验,深刻辨析JavaScript 的内部运作机制、特性、陷阱和编程最佳实践,将它们高度浓缩为极具实践指导意义的 68 条精华建议。 本书共......一起来看看 《Effective JavaScript》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具