• Django 之 logging


    1. logging

    1.1 什么是 logging

    logging 模块是 Python 内置的日志管理模块,不需要额外安装。

    使用:

    import logging
    
    logging.critical('this is critical msg')
    logging.error('this is error msg')
    logging.warning('this is warning msg')
    logging.info('this is info msg')
    

    运行结果如下:

    CRITICAL:root:this is critical msg
    ERROR:root:this is error msg
    WARNING:root:this is warning msg
    

    默认只输出 warning 以上级别的日志,日志级别:

    CRITICAL(严重错误) > ERROR > WARNING(默认) > INFO > DEBUG > NOTSET

    默认日志格式:

    LOGLEVEL:LOGGERNAME:msg
    

    1.2 logging 模块中的几个重要概念

    logging 中不得不知道的几个概念:LoggerHandlerFormatterFilter

    • Logger 记录器:暴露了应用程序代码能直接使用的接口。
    • Handler 处理器:将(记录器产生的)日志记录发送至合适的目的地。
    • Filter 过滤器:提供了更好的粒度控制,它可以决定输出哪些日志记录。
    • Formatter 格式化器:指明了最终输出中日志记录的布局。

    Logger 记录器

    使用接口debug,info,warn,error,critical之前必须创建Logger实例:

    # 创建 Logger 实例
    logger = logging.getLogger(logger_name)
    

    如果没有创建 Logger 实例,那么默认创建一个 root logger,且默认日志级别为 warning,处理器为 StreamHandler(即将日志信息打印输出在屏幕上),输出格式为一个简单的使用程序输出格式。

    logger 实例其他操作:

    logger.setLevel(logging.ERROR)	 	# 设置日志级别
    logger.addHandler(handler_name) 	# 为Logger实例增加一个处理器
    logger.removeHandler(handler_name) `# 为Logger实例删除一个处理器
    

    Handler 处理器

    常用 Handler 处理器有 :StreamHandlerFileHandlerNullHandler

    创建方法:

    # StreamHandler
    sh = logging.StreamHandler(stream=None)
    
    # FileHandler
    fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)
    
    # NullHandler
    # 不做任何的格式化或者输出的 handler
    

    根据处理器对象,可以设置日志级别、格式化日志增加或删除过滤器等操作:

    sh.setLevel(logging.WARN) 			# 指定日志级别,低于WARN级别的日志将被忽略
    sh.setFormatter(formatter_name)		 # 设置一个格式化器formatter
    sh.addFilter(filter_name)			 # 增加一个过滤器,可以增加多个
    sh.removeFilter(filter_name) 		# 删除一个过滤器
    

    Handler 类型及作用:

    类型 说明
    logging.StreamHandler 指定向流对象进行
    logging.FileHandler 指定文件
    logging.handlers.RotaingFileHandler 指定文件,但可管理文件大小,当超过指定值后则重新创建日志文件
    logging.handlers.TimedRotatingFileHandler 指定文件,超过指定周期后重新创建日志文件
    logging.handlers.SocketHandler 指定socket
    logging.handlers.SyslogHandler 指定syslog服务器
    logging.handlers.HTTPHandler 使用post/get请求提交数据到web服务器

    更多关于 Handler 可以访问 Python logging.handlers


    Formatter 格式化器

    Formatter 格式化器可以用来指定日志输出格式,默认的时间格式为 %Y-%m-%d %H:%M:%S

    创建方法:

    # fmt:消息的格式化字符串,datefmt:日期字符串,若不指定 fmt,将使用'%(message)s'。若不指定 datefmt,将使用ISO8601日期格式
    formatter = logging.Formatter(fmt=None, datefmt=None)
    
    # 示例,指定输出当前时间、日志等级名字、线程名、消息
    fmt = logging.Formatter('%(asctime)s - %(levelname)s - %(threadName)s - %(message)s')
    fh = logging.FileHandler('/tmp/test.log')  
    

    格式化参数:

    参数 说明
    %(name)s Logger的名字
    %(levelno)s 数字日志级别
    %(levelname)s 文本日志级别
    %(pathname)s 调用日志输出函数的模块文件路径
    %(filenames)s 调用日志输出函数的模块文件名
    %(module)s 调用日志输出函数的模块名
    %(funcName)s 调用日志输出函数的函数名
    %(lineno)d 调用日志输出函数语句所在行号
    %(created)f 当前时间
    %(relativeCreated)d 当前时间
    %(asctime)s 当前时间,格式’2015-05-28 20:50:03,345’
    %(thread)d 线程id
    %(threadName)s 线程名
    %(process)d 进程id
    %(message)s 消息

    Filter 过滤器

    进行更为复杂的日志过滤,只允许特定 Logger 层次以下的事件通过。

    创建方法:

    filter = logging.Filter(name='')
    
    

    Tips

    Logger 是一个树状结构,它可以有多个处理器,一个处理器也可以有多个格式化器或过滤器,且日志级别可继承


    示例

    import logging
    
    logger = logging.getLogger()
    
    # 控制台 handler 对象,标准输出
    # sh = logging.StreamHandler()
    fh = logging.FileHandler(filename='test.log')
    
    # 当前时间、日志等级名字、线程名、消息
    fmt = logging.Formatter('%(asctime)s - %(levelname)s - %(threadName)s - %(message)s')
    
    # 将格式添加到对象中
    # sh.setFormatter(fmt)
    fh.setFormatter(fmt)
    
    # 添加到 logger 中
    # logger.addHandler(sh)
    logger.addHandler(fh)
    logger.warning('This is a warning log...')
    
    

    1.3 配置方式

    logging 模块支持自定义配置,配置方式有:

    • basicConfig:简单配置
    • dictConfig:通过字典进行配置
    • fileConfig:通过一个文件进行配置
    • listen:通过一个端口进行配置

    以上配置方式非必须,可以不使用以上方式配置,而直接调用 Logger 实例。


    basicConfig

    logging.basicConfig(level=logging.DEBUG, format='', datefmt='',	 filemode='', filename='', stream='')
    
    # 示例
    logging.basicConfig(filename='logger.log', level=logging.INFO)
    
    

    参数:

    关键字 描述
    filename 创建一个 FileHandler,使用指定的文件名
    filemode 如果指明了文件名,指明打开文件的模式(如果没有指明filemode,默认为 a)
    format 指定日志输出格式
    datefmt 指定日志输出时间/日期格式
    level 指定日志等级
    stream 创建 StreamHandler。与 filename 不兼容,如果两个都有,stream 被忽略

    2. 在 Django 中使用 logging

    Django 使用 Python 自带的 logging 模块作为日志打印工具。

    日志级别:infodebugerrorwarningCRITICAL

    logging 是线程安全的,其主要由以下四部分组成:

    • Logger(记录器) :用户使用的直接接口,将日志传递给 Handler
    • Handler(处理器) :控制日志输出到哪里,consolefile 等(一个logger可以有多个Handler
    • Filter(过滤器) :控制哪些日志可以从logger流向 Handler
    • Formatter(格式化器) :控制日志的格式

    在 Django 中使用 logging

    settings.py 最后添加如下代码:

    BASE_LOG_DIR = os.path.join(BASE_DIR, "log")
    LOGGING = {
        'version': 1,  # 保留字
        'disable_existing_loggers': False,  # 禁用已经存在的logger实例
        # 日志文件的格式
        'formatters': {
            # 详细的日志格式
            'standard': {
                'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
                          '[%(levelname)s][%(message)s]'
            },
            # 简单的日志格式
            'simple': {
                'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
            },
            # 定义一个特殊的日志格式
            'collect': {
                'format': '%(message)s'
            }
        },
        # 过滤器
        'filters': {
            'require_debug_true': {
                '()': 'django.utils.log.RequireDebugTrue',
            },
        },
        # 处理器
        'handlers': {
            # 在终端打印
            'console': {
                'level': 'DEBUG',
                'filters': ['require_debug_true'],  # 只有在Django debug为True时才在屏幕打印日志
                'class': 'logging.StreamHandler',  
                'formatter': 'simple'
            },
            # 默认的
            'default': {
                'level': 'INFO',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
                'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
                'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
                'backupCount': 3,  # 最多备份几个
                'formatter': 'standard',
                'encoding': 'utf-8',
            },
            # 专门用来记错误日志
            'error': {
                'level': 'ERROR',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
                'filename': os.path.join(BASE_LOG_DIR, "xxx_err.log"),  # 日志文件
                'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
                'backupCount': 5,
                'formatter': 'standard',
                'encoding': 'utf-8',
            },
            # 专门定义一个收集特定信息的日志
            'collect': {
                'level': 'INFO',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
                'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
                'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
                'backupCount': 5,
                'formatter': 'collect',
                'encoding': "utf-8"
            }
        },
        'loggers': {
           # 默认的logger应用如下配置
            '': {
                'handlers': ['default', 'console', 'error'],  # 上线之后可以把'console'移除
                'level': 'DEBUG',
                'propagate': True,  # 向不向更高级别的logger传递
            },
            # 名为 'collect'的logger还单独处理
            'collect': {
                'handlers': ['console', 'collect'],
                'level': 'INFO',
            }
        },
    }
    
    

    在视图中使用 logging

    from django.shortcuts import render, HttpResponse
    import logging
    
    
    # 生成一个以当前文件名为名字的logger实例
    logger = logging.getLogger(__name__)
    
    # 生成一个名为collect的logger实例
    collect_logger = logging.getLogger("collect")
    
    def index(request):
        logger.debug("debug1。。。。")
        logger.info("info1。。。。")
        logger.debug("debug2")
    
        collect_logger.info("用户:rose")
    
        return HttpResponse("OK")
    
    

    运行流程

  • 相关阅读:
    Linux中history执行历史命令方法
    Linux中返回上一次目录
    Linux的vi编辑模式下常用快捷键
    [Android] TextView上同时显示图标和文字
    [Android] macOS的Android Studio快捷键
    [Android] 转-RxJava+MVP+Retrofit+Dagger2+Okhttp大杂烩
    [iOS] 测试设备解决自签名证书问题
    [macOS] keychain的跳坑之旅!git拉取的权限问题
    [PHP] swoole在daemonize模式下,chdir失效问题
    [macOS] macOS下,VirtualBox安装CentOS7.4, 搭建nginx, mysql, PHP5.6&PHP7.1
  • 原文地址:https://www.cnblogs.com/midworld/p/11002829.html
Copyright © 2020-2023  润新知