Python日志功能在Django中的应用

文章目录

      • 1.python代码实现完整的日志功能
      • 2. 日志在django中的应用的三种方式
        • 1.直接在settings.py中配置
        • 2.使用配置文件和fileConfig()函数实现日志配置
        • 3.使用字典配置信息和dictConfig()函数实现日志配置
      • 3.总结注意点

1.python代码实现完整的日志功能

需求:
	1)要求将所有级别的所有日志都写入磁盘文件中
	2)all.log文件中记录所有的日志信息,日志格式为:日期和时间 - 日志级别 - 日志信息
	3)error.log文件中单独记录error及以上级别的日志信息,日志格式为:日期和时间 - 日志级别 - 文件名[:行号] - 日志信息
	4)要求all.log在每天凌晨进行日志切割

代码实现:

import logging
import logging.handlers
import datetime

logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)

rf_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight', interval=1, backupCount=7, atTime=datetime.time(0, 0, 0, 0))
rf_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))

f_handler = logging.FileHandler('error.log')
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s"))

logger.addHandler(rf_handler)
logger.addHandler(f_handler)

logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

all.log文件输出

2018-05-13 16:12:40,612 - DEBUG - debug message
2018-05-13 16:12:40,612 - INFO - info message
2018-05-13 16:12:40,612 - WARNING - warning message
2018-05-13 16:12:40,612 - ERROR - error message
2018-05-13 16:12:40,613 - CRITICAL - critical message

error.log文件输出

2018-05-13 16:12:40,612 - ERROR - log.py[:81] - error message
201-05-13 16:12:40,613 - CRITICAL - log.py[:82] - critical message

2. 日志在django中的应用的三种方式

1.直接在settings.py中配置

#########################
## Django Logging  BEGIN
#########################

#LOGGING_DIR 日志文件存放目录
LOGGING_DIR = "/home/xxt/logs"
if not os.path.exists(LOGGING_DIR):
    os.mkdir(LOGGING_DIR)

import logging

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '[%(levelname)s][%(asctime)s][%(filename)s][%(funcName)s][%(lineno)d] > %(message)s'
        },
        'simple': {
            'format': '[%(levelname)s]> %(message)s',
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file_handler': {
             'level': 'INFO',
             'class': 'logging.handlers.TimedRotatingFileHandler',
             'filename': '%s/django.log' % LOGGING_DIR,
             'formatter':'standard',
             'encoding': 'utf-8'
        }, # 用于文件输出
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
             'formatter':'standard'
        },
    },
    'loggers': {
        'mdjango': {
            # 一个记录器中可以使用多个处理器
            'handlers': ['console','file_handler'],
            'level':'DEBUG',
            'propagate': True,
        },
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
    }
}
    
logger = logging.getLogger("mdjango")

#########################
## Django Logging  END
#########################

2.使用配置文件和fileConfig()函数实现日志配置

配置文件logging.conf内容如下:

[loggers]
keys=root,simpleExample

[handlers]
keys=fileHandler,consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=fileHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter

[handler_fileHandler]
class=FileHandler
args=('logging.log', 'a')
level=ERROR
formatter=simpleFormatter

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

代码如下:

# 读取日志配置文件内容
logging.config.fileConfig('logging.conf')

# 创建一个日志器logger
logger = logging.getLogger('simpleExample')

# 日志输出
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

结果如下:

2017-05-15 11:32:16,539 - simpleExample - DEBUG - debug message
2017-05-15 11:32:16,555 - simpleExample - INFO - info message
2017-05-15 11:32:16,555 - simpleExample - WARNING - warn message
2017-05-15 11:32:16,555 - simpleExample - ERROR - error message
2017-05-15 11:32:16,555 - simpleExample - CRITICAL - critical message

关于fileConfig()函数的说明:

该函数实际上是对configparser模块的封装,关于configparser模块的介绍请参考<>。

函数定义:
	该函数定义在loging.config模块下:

logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)

参数:
	fname:表示配置文件的文件名或文件对象
	defaults:指定传给ConfigParser的默认值
	disable_existing_loggers:这是一个布尔型值,默认值为True(为了向后兼容)表示禁用已经存在的logger,除非它们或者它们的祖先明确的出现在日志配置中;如果值为False则对已存在的loggers保持启动状态。

配置文件格式说明:

上面提到过,fileConfig()函数是对ConfigParser/configparser模块的封装,也就是说fileConfig()函数是基于ConfigParser/configparser模块来理解日志配置文件的。换句话说,fileConfig()函数所能理解的配置文件基础格式是与ConfigParser/configparser模块一致的,只是在此基础上对文件中包含的section和option做了一下规定和限制,比如:

