前言

  django框架的日志通过python内置的logging模块实现的,既可以记录自定义的一些信息描述,也可以记录系统运行中的一些对象数据,还可以记录包括堆栈跟踪、错误代码之类的详细信息。

  logging主要由4部分组成:LoggersHandlersFiltersFormatters

settings中完整的配置

如果想自定义配置日志信息,我们可以在settings.py文件中配置,那配置的格式是怎么样的呢?我们可以通过from django.utils.log import DEFAULT_LOGGING查看Django中默认的日志配置信息,然后依葫芦画瓢即可

  1. LOGGING = {
  2. 'version': 1,
  3. 'disable_existing_loggers': False,
  4. 'incremental':True,
  5. 'filters': {},
  6. 'formatters': {},
  7. 'handlers': {},
  8. 'loggers': {}
  9. }

上述是默认的日志配置信息的格式,我们依次介绍

  • version:配置信息的版本
  • disable_existing_loggers:默认为True,True:设置已存在的logger失效。False:让已存在的logger不失效,保证日志信息完整。一般情况下设置为False
  • incremental:默认为False。True:是将配置解释为现有配置的增量。False:配置会覆盖已有默认配置。一般此项不用配置
  • filter:过滤器
  • formatters:格式器
  • handlers:处理器
  • loggers:日志器

Formatters

  日志记录最终需要呈现为文本,formatter程序描述该文本的确切格式。formatter通常由包含LogRecord属性的Python格式化字符串组成 ; 但是,也可以编写自定义formatter来实现特定的格式化行为。

1.settings中配置:

3个参数(具体看后面的Formatter类):

  • ():指定格式器的类,不指定的话,默认使用logging.Formattr。一般用默认即可
  • format:格式化字符串
  • style:样式选择
  • datefmt:日期格式化字符串,使用的是python中时间日期格式化符号

案例

  1. LOGGING = {
  2. 'formatters': {
  3. 'verbose': {
  4. '()': 'logging.Formatter',
  5. 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
  6. 'style': '{',
  7. },
  8. 'simple': {
  9. 'format': '{levelname} {message}',
  10. 'style': '{',
  11. },
  12. }
  13. }

配置了2个格式器:

  • simple:只输出简单的:日志级别名称 日志消息
  • verbose:输出:日志级别名称 生成日志消息的时间 模块 进程 线程 日志消息

2.内置格式器

Formatter:默认格式器,初始化参数:fmt=None, datefmt=None, style='%'

  • fmt:格式化字符串,指定输出格式,如:'{levelname}{process:d}{message}'
  • datefmt:日期格式化字符串,为None则使用ISO8601格式化,如:'2010-01-01 08:03:26,870'
  • style:'%','{' 或 '$',3选一:
    • '%':默认是这个,使用python%格式化 , 如: %(levelname)s
    • '{':使用 str.format格式化(django框架使用这个), 如:{levelname}
    • '$':使用类string.Template格式化,如:\$levelname

格式化字符串的种类

  1. %(name)s:记录器logger的名称
  2. %(levelno)s:日志级别对应的数字
  3. %(levelname)s:日志级别名称
  4. %(pathname)s:日志记录调用的源文件的完整路径
  5. %(filename)s:日志记录调用的源文件名
  6. %(module)s:模块名
  7. %(lineno)d:日志调用的行数
  8. %(funcName)s:函数名
  9. %(created)f:日志创建时间,time.time()
  10. %(asctime)s:日志创建时间,文本类型
  11. %(msecs)d:日志创建时间的毫秒部分
  12. %(relativeCreated)d:日志创建时间 - 加载日志模块的时间 毫秒数
  13. %(thread)d:线程ID
  14. %(threadName)s:线程名
  15. %(process)d:进程ID
  16. %(processName)s:进程名
  17. %(message)s:日志消息

Filters

过滤器filter用于提供对日志记录从logger传递到handler的附加控制

​默认情况下,loggerhandler将处理满足日志级别要求的任何日志消息,但是,通过安装filter,可以在日志记录过程中添加其他条件。例如,可以安装仅允许ERROR级别 来自特定源的消息的filter。

​filter还可用于在发出之前修改日志记录。例如,如果满足一组特定条件,可以编写一个过滤器,将ERROR日志记录降级为WARNING记录。

​filter可以安装在loggerhandler上; 可以在链中使用多个filter来执行多个过滤操作。

