【Djngao基础】日志记录

1.日志核心组件

1.1 记录器对象-logger

在日志系统中,根据日志的重要性,将日志换分为5个等级:

  • DEBUG:调试信息,也是最详细的日志信息,记录项目中任何发生的事,多用于调测;
  • INFO:重要信息,记录业务流程中的重要节点信息;
  • WARNING:警告日志,记录可能影响系统正常运行或可能出现的警告信息;
  • ERROR:错误日志,记录系统运行时异常信息和业务数据错误信息;
  • CRITICAL:严重错误信息,记录可能导致软件崩溃的信息。
    在操作日志中都会记录日志级别和描述信息。设置日志级别后,其中低于该日志级别的日志会被忽略。比如设置日志级别为INFO,则DEBUG信息会被忽略。

下面示例是logger对象的简单使用:

import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.debug("这是debug信息")
logger.info("这是info信息")
logger.warning("这是warning信息")
logger.error("这是error信息")
logger.critical("这是critical信息")

1.2 操作对象-handler

操作对象用于对记录到日志容器logger种的日志信息进行后续处理。

操作对象完全支持日志级别的处理方式,可以按照日志级别对象数据进行隔离处理。操作对象还支持多种操作同时进行,比如将日志信息打印到屏幕上、将日志信息存储到指定文件中和将日志信息提交到远程服务器上三种操作同时进行。

1.3 过滤器对象-filter

过滤器对象是工作在记录器对象和操作对象时间的一个中间组件,通过过滤器为日志记录添加更多额外功能。

1.4 格式化对象-formatter

格式化对象用于对日志信息进行自定义,优化日志文件内容。
重要的格式符如下:

  • %(levalno)s:打印日志级别对应的整数数值;
  • %(levelname)s:打印日志级别的名称信息;
  • %(pathname)s:打印当前正在执行程序的程序路径;
  • %(filename)s:打印当前正在执行程序的名称或文件名;
  • %(funcName):打印当前日志记录执行操作的函数名称;
  • %(lineno)d:打印当前日志记录执行操作的代码行号;
  • %(asctime)s:打印当前日志记录执行操作的时间;
  • %(thread)d:打印当前日志记录执行操作的线程编号;
  • %(threadName)s:打印正在执行的线程名称;
  • %(process)d:打印当前正在执行的进程编号;
  • %(message):打印日志描述信息。

2.Django中的日志操作

2.1 命名空间结构化管理

在Django中可以通过父子节点路径隔离方式来进行日志管理,不过是通过记录器对象的命名规则进行管理的,也就是记录器对象的命名空间节点。
一般日志记录器对象的命名规则是:项目名.模块名.类型名称
例如:
项目的根管理项目中,日志记录器对象的命名规则如下:

logger = logging.getLogger('project.root.views')

在项目的用户模块中,日志记录器对象的命名规则如下:

logger = logging.getLogger('project.user.User')
logger = logging.getLogger('project.user.UserProfile')
logger = logging.getLogger('project.user.UserStatus')

这样,根据不同的过滤器对象,可以得到不同模块输出的日志信息。

2.2 记录到控制台的日志配置规则
在Django项目中可以根据配置,将日志输出到指定的存储对象中。
如下配置,把日志输出控制台进行展示:

LOGGING = {
    # 版本
    'version': 1,
    # 禁用已经存在的日志
    'disable_existing_loggers': True,
    # 配置日志格式化对象
    'formatters': {
        # 配置标准日志格式
        'verbose': {
            'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
            'style': '{',
        },
      	# 配置简单格式
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    # 配置日志操作对象
    'handlers': {
      	# 定义控制台操作选项,通过变量命名console
        'console': {
            # 'level': 'DEBUG',
          	# 指定操作类型
            'class': 'logging.StreamHandler',
            # 指定记录格式,使用verbose标准日志格式记录日志
            'formatter': 'verbose'
        },
    },
  	# 配置日志记录器对象
    'loggers': {
      	# 声明使用记录器django
        'django': {
          	# 指定操作对象,可以是一个或多个
            'handlers': ['console'],
            # 'propagate': True,
          	# 配置日志记录级别
            'level': 'DEBUG',
        },
    }
}

2.3 记录到文件的日志配置规则

记录到控制台比较适合开发阶段,在生产环境通常将日志按照规则记录到文件中。
配置如下:

LOGGING = {
    # 日志记录配置版本信息
    'version': 1,
    # 启用已有日志配置信息
    'disable_existing_loggers': False,
    # 配置日志格式化对象:定义消息格式
    'formatters': {
        # 定义标准消息格式
        'verbose': {
            'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
            'style': '{',
        },
        # 定义简化消息格式,用于控制台操作
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    # 配置日志操作对象
    'handlers': {
        # 配置文件日志处理程序
        'file': {
            # 记录DEBUG级别及以上日志
            'level': 'DEBUG',
            # 使用标准消息格式进行记录
            'formatter': 'standard',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, 'log/blog.log'),
            # 备份文件数量
            'backupCount': 10,
            # 设置每个文件存储的最大体积
            'maxBytes': 1024 * 1024 * 1024 * 10,
        },
    },
    # 配置日志记录器对象
    'loggers': {
        'django': {
            'handlers': ['console', 'file'],
            'propagate': True,
            'level': 'DEBUG'
        }
    }
}

在日志处理过程中,可以将所有日志记录到一个文件中,也可以按照时间间隔拆分文件记录,还可以按照文件大小拆分文件记录。具体的操作方式在handlers的file配置的class里。

Django提供了如下操作方式:

  • logging.FileHandler 普通日志,将日志记录到一个文件中
  • logging.handlers.RotatingFileHandler 按照文件大小拆分文件记录日志
  • logging.handlers.TimedRotatingFileHandler 按照时间间隔拆分文件记录日志
  • logging.handlers.WatchedFileHandler 按照日志是否被查看占用拆分文件记录日志
  • logging.handlers.SockerHandler 将日志添加到Socket管道中进行传输记录
  • logging.handlers.DatagramHandler 通过UDP对日志进行传输记录
  • logging.handlers.SMTPHandler 通过SMTP对日志进行传输记录
  • logging.handlers.HTTPHandler 通过GET/POST方式对日志进行网络记

2.4 日志模块API
2.4.1 记录器对象logger
上面的例子中我们使用的记录器对象是django、django.request、myproject.custom。其中django、django.request是内建的记录器对象。下面看看Django中有哪些内建的记录器对象。

  • django:抓取所有日志的顶层记录器对象。
  • django.request:处理与请求相关的日志信息。发送给这个记录器对象的消息区分上下文响应状态码和请求对象。比较特殊的是,5xx状态码记录ERROR级别的日志信息,4xx状态码记录WARNING级别的日志。
  • django.server:专门记录与开发服务器runserver接口请求相关的处理消息。比较特殊的是,5xx状态码记录ERROR级别的日志信息,4xx状态码记录WARNING级别的日志,其他记录INFO级别的日志信息。
  • django.template:专门记录与模板相关的日志信息。
  • django.db.backends:专门用于记录与数据交互相关的日志信息。SQL语句记录为DEBUG级别的日志,必须设置配置文件的调试模式settings.DEBUG=True,才能启用该记录器对象的日志信息,但是不包含框架初始化日志信息和实物管理查询信息。
  • django.security:安全认证日志记录器对象,用于记录与Suspiciousoperatio以及其他安全相关错误信息。

2.4.2 handler处理程序
除了上述日志模块提供的日志处理程序,Django框架内建一些原生都得日志处理功能,提供了基本的日志数据处理方式。比如django.utils.log.AdminEmailHandler类型的实例可以将重要信息发送到管理员邮箱。
2.4.3 Django的默认日志配置
在不进行任何编码和配置的情况下,Django框架中的默认日志生效。
通常Django框架中的错误日志输出与DEBUG配置相关:
如果设置DEBUG=True,则表示将所有的日志信息都传送到django记录器对象,并输出INFO级别或高于INFO级别的日志信息。
如果设置DEBUG=False,则表示django记录器对象将ERROR或者CRITICAL级别的日志信息传送到AdminEmailHandler邮件处理程序中进行处理,并将该级别日志发送到管理员邮箱。
3.日志实战
在实际开发中,会将多种日志处理方式合理添加到真个业务流程中。以我们前面的博客项目为例,日志配置如下:

LOGGING = {
    # 日志记录配置版本信息
    'version': 1,
    # 启用已有日志配置信息
    'disable_existing_loggers': False,
    # 配置日志格式化对象:定义消息格式
    'formatters': {
        # 定义标准消息格式
        'standard': {
            'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
            'style': '{',
        },
        # 定义简化消息格式,用于控制台操作
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    # 配置过滤器
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    # 配置定义处理程序
    'handlers': {
        # 配置控制台日志处理程序
        'console': {
            # 记录INFO级别及以上日志
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            # 使用建议日志格式消息
            'formatter': 'simple'
        },
        # 配置文件日志处理程序
        'file': {
            # 记录DEBUG级别及以上日志
            'level': 'DEBUG',
            # 使用标准消息格式进行记录
            'formatter': 'standard',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, 'log/blog.log'),
            # 备份文件数量
            'backupCount': 10,
            # 设置每个文件存储的最大体积 10G
            'maxBytes': 1024 * 1024 * 1024 * 10,
        },
        # 配置邮件处理程序
        'mail_admins': {
            # 记录ERROR级别及以上日志
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    # 配置日志记录器对象
    'loggers': {
        'django': {
            'handlers': ['console', 'file'],
            'propagate': True,
            'level': 'DEBUG'
        },
        'django.request': {
            'handlers': ['mail_admins', 'file'],
            'level': 'ERROR',
            'propagate': False,
        },
        'myproject.custom': {
            'handlers': ['console', 'mail_admins', 'file'],
            'level': 'INFO',
        }
    }
}

案例:

日志配置

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
        },
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            # 日志位置,日志文件名,日志保存目录必须手动创建
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/luffy.log"),
            # 日志文件的最大值,这里我们设置300M
            'maxBytes': 300 * 1024 * 1024,
            # 日志文件的数量,设置最大日志数量为10
            'backupCount': 10,
            # 日志格式:详细格式
            'formatter': 'verbose'
        },
    },
    # 日志对象
    'loggers': {
        'django': {
            'handlers': ['console', 'file'],
            'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
        },
    }
}
posted @ 2023-11-25 15:05  小C学安全  阅读(34)  评论(0编辑  收藏  举报