1)配置文件中一定要包含loggers、handlers、formatters这些section,它们通过keys这个option来指定该配置文件中已经定义好的loggers、handlers和formatters,多个值之间用逗号分隔;另外loggers这个section中的keys一定要包含root这个值;
2)loggers、handlers、formatters中所指定的日志器、处理器和格式器都需要在下面以单独的section进行定义。seciton的命名规则为[logger_loggerName]、[formatter_formatterName]、[handler_handlerName]
3)定义logger的section必须指定level和handlers这两个option,level的可取值为DEBUG、INFO、WARNING、ERROR、CRITICAL、NOTSET,其中NOTSET表示所有级别的日志消息都要记录,包括用户定义级别;handlers的值是以逗号分隔的handler名字列表,这里出现的handler必须出现在[handlers]这个section中,并且相应的handler必须在配置文件中有对应的section定义;
4)对于非root logger来说,除了level和handlers这两个option之外,还需要一些额外的option,其中qualname是必须提供的option,它表示在logger层级中的名字,在应用代码中通过这个名字得到logger;propagate是可选项,其默认是为1,表示消息将会传递给高层次logger的handler,通常我们需要指定其值为0,这个可以看下下面的例子;另外,对于非root logger的level如果设置为NOTSET,系统将会查找高层次的logger来决定此logger的有效level。
5)定义handler的section中必须指定class和args这两个option,level和formatter为可选option;class表示用于创建handler的类名,args表示传递给class所指定的handler类初始化方法参数
,它必须是一个元组(tuple)的形式,即便只有一个参数值也需要是一个元组的形式;level与logger中的level一样,而formatter指定的是该处理器所使用的格式器,这里指定的格式器名称必须出现在formatters这个section中,且在配置文件中必须要有这个formatter的section定义;如果不指定formatter则该handler将会以消息本身作为日志消息进行记录,而不添加额外的时间、日志器名称等信息;
6)定义formatter的sectioin中的option都是可选的,其中包括format用于指定格式字符串,默认为消息字符串本身;datefmt用于指定asctime的时间格式,默认为'%Y-%m-%d %H:%M:%S';class用于指定格式器类名,默认为logging.Formatter;

3.使用字典配置信息和dictConfig()函数实现日志配置

首先需要安装PyYAML模块:

pip install PyYAML

logging.yml配置文件的内容:

---
version: 1
disable_existing_loggers: false
formatters:
  simple:
    format: "%(asctime)s - %(levelname)s - %(filename)s : %(message)s"
  special:
    format: "%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s : %(message)s"
handlers:
  basic_console:
    class: logging.StreamHandler
    level: INFO
    formatter: special
    stream: ext://sys.stdout
  debug_file:
    class: logging.handlers.TimedRotatingFileHandler
    level: DEBUG
    formatter: special
    filename: debug.log
    when: D
    interval: 1
    backupCount: 1
  info_file:
    class: logging.handlers.TimedRotatingFileHandler
    level: INFO
    formatter: special
    filename: info.log
    when: D
    interval: 1
    backupCount: 1
  warning_file:
    class: logging.handlers.TimedRotatingFileHandler
    level: WARNING
    formatter: special
    filename: warnning.log
    when: D
    interval: 1
    backupCount: 1
  error_file:
    class: logging.handlers.TimedRotatingFileHandler
    level: ERROR
    formatter: special
    filename: error.log
    when: D
    interval: 1
    backupCount: 1
  normal_app_request:
    class: logging.handlers.TimedRotatingFileHandler
    level: WARNING
    formatter: special
    filename: warnning.log
    when: D
    interval: 1
    backupCount: 1
  error_app_request:
    class: logging.handlers.TimedRotatingFileHandler
    level: ERROR
    formatter: special
    filename: error.log
    when: D
    interval: 1
    backupCount: 1
loggers:
  django_1:
    level: INFO
    handlers:
    - basic_console
    - error_file
    propagate: 'no'

代码如下:

import logging
import logging.config
import yaml

with open('logging.yml', 'r') as f_conf:
    dict_conf = yaml.load(f_conf)
logging.config.dictConfig(dict_conf)

logger = logging.getLogger('django_1')
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

3.总结注意点

1.关于logging.getLogger('django_1')
	name参数与定义的loggers有关,一一对应,即可以实现将不同功能模块的log,使用不同的logger记录到不同的log文件中

参考文档: https://docs.python.org/3.5/library/logging.config.html
参考文档: https://www.cnblogs.com/yyds/p/6885182.html

你可能感兴趣的:(Django框架系列,python,logging)