小编这次要给大家分享的是python3中的logging记录日志如何实现过程及封装成类,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。
作用:
主要记录信息,便于定位查看问题。
三种定位问题方法:
debug调试:代码写好后,就不需要再进行调试了,所以引入了logger
logging.debug() – 一般在测试环境中用
logger:当生产环境中有问题时,可以查看logger定位问题
步骤:
1.初始化日志 收集器
2.设置日志 收集器级别 -默认是warning
3.初始化日志 处理器 - 可以理解为写日志的笔
4.设置日志 处理器级别
5.添加handler
6.设置日志的格式
7.添加日志处理器
8.设置不同级别的logger
这里是引用
日志收集器级别
1.NOSET 0 等于没写,废话
2.DEBUG 10 程序调试bug时使用
3.INFO 20 程序正常运行时使用
4.WARNING 30 警告,程序未按预期运行时使用
5.ERROE 40 程序出错
6.CRITICAL 50 严重问题
如何定义级别:自己定的 可以结合try: except: 记录log
代码实现过程如下:
```python import logging # 标准库,直接导入。 logger = logging.getLogger("日志名字") # 初始化日志收集器 logger.setLevel("DEBUG") # 设置日志收集器级别 handler = logging.FileHandler("日志路径") # 初始化日志处理器 - 文件输出(指定位置使用绝对路径,默认当前目录下) handler.setLevel("warning") # 设置日志处理器级别 默认warning console_handler = logging.StreamHandler() # 控制台输出 console_handler.setLevel("DEBUG") logger.addHandler(handler) # 添加handler logger.addHandler(console_handler) # 设置日志格式,中间间隔使用冒号也可以(模块名字-报错行-收集器名字-级别-信息) fmt = logging.Formatter("%(filename)s-%(lineno)s-%(name)s-%(levelname)s-%(massage)s") handler.setFormat(fmt) # 日志轮转 - 添加日志处理器 # 设置不同级别的logger -- 选择一个级别就可以 logging.info("") logging.debug("") logging.waring("") logging.error("") logging.critical("")
问题1:级别设置
如当设成debug的时候,只有高于,等于该级别的才会打印
如当你设成warning的时候,只有warning.error,critical才会打印
不用管(日志收集器)的级别是啥,这里设置就以(日志处理器)的级别
为准,两者中选择最高的如果(日志收集器)是warning,(日志处理器)
是debug,就以warning为准,两个都设置,这样可以添加多个handler
问题2:实例化
在模块中直接实例化,如果在外部实例化,容易造成多个日志文件的生成
问题3:日志格式设置,python logging官网,查找需要用到的。
https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects
封装为类
import logging class LoggerHandler(logging.Logger): def __init__(self, name="root", level="DEBUG", file=None, format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s" ): # 初始化日志收集器 logger = logging.getLogger(name) # 设置收集器级别 logger.setLevel(level) # 继承了Logger 返回的实例就是自己 # 初始化format,设置格式 fmt = logging.Formatter(format) # 初始化处理器 # 如果file为空,就执行stream_handler,如果有,两个都执行 if file: file_handler = logging.FileHandler(file) # 设置handler级别 file_handler.setLevel(level) # 添加handler logger.addHandler(file_handler) # 添加日志处理器 file_handler.setFormatter(fmt) stream_handler = logging.StreamHandler() stream_handler.setLevel(level) logger.addHandler(stream_handler) stream_handler.setFormatter(fmt) self.logger = logger def debug(self, msg): return self.logger.debug(msg) def info(self,msg): return self.logger.info(msg) def warning(self,msg): return self.logger.warning(msg) def error(self,msg): return self.logger.error(msg) def critical(self,msg): return self.logger.critical(msg) # 为了确保每次是同一个文件,调用同样的logger对象(防止手误写错文件名字),所以在这里直接初始化logger这个对象比较好 # 可以将name,file参数写入配置文件中(这里我是直接写到了配置文件当中,也可以直接传) logger = LoggerHandler(config.logger_name,config.level,config.logger_file) # logger = LoggerHandler("python21",file="demo.txt") if __name__ == '__main__': logger = LoggerHandler() logger.debug("world") # 测试.py:40:root:DEBUG:world - 应该是59行打印,因为信息早就保存到logger当中了 -- 可以直接继承logging.Logger使用
重新封装 - 继承logger后,发现可以直接定位到哪一行打印,可以查看源码
import logging class LoggerHandler(logging.Logger): def __init__(self, name="root", level="DEBUG", file=None, format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s" ): # logger(name) 直接超继承logger当中的name super().__init__(name) # 设置收集器级别 # logger.setLevel(level) self.setLevel(level) # 继承了Logger 返回的实例就是自己 # 初始化format,设置格式 fmt = logging.Formatter(format) # 初始化处理器 # 如果file为空,就执行stream_handler,如果有,两个都执行 if file: file_handler = logging.FileHandler(file) # 设置handler级别 file_handler.setLevel(level) # 添加handler self.addHandler(file_handler) # 添加日志处理器 file_handler.setFormatter(fmt) stream_handler = logging.StreamHandler() stream_handler.setLevel(level) self.addHandler(stream_handler) stream_handler.setFormatter(fmt) # 为了确保每次是同一个文件,调用同样的logger对象(防止手误写错文件名字),所以在这里直接初始化logger这个对象比较好 # 可以将name,file参数写入配置文件中(这里我是直接写到了配置文件当中,也可以直接传) logger = LoggerHandler(config.logger_name,config.level,config.logger_file) # logger = LoggerHandler("python21",file="demo.txt") if __name__ == '__main__': logger = LoggerHandler() logger.debug("world") # 继承后---测试.py:44:root:DEBUG:world
补充知识:python3使用logging包,把日志写到系统的rsyslog中
最近要写一个python程序写日志到rsyslog中,并通过配置rsyslog的文件来将他存到一个指定文件中。
首先,我想来看看logging提供的常用模块:
logger:logger主要是用来配置和发送日志消息的。可通过logging.getLogger(name)来返回一个logger对象。
不指定name就默认为root。
这里可以取一个合适的名字。
相同的name会返回同一个logger对象。在Formatter方法中用%(name)s在日志中打印出这个name。例如:
log = logging.getLogger('mylog') log_format = logging.Formatter( 'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s') #打印结果示例: #Aug 2 12:44:41 [localhost] hhl-mylog-server[7409]-DEBUG: debug message handler:将日志记录发送到目的地,如文件,socket等。这里可以通过addHandler方法添加多个handler,可以实现日志的分级过滤。如果要把日志发送到rsyslog中,就可以采用SysLogHandler(),使用这个方法前需要导入他 from logging.handlers import SysLogHandler 这个方法有两个参数、一个是rsyslog中的facility:指定的是发送的设备,如kernel,mail,system等等,他还有local0-local7预留。这里我采用local5。还有一个参数指定的是log程序的地址,在centos7上默认是/dev/log。示例如下: log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log') 对应的rsyslog设置文件(/etc/rsyslog.conf): local5.* /var/log/all.log #将local5的所有日志存入all.log文件中
如果想用handler对日志信息进行过滤,可以这样:
log_hdlr.setLevel(logging.ERROR) #这里就指定了接收error以及更高级别的日志 formatter:指定日志的输出格式,包括消息格式和日期字符格式,例如: log_format = logging.Formatter( 'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s') #输出示例 #Aug 2 12:44:41 [localhost] hhl-mylog-server[7409]-DEBUG: debug message
formatter可调用参数有:
%(name)s Logger的名字
%(levelname)s 文本形式的日志级别
%(message)s 用户输出的消息
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(levelno)s 数字形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
由上面的这些模块就可以实现我想要的功能啦
将日志写入到all.log文件中-----源代码:
import logging from logging.handlers import SysLogHandler log = logging.getLogger('mylog') log.setLevel(logging.DEBUG) log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log') log_format = logging.Formatter( 'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s') log_hdlr.setFormatter(log_format) log_hdlr.setLevel(logging.ERROR)#接受error及以上的日志信息 log.addHandler(log_hdlr) log.debug('debug message test')#指明级别为debug log.error('error message test')#指明级别为error #最后只保存error及更高优先级的日志
可能有些地方说的不对,还望大家能够指正!
看完这篇关于python3中的logging记录日志如何实现过程及封装成类的文章,如果觉得文章内容写得不错的话,可以把它分享出去给更多人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。