django 日志系统

来源:互联网 发布:如何开发一门编程语言 编辑:程序博客网 时间:2024/05/23 19:27

我的代码:

1.settings.py文件中

#django日志系统LOGGING = {    'version': 1,    'disable_existing_loggers': False,    'filters': {        'require_debug_true': {            '()': 'django.utils.log.RequireDebugTrue',        }, # 针对 DEBUG = True 的情况    },    'formatters': {        'standard': {            'format': '%(levelname)s %(asctime)s %(pathname)s %(filename)s %(module)s %(funcName)s %(lineno)d: %(message)s'        }, # 对日志信息进行格式化,每个字段对应了日志格式中的一个字段,更多字段参考官网文档,我认为这些字段比较合适,输出类似于下面的内容        # INFO 2016-09-03 16:25:20,067 /home/ubuntu/mysite/views.py views.py views get 29: some info...    },    'handlers': {        'mail_admins': {            'level': 'ERROR',            'class': 'django.utils.log.AdminEmailHandler',             'formatter':'standard'        },        'file_handler': {             'level': 'DEBUG',             'class': 'logging.handlers.TimedRotatingFileHandler',             'filename': os.path.join(BASE_DIR, "logging\\test.log"),   #网上的报错,改成相对路径             'formatter':'standard'        }, # 用于文件输出        'console':{            'level': 'INFO',            'filters': ['require_debug_true'],            'class': 'logging.StreamHandler',            'formatter': 'standard'        },    },    'loggers': {        'django': {            'handlers' :['file_handler', 'console'],            'level':'DEBUG',            'propagate': True # 是否继承父类的log信息        }, # handlers 来自于上面的 handlers 定义的内容        'django.request': {            'handlers': ['mail_admins'],            'level': 'ERROR',            'propagate': False,        },    }}

2.在views.py中调用,不知道是不是每个都需要调用,暂时都调用了

#记录日志import logginglogger = logging.getLogger("django") # loggers中定义的名称logger.info("some info...")


3.得到了报错日志,该文件下有所有的信息。



4.若想单独打印bug信息,则需要根据对应的函数自己写try except然后打日志。这步还没做。




另外一篇简单的配置博文:

http://blog.csdn.net/novostary/article/details/52424116

django使用python内建的logging模块去建造自己的系统日志的,如果你想详细了解这个模块的话,请自己去看python的说明文档,这里仅仅介绍django中的日志系统

日志配置包括四个部分:记录器,处理器,过滤器和格式器,下面我们来一一讲解

记录器

一个记录器是日志系统的一个实体,每一个记录器是一个已经命名好的可以将消息为进程写入的“桶”。

每一个记录器都会有一个日志等级,每个等级描述了记录器即将处理的信息的严重性,python定义了以下五个等级:

debug:出于调试目的的低层次系统信息

  • info:普通的系统信息
  • warning:描述已经发生的小问题
  • error:描述已经发生的主要问题
  • critical:描述已经发生的严重问题

每一条被写入记录器的信息成为一条日志记录,每条日志记录都有一个表明该记录严重性的日志等级,每条日志信息也会包含一些有用的元信息表明已经被记录的事件,比如栈追溯和错误代码。

当一条信息被发往记录器的时候,消息的记录等级会和记录器的等级相比较,如果符合甚至超越当前等级,则被发往处理器处理,否则会被忽略掉。

处理器

处理器是决定日志记录器中对应的实体消息发生了什么的引擎,描述了一个具体的日志行为,比如输出到屏幕,或者一个文件,抑或一个网络socket。

和记录器一样,没有到达相应等级的消息会被忽略。

一个记录器可以有多个处理器,一个处理器可以有不同的日志等级,因此你可以根据消息的重要性而提供不同的提示。

过滤器

过滤器是用来提供额外的控制,控制哪些日志记录可以被传给处理器处理。

默认情况下,只要日志消息符合相应的等级要求就会传给对应的处理器处理,然而,通过安装过滤器,你可以在日志记录过程中设置额外的内容,例如,你可以安装一个过滤器使得某个源只有error级别的消息才会被发送。你也可以使用过滤器修改之前会被发送的消息,例如,你可以写一个过滤器使得符合某些条件的error等级的消息降级为warning等级。

过滤器可以给处理器和记录器使用,多个过滤器可以级联使用。

格式器

控制日志输出的格式,格式使用python的字符串控制格式

使用日志

一旦配置好你的记录器,处理器,过滤器和格式器,你需要在你的代码中调用日志功能,下面是一个简单的例子:

复制代码
复制代码
# import the logging libraryimport logging# Get an instance of a loggerlogger = logging.getLogger(__name__)def my_view(request, arg1, arg):    ...    if bad_mojo:        # Log an error message        logger.error('Something went wrong!')
复制代码
复制代码

 

命名你的记录器

logging.getLogger()的调用获得一个记录器的实体,记录器实体通过名字来辨别。

像上面的那个例子,一般是使用__name__,包含记录器的python模块的名字,这使得基于每个模块的记录成为可能

或者你可以是用点号相连的名字,这意味着记录器的层次,点号之前的是点号之后的父模块,例如

# Get an instance of a specific named loggerlogger = logging.getLogger('project.interesting.stuff')

 

这种方式也很重要,因为通过层次,子层次的消息可以把消息发送给自己的父层次,如果你不想把消息发给你的父层次,记得把发送开关关闭掉。(下面会有介绍到)

日志调用

对应日志的五个等级,日志调用有五个对应的方法:

  • logger.critical()
  • logger.error()
  • logger.warning()
  • logger.info()
  • logger.debug()