1.settings中配置

  1. LOGGING = {
  2. 'filters': {
  3. 'require_debug_false': {
  4. '()': 'django.utils.log.RequireDebugFalse',
  5. },
  6. 'require_debug_true': {
  7. '()': 'django.utils.log.RequireDebugTrue',
  8. },
  9. },
  10. }

配置了2个过滤器

  • require_debug_false:使用类:RequireDebugFalse
  • require_debug_true:使用类:RequireDebugTrue

Handlers

  这个类是确定logger中消息发生的引擎程序,描述特定的日志记录行为,譬如控制台打印、写入日志文件、通过网络进行发送等

  与logger一样,handler也具有日志级别,如果日志记录的日志级别未达到或超过handler的级别,则handler将忽略该消息。

  一个logger可以有多个handler,每个handler可以有不同的日志级别和记录方法

1.settings中配置

4个参数(如下),加上对应class类的初始化参数

  • class(必需):处理程序类的名称
  • level(可选的):处理程序的级别
  • formatter(可选的):处理程序的格式化程序
  • filters(可选的):处理程序的过滤器的列表

2.内置处理器

  1. python3的logging中的handler

    • StreamHandler:输出到stream,未指定则使用sys.stderr输出到控制台

    • FileHandler:继承自StreamHandler,输出到文件,默认情况下,文件无限增长

      初始化参数:filename,mode ='a',encoding = None,delay = False

      delay如果为True,那么会延迟到第一次调用emit写入数据时才打开文件

      1. 'handlers': {
      2. 'file': {
      3. 'level': 'DEBUG',
      4. 'class': 'logging.FileHandler',
      5. 'filename': '/path/to/django/app.log', #参数配置在这里,多个参数按顺序继续配置即可, 如果要添加encoding,那么在下面添加 encoding: 'utf-8' 即可
      6. },
      7. }
    • RotatingFileHandler:自动按大小切分的log文件(常用)

      初始化参数:filename,mode ='a',maxBytes = 0,backupCount = 0,encoding = None,delay = False

      maxBytes:最大字节数,超过时创建新的日志文件,如果backupCountmaxBytes有一个为0,那么就一直使用一个文件

      backupCount:最大文件个数,新文件的扩展名是指定的文件后加序号".1"等,譬如:backupCount=5,基础文件名为:app.log,那么达到指定maxBytes之后,会关闭文件app.log,将app.log重命名为app.log.1,如果app.log.1存在,那么就顺推,先将 app.log.1重命名为app.log.2,再将现在的app.log命名为app.log.1,最大创建到app.log.5(旧的app.log.5会被删除),然后重新创建app.log文件进行日志写入,也就是永远只会对app.log文件进行写入。

    • TimedRotatingFileHandler:按时间自动切分的log文件,文件后缀 %Y-%m-%d_%H-%M-%S

      初始化参数:filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None

      when:时间间隔类型,不区分大小写

      1. 'S':秒
      2. 'M':分钟
      3. 'H':小时
      4. 'D':天
      5. 'W0'-'W6':星期几(0 = 星期一)
      6. 'midnight':如果atTime未指定,则在 000 翻转,否则在atTime时间翻转

      interval:间隔的数值

      backupCount: 文件个数

      encoding:编码

      delay:True是写入文件时才打开文件,默认False,实例化时即打开文件

      utc:False则使用当地时间,True则使用UTC时间

      atTime:必须是datetime.time实例,指定文件第一次切分的时间,when设置为S,M,H,D时,该设置会被忽略

    • SMTPHandler:通过email发送日志记录消息

      初始化参数:mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=5.0

      mailhost:发件人邮箱服务器地址(默认25端口)或地址和指定端口的元组,如:('smtp.163.com', 25)

      fromaddr:发件人邮箱

      toaddrs:收件人邮箱列表

      subject:邮件标题

      credentials:如果邮箱服务器需要登录,则传递(username, password)元组

      secure:使用TLS加密协议

Loggers

1.settings中配置

通过在settings中配置LOGGING配置项实现日志配置,共4个配置项(都是可选的,不过一般会指定handler):

  • level:指定记录日志的级别,没有配置则处理所有级别的日子
  • propagate:设置该记录器的日志是否传播到父记录器,不设置则是True
  • filters:指定过滤器列表
  • handlers:指定处理器列表

