zoukankan      html  css  js  c++  java
  • python logging日志记录

    日志logging模块

    日志记录的作用:基本上就是收集与程序运行有关的数据,这样可以在随后进行检查(或者累计数据)

    logging.basicConfig函数的配置:
    filename:指定日志文件名
    filemode:指定日志文件的打开模式,‘w’或‘a’
    format:指定输出格式和内容,format可以输出很多有信息。
    %(levelno)s:打印日志级别的数值
    %(levelname)s:打印日志级别名称
    %(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
    %(filename)s:打印当前执行程序名
    %(funcName)s:打印日志的当前函数
    %(lineno)s:打印日志的当前行号
    %(asctime)s:打印日志的时间
    %(thread)s:打印线程ID
    %(threadName)s:打印线程名称
    %(process)s:打印进程ID
    %(message)s:打印日志信息
    datefmt:指定时间格式,同time.strftime()
    level:设置日志级别,默认为logging.WARNING
    stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略。

    selLevel()方法的级别
    level numeric value
    CRITICAL    50
    ERROR       40
    WARNING        30
    INFO      20
    DEBUG       10
    NOTSET      0

    logging包默认给出6个级别,最高级为CRITICAL,最低级为NOTSET。高级别的日志会覆盖低级别的日志信息,比如,如果定义setLevel(INFO),那么打印debug信息时,就无法打印出来,只能打印INFOWARNINGERRORCRITICAL的日志。如果要打印debug的信息,则可以设置setLevel为:DEBUG或NOTSET。

    创建日志实例:import logging

    import time
    
     
    # 获取logger实例,如果参数为空则返回root logger
    logger = logging.getLogger()
     
    # 指定logger输出格式
    formatter=logging.Formatter("[%(levelname)s]--%(asctime)s-%(filename)s->%(funcName)s line:%(lineno)d: %(message)s")
     
    # 文件日志
    file_handler = logging.FileHandler("test.log",'a')
    file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式
     
    # 控制台日志
    console_handler = logging.StreamHandler()
    console_handler.formatter = formatter  # 也可以直接给formatter赋值
     
    # 为logger添加的日志处理器
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)
     
    # 指定日志的最低输出级别,默认为WARNING级别
    logger.setLevel(logging.INFO)
    
    #日志打印参数
    parameter1="20"
    parameter2="30"
    
    # 输出不同级别的log
    logger.debug('this is debug info , parameter1=%s - parameter2=%s' %(parameter1,parameter2))
    logger.info('this is information , parameter1=%s - parameter2=%s' %(parameter1,parameter2))
    logger.warn('this is warning message , parameter1=%s - parameter2=%s' %(parameter1,parameter2))
    logger.error('this is error message , parameter1=%s - parameter2=%s' %(parameter1,parameter2))
    logger.fatal('this is fatal message, it is same as logger.critical , parameter1=%s - parameter2=%s' %(parameter1,parameter2))
    logger.critical('this is critical message , parameter1=%s - parameter2=%s' %(parameter1,parameter2))
     
     
    # 移除一些日志处理器
    logger.removeHandler(file_handler)
    logger.removeHandler(console_handler)
    运行结果:

    [INFO]--2018-12-23 10:43:28,453-test.py-><module> line:34: this is information , parameter1=20 - parameter2=30
    [WARNING]--2018-12-23 10:43:28,453-test.py-><module> line:35: this is warning message , parameter1=20 - parameter2=30
    [ERROR]--2018-12-23 10:43:28,453-test.py-><module> line:36: this is error message , parameter1=20 - parameter2=30
    [CRITICAL]--2018-12-23 10:43:28,453-test.py-><module> line:37: this is fatal message, it is same as logger.critical , parameter1=20 - parameter2=30
    [CRITICAL]--2018-12-23 10:43:28,453-test.py-><module> line:38: this is critical message , parameter1=20 - parameter2=30
    [Finished in 0.1s]

     

    重新封装logging(此处参考网上的代码进行修改)

    #-*-encoding:utf-8-*-
    import logging
    import time
    
    class TestLog(object):
    	#封装logging
    
    	def __init__(self,logger=None):
    		self.logger=logging.getLogger(logger)
    		self.logger.setLevel(logging.NOTSET)
    		self.log_time=time.strftime("%Y_%m_%d_")
    		self.log_path="D:\"
    		self.log_name=self.log_path+self.log_time+"test.log"
    
    
    	def set_logger(self):
    		if not self.logger.handlers:  #判断如果handlers中无handler则添加新的handler
    			self.fh=logging.FileHandler(self.log_name,"a")  #创建将日志写入到文件,a表示以追加的形式写入日志
    			self.fh.setLevel(logging.DEBUG)
    			self.chd=logging.StreamHandler()   #创建从控制台输入日志
    			self.chd.setLevel(logging.DEBUG)  #设置为notset,可以打印debug、info、warning、error、critical的日志级别
    			self.formatter=logging.Formatter("[%(levelname)s]--%(asctime)s-%(filename)s->%(funcName)s line:%(lineno)d: %(message)s")
    			self.chd.setFormatter(self.formatter)
    			self.logger.addHandler(self.fh)   #添加文件日志的日志处理器
    			self.logger.addHandler(self.chd)  #添加控制台的日志处理器
    
    
    	def get_logger(self):
    		TestLog.set_logger(self)
    		# print self.logger.handlers  打印handlers列表
    		return self.logger
    
    
    	def remove_log_handler(self):
    		#移除handlers中的元素
    		self.logger.removeHandler(self.fh)  #移除句柄,避免重复打印相同的日志
    		self.logger.removeHandler(self.chd) #移除句柄,避免重复打印相同的日志
    		self.fh.close()  #关闭日志处理器
    		self.chd.close()  #关闭日志处理器
    
    
    if __name__=="__main__":
    	#调式是否能打印成功
    	test=TestLog()
    	log=test.get_logger()
    	log.warning("this is warning information")
    	log.info("this is info informattion")
    	log.info("this is info informattion1")
    	log.debug("this is debug information")
    
    运行结果:
    [WARNING]--2018-12-23 10:21:04,698-TestLog.py-><module> line:52: this is warning information
    [INFO]--2018-12-23 10:21:04,698-TestLog.py-><module> line:53: this is info informattion
    [INFO]--2018-12-23 10:21:04,698-TestLog.py-><module> line:54: this is info informattion1
    [DEBUG]--2018-12-23 10:21:04,698-TestLog.py-><module> line:55: this is debug information
    [Finished in 0.2s]
    

      

    创建测试脚本,调用已封装好的TestLog类

    #-*-encoding:utf-8-*-
    import TestLog
    import unittest
    
    class MyTest(unittest.TestCase):
    #测试日志是否能正常记录信息
    	def setUp(self):
    		self.a=10
    		self.b=12
    		self.log=TestLog.TestLog().get_logger()
    
    
    
    	def test1(self):
    		result=self.a+self.b
    		value=23
    		try:
    			self.assertEqual(result,value)
    			self.log.debug("parament1:%s - parament2:%s :puls=%s <-> value=%s" %(self.a,self.b,result,value))
    		except Exception as e:
    			self.log.error("异常原因:%s" %e)
    			
    
    	def test2(self):
    		try:
    			a=0
    			b=10
    			result=b/a
    			self.log.debug("parament1:%s - parament2:%s " %(a,b,result))
    		except Exception as e:
    			self.log.error("异常原因:%s" %e)
    			
    
    
    	def test3(self):
    		try:
    			a=u"测试"
    			b=u"测试"
    			self.assertEqual(a,b)
    			self.log.info("parament1:%s - parament2:%s " %(a,b))
    		except Exception as e:
    			self.log.error("异常原因:%s" %e)
    		
    
    	def test4(self):
    		try:
    			a=u"测试a"
    			b=u"测试a"
    			self.assertEqual(a,b)
    			self.log.info("parament1:%s - parament2:%s " %(a,b))
    		except Exception as e:
    			self.log.error("异常原因:%s" %e)
    
    
    
    	def tearDonw(self):
    		pass
    
    
    if __name__=="__main__":
    	unittest.main()
    
    运行结果:
    [ERROR]--2018-12-23 10:26:50,785-MyTest.py->test1 line:24: 异常原因:22 != 23
    .[ERROR]--2018-12-23 10:26:50,785-MyTest.py->test2 line:34: 异常原因:integer division or modulo by zero
    .[INFO]--2018-12-23 10:26:50,785-MyTest.py->test3 line:43: parament1:测试 - parament2:测试 
    .[INFO]--2018-12-23 10:26:50,785-MyTest.py->test4 line:53: parament1:测试a - parament2:测试a 
    

      MyTest运行后,文件的记录内容:

  • 相关阅读:
    从一个故障说说Java的三个BlockingQueue
    kafka producer源码
    Mock方法介绍
    async4j 普通用法、整合spring用法
    Spring中属性文件properties的读取与使用
    异步框架asyn4j的原理
    如何从线程返回信息——轮询、回调、Callable
    jdk 1.8 Executors
    java Iterator Fail-fast机制
    java的几种对象(PO,VO,DAO,BO,POJO)解释
  • 原文地址:https://www.cnblogs.com/JcHome/p/10163434.html
Copyright © 2011-2022 走看看