Django中的logging

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

内容简介:对网站、微服务来说,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级别, INFOERROR 这些。
  • {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策略。

参考


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

查看所有标签

猜你喜欢:

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

基于内容图像检索技术

基于内容图像检索技术

周明全 / 清华大学 / 2007-12 / 28.00元

《基于内容图像检索技术》从理论方法研究与实现技术角度,总结归纳了基于内容图像检索(CBIR)技术的研究与进展,并融入了作者多年来的相关研究与应用成果,系统地介绍了CBIR的主要概念、基本原理、典型方法、实用范例以及新动向。《基于内容图像检索技术》共有12章分为五部分:第一部分是概述,分析了CBIR的体系结构、技术现状和发展趋势;第一部分讨论图像特征提取,给出图像低层特征(颜色、形状、纹理、空间关系......一起来看看 《基于内容图像检索技术》 这本书的介绍吧!

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

Base64 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试