日志
日志
1、Log简介
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
通过log的分析,可以方便用户了解系统或软件、应用的运行情况;如果你的应用log足够丰富,也可以分析以往用户的操作行为、类型喜好、地域分布或其他更多信息;如果一个应用的log同时也分了多个级别,那么可以很轻易地分析得到该应用的健康状况,及时发现问题并快速定位、解决问题,补救损失。
2、Log的用途
不管是使用何种编程语言,日志输出几乎无处不再。总结起来,日志大致有以下几种用途:
- 问题追踪:通过日志不仅仅包括我们程序的一些bug,也可以在安装配置时,通过日志可以发现问题。
- 状态监控:通过实时分析日志,可以监控系统的运行状态,做到早发现问题、早处理问题。
- 安全审计:审计主要体现在安全上,通过对日志进行分析,可以发现是否存在非授权的操作
3、Log等级
- DEBUG最详细的日志信息,典型应用场景是 问题诊断
- INFO信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
- WARNING当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
- ERROR由于一个更严重的问题导致某些功能不能正常运行时记录的信息 如IO操作失败或者连接问题
- CRITICAL当发生严重错误,导致应用程序不能继续运行时记录的信息
4、日志记录级别
logging模块的重点在于生成和处理日志消息。每条消息由一些文本和指示其严重性的相关级别组成。级别包含符号名称和数字值。  
级别      	值   	描述
CRITICAL	50  	关键错误/消息
ERROR   	40  	错误
WARNING 	30  	警告消息
INFO    	20  	通知消息
DEBUG   	10  	调试
NOTSET  	0   	无级别
5、Log模块的四大组件
- 
Loggers 
 提供应用程序代码直接使用的接口
- 
Handlers 
 用于将日志记录发送到指定的目的位置- 内置处理器
 logging模块提供了一些处理器,可以通过各种方式处理日志消息。使用addHandler()方法将这些处理器添加给Logger对象。另外还可以为每个处理器配置它自己的筛选和级别- handlers.DatagramHandler(host,port):发送日志消息给位于制定host和port上的UDP服务器
- handlers.FileHandler(filename):将日志消息写入文件filename
- handlers.HTTPHandler(host, url):使用HTTP的GET或POST方法将日志消息上传到一台HTTP 服务器
- handlers.RotatingFileHandler(filename):将日志消息写入文件filename。如果文件的大小超出maxBytes制定的值,那么它将被备份为filename1
 
 
- 内置处理器
- 
Filters 
 提供更细粒度的日志过滤功能,用于决定哪些日志记录将会被输出(其它的日志记录将会被忽略)
- 
Formatters 
 用于控制日志信息的最终输出格式
6、记录器
记录器负责管理日志消息的默认行为,包括日志记录级别、输出目标位置、消息格式以及其它基本细节。
关键字参数   	描述
filename	将日志消息附加到指定文件名的文件
filemode	指定用于打开文件模式
format  	用于生成日志消息的格式字符串
datefmt 	用于输出日期和时间的格式字符串
level   	设置记录器的级别
stream  	提供打开的文件,用于把日志消息发送到文件。
7、format 日志消息格式
格式            	描述
%(name)s      	记录器的名称
%(levelno)s   	数字形式的日志记录级别
%(levelname)s 	日志记录级别的文本名称
%(filename)s  	执行日志记录调用的源文件的文件名称
%(pathname)s  	执行日志记录调用的源文件的路径名称
%(funcName)s  	执行日志记录调用的函数名称
%(module)s    	执行日志记录调用的模块名称
%(lineno)s    	执行日志记录调用的行号
%(created)s   	执行日志记录的时间
%(asctime)s   	日期和时间
%(msecs)s     	毫秒部分
%(thread)d    	线程ID
%(threadName)s	线程名称
%(process)d   	进程ID
%(message)s   	记录的消息
8、logging
- 
简单使用-控制台查看 
 示例
 import loggings = '0' n = int(s) logging.info('n = %d' % n) print(10 / n)logging.info()就可以输出一段文本 
 配置级别
 import logging
 logging.basicConfig(level=logging.INFO)
 输出结果
 $ python err.py
 INFO:root:n = 0
 Traceback (most recent call last):
 File "err.py", line 8, in
 print(10 / n)
 ZeroDivisionError: division by zero
 说明:
 这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
 logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件
- 
logging进阶使用-控制台查看 
 配置logging基本的设置,然后在控制台输出日志
 import logging
 logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 logger = logging.getLogger(name)logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")运行时,控制台输出 
 2088-10-09 19:11:19,434 - main - INFO - Start print log
 2088-10-09 19:11:19,434 - main - WARNING - Something maybe fail.
 2088-10-09 19:11:19,434 - main - INFO - Finish
 将logger的级别改为DEBUG,再观察一下输出结果
 logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 控制台输出,可以发现,输出了debug的信息
 2088-10-09 19:12:08,289 - main - INFO - Start print log
 2088-10-09 19:12:08,289 - main - DEBUG - Do something
 2088-10-09 19:12:08,289 - main - WARNING - Something maybe fail.
 2088-10-09 19:12:08,289 - main - INFO - Finish
- 
将日志写入到文件 
 设置logging,创建一个FileHandler,并对输出消息的格式进行设置,将其添加到logger,然后将日志写入到指定的文件中
 示例
 import logging
 logger = logging.getLogger(name)
 logger.setLevel(level = logging.INFO)
 handler = logging.FileHandler("log.txt")
 handler.setLevel(logging.INFO)
 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 handler.setFormatter(formatter)
 logger.addHandler(handler)logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")log.txt中日志数据为 
 2088-10-09 19:01:13,263 - main - INFO - Start print log
 2088-10-09 19:01:13,263 - main - WARNING - Something maybe fail.
 2088-10-09 19:01:13,263 - main - INFO - Finish