示例如下:

  1. LOGGING = {
  2. 'version': 1, # 固定值,现在只有这一个版本
  3. 'disable_existing_loggers': False, # 设置已存在的logger不失效
  4. 'loggers': {
  5. '': {
  6. 'handlers': ['console'],
  7. },
  8. 'django': {
  9. 'handlers': ['console'],
  10. 'propagate': True,
  11. },
  12. 'django.request': {
  13. 'handlers': ['mail_admins'],
  14. 'level': 'ERROR',
  15. 'propagate': False,
  16. },
  17. 'myproject.custom': {
  18. 'handlers': ['console', 'mail_admins'],
  19. 'level': 'INFO',
  20. 'filters': ['special']
  21. }
  22. }
  23. }

配置了4个 logger, 分别对应2个不同的handler(console输出日志到控制台,mail_admins输出日志到邮件)

  • '':默认的记录器,不指定特定名称,那么就是使用这个记录器,没有配置level,那么就是处理所有级别的日志,传递所有级别的日志到console控制器
  • django:传递所有级别的日志到console控制器
  • django.request:django记录器的子记录器,处理ERROR级别及以上的日志,propagate设置为 False,表明不传播日志给 "django",该logger传递日志到mail_admins控制器
  • myproject.custom:处理INFO级别及以上的日志,应用了一个 special 的过滤器来过滤日志,传递日志到2个控制器(['console', 'mail_admins'])处理

注意

django框架有个默认的配置:DEFAULT_LOGGING,一旦配置了自己的LOGGING后,那么所有的默认的LOGGER全部都失效,失效不等于没有记录器了,而是说记录器不起作用了,即不会记录日志,也不会将日志传播给父记录器。因此你应该非常小心使用,因为你会感觉你丢了日志一样,可以手动设置同名的logger实现覆盖,如:

  1. LOGGING = {
  2. 'version': 1,
  3. 'disable_existing_loggers': False,
  4. 'loggers': {
  5. # 覆盖了 django 记录器,所有django的记录日志最后全部写入到文件中
  6. 'django': {
  7. 'handlers': ['file'],
  8. 'level': 'DEBUG',
  9. 'propagate': True,
  10. },
  11. },
  12. }

2.django内置的logger

  内置的logger在django项目运行中会自动记录日志,与我们手动创建的logger的执行没有关系,除非我们也创建相同的logger

django框架调用的地方在:django.core.servers.basehttp中(如WSGIRequestHandler)

  • django:django框架中所有消息的记录器,一般使用它的子记录器,而不是它发布消息,因为默认情况下子记录器的日志会传播到根记录器django,除非设置 'propagate': False
  • django.request:记录与请求处理相关的消息。5XX响应作为ERROR消息; 4XX响应作为WARNING消息引发。记录到django.security记录器的请求不会记录到django.request

发送给此记录器的消息具有以下额外上下文:

  • status_code:与请求关联的HTTP响应代码

  • request:生成日志消息的请求对象。

  • django.server:记录与runserver命令调用的服务器接收的请求的处理相关的消息。5XX响应记录为ERROR 消息,4XX响应记录为WARNING消息,其他所有响应记录为INFO

    发送给此记录器的消息具有以下额外上下文:

    • status_code:与请求关联的HTTP响应代码
    • request:生成日志消息的请求对象。
  • django.template:记录与模板呈现相关的消息

  • django.db.backends:记录代码和数据库交互相关的消息

  • django.security.*:记录任何SuspiciousOperation和其他安全相关错误(django.security.csrf )的消息

  • django.db.backends.schema:记录数据库迁移过程中的日志,但是不记录执行的查询SQL语句等,发送给此记录器的消息具有以下额外上下文:

    • sql:已执行的SQL语句。
    • params:SQL调用中使用的参数

实战案例

如果你对以上的介绍觉得写得很乱又复杂,没关系,下面直接教你在项目中如何使用,基本就3种用法

  • 通过文件分割日志
  • 通过时间分割日志
  • 通过邮箱发送日志

案例1:通过文件分割日志