还有两个可用的日志方法可以调用:

  • logger.log():手工发送一个具体等级的日志消息
  • logger.exception():创建一个error等级的封装着异常堆栈帧内容的日志消息

配置日志系统

在代码中调用日志的前提是已经配置好了日志系统的记录器,处理器,过滤器和格式器,我们通过一个复杂的例子来详细讲解吧:

复制代码
复制代码
LOGGING = {    'version': 1,#指明dictConnfig的版本,目前就只有一个版本,哈哈    'disable_existing_loggers': True,#禁用所有的已经存在的日志配置    'formatters': {#格式器        'verbose': {#详细            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'        },        'simple': {#简单            'format': '%(levelname)s %(message)s'        },    },    'filters': {#过滤器        'special': {#使用project.logging.SpecialFilter,别名special,可以接受其他的参数            '()': 'project.logging.SpecialFilter',            'foo': 'bar',#参数,名为foo,值为bar        }    },    'handlers': {#处理器,在这里定义了三个处理器        'null': {#Null处理器,所有高于(包括)debug的消息会被传到/dev/null            'level':'DEBUG',            'class':'django.utils.log.NullHandler',        },        'console':{#流处理器,所有的高于(包括)debug的消息会被传到stderr,使用的是simple格式器            'level':'DEBUG',            'class':'logging.StreamHandler',            'formatter': 'simple'        },        'mail_admins': {#AdminEmail处理器,所有高于(包括)而error的消息会被发送给站点管理员,使用的是special格式器            'level': 'ERROR',            'class': 'django.utils.log.AdminEmailHandler',            'filters': ['special']        }    },    'loggers': {#定义了三个记录器        'django': {#使用null处理器,所有高于(包括)info的消息会被发往null处理器,向父层次传递信息            'handlers':['null'],            'propagate': True,            'level':'INFO',        },        'django.request': {#所有高于(包括)error的消息会被发往mail_admins处理器,消息不向父层次发送            'handlers': ['mail_admins'],            'level': 'ERROR',            'propagate': False,        },        'myproject.custom': {#所有高于(包括)info的消息同时会被发往console和mail_admins处理器,使用special过滤器            'handlers': ['console', 'mail_admins'],            'level': 'INFO',            'filters': ['special']        }    }}
复制代码
复制代码

 

相信看完这个例子,对日志系统的配置大家基本了解了吧

循环导入问题

如果你自定义了一个处理器,然后再settings.py文件有配置,如果这是你在类实现文件里面导入settings模块的时候,就会出现循环导入的问题,建议只在settings.py配置文件里面配置

自定义日志配置和禁用日志配置

使用LOGGING_CONFIG属性自定义和禁用日志配置,LOGGING_CONFIG=None禁用

django日志拓展

django提供三个自带的记录器:

django

django记录器是捕捉所有消息的记录器,没有消息是直接发往django记录器的

django.request

5XX会引发一个error消息,4XX会引发一个warning消息,这个记录器还附带有额外的上下文:

  • status_code:HTTP响应吗
  • request:生成这个消息的request对象

django.db.backens

所有的由请求运行的sql语句都会记录一条debug的消息,每个记录器还附带有额外的上下文:

  • duration:sql语句运行的时间
  • sql:运行的sql语句
  • params:sql语句调用的参数

处于网站运行的表现原因,仅当settings.DEBUG=True的时候,这个处理器才生效,否则即使配置了也无效

除了python模块自带的,django自定义了一个处理器

class AdminEmailHandler(include_html=False)

这个处理器每收到一条消息就会发往站点管理员,如果日志信息包含request属性,那么整个request的详细信息也会被包包含在Email中发往站点管理员;如果日志信息包含堆栈跟踪信息,堆栈跟踪信息也会被发送。

include_html属性控制当DEBUG为真的时候是否发送那些回溯信息,因为这些都是很敏感的系统系统,如果被人截获,可能会发生危险,所以要谨慎。配置这个属性示例如下:

复制代码
复制代码
'handlers': {    'mail_admins': {        'level': 'ERROR',        'class': 'django.utils.log.AdminEmailHandler',        'include_html': True,    }},
复制代码
复制代码

 

除了python自带的,django提供了两个自带的过滤器:

class CallBackFilter(callback)

这个过滤器接受一个回调函数(这个函数接受一个参数,被记录的信息),每个记录通过过滤器的时候都会调用这个回调函数,当回调函数返回False的时候,不处理这个记录。下面是一个示例:

复制代码
复制代码
from django.http import UnreadablePostErrordef skip_unreadable_post(record):    if record.exc_info:        exc_type, exc_value = record.exc_info[:2]        if isinstance(exc_value, UnreadablePostError):            return False    return True
复制代码
复制代码
复制代码
复制代码
'filters': {    'skip_unreadable_posts': {        '()': 'django.utils.log.CallbackFilter',        'callback': skip_unreadable_post,    }},'handlers': {    'mail_admins': {        'level': 'ERROR',        'filters': ['skip_unreadable_posts'],        'class': 'django.utils.log.AdminEmailHandler'    }},
复制代码
复制代码

 

class RequireDebugFalse

这个过滤器仅当settings.DEBUG为False的时候会生效,默认是启用的,仅当settings.DEBUG=False的时候,AdminEmailHandler才生效

复制代码
复制代码
'filters': {     'require_debug_false': {         '()': 'django.utils.log.RequireDebugFalse',     } }, 'handlers': {     'mail_admins': {         'level': 'ERROR',         'filters': ['require_debug_false'],         'class': 'django.utils.log.AdminEmailHandler'     } },
复制代码
复制代码
原创粉丝点击