- 
将日志同时输出到屏幕和日志文件 
 logger中添加StreamHandler,可以将日志输出到屏幕上
 import logging
 logger = logging.getLogger(name)
 logger.setLevel(level = logging.INFO)
 handler = logging.FileHandler("log.txt")
 handler.setLevel(logging.INFO)
 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 handler.setFormatter(formatter)console = logging.StreamHandler() console.setLevel(logging.INFO) logger.addHandler(handler) logger.addHandler(console) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")可以在log.txt文件和控制台中看到 
 2088-10-09 19:20:46,553 - main - INFO - Start print log
 2088-10-09 19:20:46,553 - main - WARNING - Something maybe fail.
 2088-10-09 19:20:46,553 - main - INFO - Finish
9、Django中配置输出到文件
- 配置setting.py配置文件
 LOGGING = {
 'version': 1,
 'disable_existing_loggers': True,
 'formatters': { # 日志格式
 'standard': {
 'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'}
 },
 'filters': { # 过滤器
 },
 'handlers': { # 处理器
 'null': {
 'level': 'DEBUG',
 'class': 'logging.NullHandler',
 },
 'debug': { # 输出到文件
 'level':'DEBUG',
 'class':'logging.handlers.RotatingFileHandler',
 'filename': os.path.join(BASE_DIR, "log",'debug.log'), # 日志输出文件
 'maxBytes':102410245, # 文件大小
 'backupCount': 5, # 备份份数
 'formatter':'standard', # 使用哪种formatters日志格式
 },
 'console':{ # 输出到控制台
 'level': 'DEBUG',
 'class': 'logging.StreamHandler',
 'formatter': 'standard',
 },
 },
 'loggers': { # logging管理器
 'django': {
 'handlers': ['console'],
 'level': 'DEBUG',
 'propagate': False
 },
 'django.request': {
 'handlers': ['debug'],
 'level': 'ERROR',
 'propagate': True,
 },
 }
 }
 说明:把所有的debug信息输出到控制台,把error级别错误信息输出到文件。当然要先在django网站创建我设置的日志目录:log,要不然会出错。
 解析:- formatters:配置打印日志格式
- handler:用来定义具体处理日志的方式,可以定义多种,"default"就是默认方式,"console"就是打印到控制台方式
- loggers:用来配置用那种handlers来处理日志,比如你同时需要输出日志到文件、控制台
 
10、Django配置邮件发送错误信息
- 
关闭Debug模式 
 关闭调试模式,调试模式响应速度相对有些慢。关闭调试模式可以加快访问速度,而且可以避免敏感的调试信息泄漏
 打开settings.py文件,把DEBUG设置False。接着还需要设置 ALLOWED_HOSTS (被运行的主机),如果这个设置的话,会提示错误。偷懒的人可以设置为 ALLOWED_HOSTS = ['*'] 但这种不建议,不够安全。应该根据自己的域名来设置。设置为 ALLOWED_HOSTS = ['xxx.com']
- 
动态设置Debug模式 
 为了方便我开发和生产部署,不想每次都手动修改DEBUG这个值,导入socket模块,根据ip地址来设置。判断是否是127开头的IP地址
 import socket
 if socket.gethostbyname(socket.gethostname())[:3]=='127':
 DEBUG = True
 else:
 DEBUG = False
 ALLOWED_HOSTS = ['*']
- 
完整的代码 
 import socket# 根据IP地址判断是否是开发环境 if socket.gethostbyname(socket.gethostname())[:3]=='127': DEBUG = True else: DEBUG = False ALLOWED_HOSTS = ['*'] # 设置允许访问的主机 # 管理员邮箱 ADMINS = ( ('xialigang','793390457@qq.com'), ) # 非空链接,却发生404错误,发送通知MANAGERS SEND_BROKEN_LINK_EMAILS = True MANAGERS = ADMINS # Email EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.1000phone.com' # QQ邮箱SMTP服务器 EMAIL_HOST_USER = 'xialigang@1000phone.com' # 我的邮箱帐号 EMAIL_HOST_PASSWORD = '******' # 密码 DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER # 设置发件人 #logging日志配置 LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { # 日志格式 'standard': { 'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'} }, 'filters': { # 过滤器 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse', } }, 'handlers': { # 处理器 'null': { 'level': 'DEBUG', 'class': 'logging.NullHandler', }, 'mail_admins': {# 发送邮件通知管理员 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'filters': ['require_debug_false'], # 仅当 DEBUG = False 时才发送邮件 'include_html': True, }, 'debug': { # 记录到日志文件(需要创建对应的目录,否则会出错) 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': os.path.join(BASE_DIR, "log",'debug.log'), # 日志输出文件 'maxBytes':1024*1024*5, # 文件大小 'backupCount': 5, # 备份份数 'formatter':'standard', # 使用哪种formatters日志格式 }, 'console':{ # 输出到控制台 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'standard', }, }, 'loggers': { # logging管理器 'django': { 'handlers': ['console','debug'], # 控制台输出并写入debug文件 'level': 'DEBUG', 'propagate': False }, 'django.request': { 'handlers': ['debug','mail_admins'], 'level': 'ERROR', 'propagate': True, }, # 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件 'django.security.DisallowedHost': { 'handlers': ['null'], 'propagate': False, }, } }注意:如果发送失败 注意查看debug是否关闭为False 
作业:
当项目出现错误 将错误信息格式化写入到错误日志文件中
本文来自博客园,作者:寻月隐君,转载请注明原文链接:https://www.cnblogs.com/QiaoPengjun/articles/15948924.html

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号