首先配置settings.py中的logging,代码如下

  1. BASE_LOG_DIR = os.path.join(BASE_DIR, 'log')
  2. LOGGING = {
  3. 'version': 1,
  4. 'disable_existing_loggers': False, # 设置已存在的logger不失效
  5. 'filters': {},
  6. 'formatters': {
  7. 'standard': {
  8. 'format': '[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d:%(funcName)s]:%(message)s',
  9. 'datefmt': '%Y-%m-%d %H:%M:%S'
  10. },
  11. 'simple':{
  12. 'format':'[%(asctime)s][%(levelname)s]:%(message)s',
  13. 'datefmt': '%Y-%m-%d %H:%M:%S'
  14. }
  15. },
  16. 'handlers': {
  17. 'console': {
  18. 'level': 'DEBUG',
  19. 'class': 'logging.StreamHandler',
  20. 'formatter': 'simple'
  21. },
  22. 'default': {
  23. 'level': 'DEBUG',
  24. 'class': 'logging.handlers.RotatingFileHandler',
  25. 'filename': os.path.join(BASE_LOG_DIR, 'debug.log'),
  26. 'maxBytes': 1024 * 1024 * 50, # 日志大小50M
  27. 'backupCount': 5,
  28. 'formatter': 'standard',
  29. 'encoding': 'utf-8',
  30. },
  31. },
  32. 'loggers': {
  33. 'django': {
  34. 'handlers': ['console', 'default'],
  35. 'level': 'INFO',
  36. 'propagate': True
  37. },
  38. },
  39. }

接下来在views.pyurls.py函数中写入函数,代码如下

  1. # urls.py
  2. urlpatterns = [
  3. path('', views.index, name="index"),
  4. ]
  5. # views.py
  6. logger = logging.getLogger('django')
  7. def index(request):
  8. logger.debug('debug 测试')
  9. logger.info('info 测试')
  10. logger.warning('warning 测试')
  11. logger.error('error 测试')
  12. return HttpResponse('success')

然后我们访问127.0.0.1/logging/,我们可以看到控制台的代码

  1. Starting development server at http://127.0.0.1:8000/
  2. Quit the server with CONTROL-C.
  3. [2021-05-30 15:03:09][INFO]:info 测试
  4. [2021-05-30 15:03:09][WARNING]:warning 测试
  5. [2021-05-30 15:03:09][ERROR]:error 测试
  6. [2021-05-30 15:03:09][INFO]:"GET /logging/ HTTP/1.1" 200 7

这是因为我们在django记录器中配置了console控制器,格式要求也是符合我们所写的,接着查看项目的log目录下会新增了一个debug.log这样一个日志文件,文件内容如下

  1. [2021-05-30 15:03:04][INFO][autoreload.py:578:run_with_reloader]:Watching for file changes with StatReloader
  2. [2021-05-30 15:03:09][INFO][views.py:12:index]:info 测试
  3. [2021-05-30 15:03:09][WARNING][views.py:13:index]:warning 测试
  4. [2021-05-30 15:03:09][ERROR][views.py:14:index]:error 测试
  5. [2021-05-30 15:03:09][INFO][basehttp.py:154:log_message]:"GET /logging/ HTTP/1.1" 200 7

debug.log日志输出格式更加详细,这是因为我们在default控制器中,使用的standard格式器。

总结:以上就是我们最常用的一种日志配置---文件日志,当中的细节例如格式啊等等的可以自己更改

案例2:时间分割日志

代码设置如下:

  1. 'time_handler': {
  2. 'level': 'INFO',
  3. 'class': 'logging.handlers.TimedRotatingFileHandler',
  4. 'filename': os.path.join(BASE_LOG_DIR, "time.log"),
  5. 'when': 'S',
  6. 'interval': 10,
  7. 'backupCount': 5,
  8. 'formatter': 'standard',
  9. 'encoding': 'utf-8',
  10. }

以上设置为间隔10秒,生成一个日志文件

案例3:日志邮箱发送

代码设置如下:

  1. 'email_handler': {
  2. 'level': 'ERROR',
  3. 'class': 'logging.handlers.SMTPHandler',
  4. 'formatter': 'standard',
  5. 'mailhost': ('smtp.163.com', 25),
  6. 'fromaddr': 'xxxx@163.com',
  7. 'toaddrs': ['xxx@qq.com'],
  8. 'subject': 'test',
  9. 'credentials': ('邮箱用户名', '邮箱密码'),
  10. },

接下来出现ERROR级别的日志,就会发送邮件,如果你出现报错代码为550,那么就是你邮箱的权限没有开通,到邮箱的设置中开启SMTP服务即可

Django(37)配置django日志的更多相关文章

  1. Django中配置自定义日志系统

  2. Windows10下Apache2.4配置Django

    开发环境 Windows 10 x64 Apache 2.4 x64 Python 2.7.11 x64 Django 1.9.6+ 下载和安装mod_wsgi 到 http://download.c ...

  3. Django中配置用Redis做缓存和session

    django-redis文档: http://django-redis-chs.readthedocs.io/zh_CN/latest/# 一.在Django中配置 # Django的缓存配置 CAC ...

  4. Django Redis配置

    Django Redis配置 # Django默认不支持redis,需要第三方插件来支持 pipenv install django-redis pipenv install hiredis # 不是 ...

  5. 【python小随笔】Django+错误日志(配置Django报错文件指定位置)

    1:  自定义日志文件.py----------几个文件需要创建日志,就需要重新定义几份 # 定义一个日志文件 创建一个操作日志对象logger file_1 = logging.FileHandle ...

  6. Docker部署Django项目+Nginx+Fluend日志收集 和redis、memcached、RabbitMQ、Celery

    前言 一.docker 1.docker是什么? Docker的英文本意是“搬运工”,Docker搬运的是集装箱(Container)可以成为容器,我可以把写的Django的WEB应用以及Python ...

  7. ModelViewSet 路由 / django logging配置 / django-debug-toolbar使用

    一.ModelViewSet 路由 因为我们正在使用ViewSet代替View,实际上已经不再需要自己来设计URL的配置了.将资源和视图.URL绑定到一起是一个可以自动完成的过程,只需要使用Route ...

  8. Django应用:学习日志网站

    目录 一.创建虚拟环境(Windows) 二.创建项目 三.创建应用程序 四.创建网页:学习笔记主页 五.创建其他网页 六.用户输入数据 七.用户账户 八.让用户拥有自己的数据 九.设置应用程序样式 ...

  9. python 全栈开发,Day96(Django REST framework 视图,django logging配置,django-debug-toolbar使用指南)

    昨日内容回顾 1. Serializer(序列化) 1. ORM对应的query_set和ORM对象转换成JSON格式的数据 1. 在序列化类中定义自定义的字段:SerializerMethodFie ...

随机推荐

  1. Day14_83_反射机制获取某个特定属性的各部分

    反射机制获取某个特定属性的各部分 * 通过属性名(变量名)来获取一个属性整体 例如: Field userNoField=c.getDeclaredField("userNo"); ...

  2. k8s service NodePort 方式向外发布

    k8s service NodePort 方式向外发布 k8s 无头service 方式向内发布 k8s service 服务发现 {ServiceName}.{Namespace}.svc.{Clu ...

  3. IPC 方法分类

    IPC 方法分类 进程间通信 shell out 被调用程序在执行完毕之前接管用户的键盘和显示,退出后,调用程序重新控制键盘和显示并继续运行. 专门程序通常有文件系统与父进程进行通信,方法是在指定位置 ...

  4. 1148 Werewolf - Simple Version

    Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and th ...

  5. (转)Amazon Aurora MySQL 数据库配置最佳实践

    转自:https://zhuanlan.zhihu.com/p/165047153 Amazon Aurora MySQL 数据库配置最佳实践 AWS云计算 ​ 已认证的官方帐号 1 人赞同了该文章 ...

  6. 数据库的读写分离(Amoeba)

    目录 Amoeba Amoeba读写分离的配置 Amoeba Amoeba(变形虫) 项目,该开源框架于2008年开始发布一款 Amoeba for Mysql软件. 这个软件基于Java致力于MyS ...

  7. IPS入侵防御系统

    目录 IPS入侵防御系统 如何才能更好的防御入侵 IPS与IDS的区别 IDS与IPS的部署 IPS独立部署 IPS分布式部署 IPS入侵防御系统 IPS(Intrusion Prevention S ...

  8. Open VAS 漏扫工具的安装

    wget -q -O - http://www.atomicorp.com/installers/atomic |sh .安装openvas [root@localhost ~]#yum -y ins ...

  9. PHP 通用格式化调试函数

    /** * 打印调试函数 * @param $content * @param $is_die */function pre($content, $is_die = true){ header('Co ...

  10. Windows进程间通讯(IPC)----内存映射文件

    内存映射文件原理 内存映射文件是通过在虚拟地址空间中预留一块区域,然后通过从磁盘中已存在的文件为其调度物理存储器,访问此虚拟内存空间就相当于访问此磁盘文件了. 内存映射文件实现过程 HANDLE hF ...