Python logging系统
我们都知道python在2.x之后自带了一个模块import logging.
但是每次都要写log很麻烦,同时我想把info,debug之类的指令通过颜色分离开来。
于是写了一个简单的类似glog的小程序(完善是不可能完善的,checkeq这辈汁都不可能写的)
import logging
from colorlog import ColoredFormatter
import sys
import os def currentframe():
"""Return the frame object for the caller's stack frame."""
try:
raise Exception
except:
return sys.exc_info()[2].tb_frame.f_back
_srcfile = os.path.normcase(currentframe.__code__.co_filename) logging._srcfile = _srcfile class myLogger(logging.Logger):
def __init__(self):
super(myLogger, self).__init__('my_logger')
formatter = ColoredFormatter(
"%(asctime)s - %(filename)s - [line:%(lineno)d] - %(log_color)s%(levelname)s: %(white)s%(message)s",
datefmt = None,
reset = True,
log_colors = {
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red',
}
) self.logger = logging.getLogger('example')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
self.logger.addHandler(handler)
self.logger.setLevel(logging.DEBUG) def setLevel(self, opt):
self.logger.setLevel(opt) def log(self, opt, str):
if opt == 'debug':
self.logger.debug(str)
if opt == 'info':
self.logger.info(str)
if opt == 'warning':
self.logger.warning(str)
if opt == 'error':
self.logger.error(str)
if opt == 'critical':
self.logger.critical(str) def log_if(self, opt, flag, str):
if (flag == True):
self.log(opt, str) def debug(self, str):
self.logger.debug(str) def debug_if(self, flag, str):
if (flag == True):
self.logger.debug(str) def info(self, str):
self.logger.info(str) def info_if(self, flag, str):
if (flag == True):
self.logger.info(str) def warning(self, str):
self.logger.warning(str) def warning_if(self, flag, str):
if (flag == True):
self.logger.warning(str) def error(self, str):
self.logger.error(str) def error_if(self, flag, str):
if (flag == True):
self.logger.error(str) def critical(self, str):
self.logger.critical(str) def critical_if(self, flag, str):
if (flag == True):
self.logger.critical(str)
myLogger
还有一个demo
import logging
from myLogger import myLogger def demo():
log = myLogger()
log.log('debug', 'log debug test') log.log_if('info', True, 'log_if info test')
log.log('warning', 'log warning test')
log.log_if('warning', False, 'log_if warning test')
log.log_if('error', True, 'log_if error test')
log.log('critical', 'log critical test') print(' ') log.debug('log debug function test')
log.info('log info function test')
log.warning('log warning function test')
log.error('log error function test')
log.critical('log critical function test') print(' ') log.setLevel(logging.WARNING)
log.info('log info function test set level')
log.warning('log warning function test set level')
log.error_if(True, 'log error if true')
log.critical_if(False, 'log critical if false') if __name__ == '__main__':
demo()
myLoggerDemo
效果就如下图:

下面稍微解释一下python的logging的原理:
我们以python2.7的logging模块为例子:
先查看logging最开始的一个函数currentframe():
# next bit filched from 1.5.2's inspect.py
def currentframe():
"""Return the frame object for the caller's stack frame."""
try:
raise Exception
except:
return sys.exc_info()[2].tb_frame.f_back
这个函数的作用就是获得当前函数(caller)的在内存中的栈帧。
那么这个函数有什么用的呢?
下面还有一句话:
# _srcfile is used when walking the stack to check when we've got the first
# caller stack frame.
#
_srcfile = os.path.normcase(currentframe.__code__.co_filename)
通过currentframe()的信息,就能获得_srcfile,也就是这个python_root/lib/logging/__init__.py的filename。
而我们在import logging之后,例如通过log.info(),希望获得当前的filename,logging是怎么做的呢?
在logging/__init__.py中的class Logger(Filterer)中有一个函数findCaller():
def findCaller(self):
"""
Find the stack frame of the caller so that we can note the source
file name, line number and function name.
"""
f = currentframe()
#On some versions of IronPython, currentframe() returns None if
#IronPython isn't run with -X:Frames.
if f is not None:
f = f.f_back
rv = "(unknown file)", 0, "(unknown function)"
while hasattr(f, "f_code"):
co = f.f_code
filename = os.path.normcase(co.co_filename)
if filename == _srcfile:
f = f.f_back
continue
rv = (co.co_filename, f.f_lineno, co.co_name)
break
return rv
显然这个函数的作用就是先获得当前这个findCaller的栈帧,然后不断地回退,一直到栈帧的文件信息不是当前logging/__init__.py为止,这时候就是我调用log.info()的具体位置了。
所以为了添加彩色弹幕信息,我们在新加一个myLogger类的时候,记得把logging中的_srcfile从python_root/lib/logging/__init__.py换成当前文件就好了,替换的方法和logging本身如出一辙。
至此我们理解和改造python log告一段落,但是glog的checkeq我是坚决不会写的(因为不会)。
Python logging系统的更多相关文章
- Python logging日志系统
写我小小的日志系统 配置logging有以下几种方式: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件, ...
- python logging模块可能会令人困惑的地方
python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调 ...
- Python LOGGING使用方法
Python LOGGING使用方法 1. 简介 使用场景 场景 适合使用的方法 在终端输出程序或脚本的使用方法 print 报告一个事件的发生(例如状态的修改) logging.info()或log ...
- Python logging 模块和使用经验
记录下常用的一些东西,每次用总是查文档有点小麻烦. py2.7 日志应该是生产应用的重要生命线,谁都不应该掉以轻心 有益原则 级别分离 日志系统通常有下面几种级别,看情况是使用 FATAL - 导致程 ...
- python logging模块使用流程
#!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.debug('debug message') logging ...
- python logging详解及自动添加上下文信息
之前写过一篇文章日志的艺术(The art of logging),提到了输出日志的时候记录上下文信息的重要性,我认为上下文信息包括: when:log事件发生的时间 where:log事件发生在哪个 ...
- python logging模块使用教程
简单使用 #!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.debug('debug message') lo ...
- 0x01 Python logging模块
目录 Python logging 模块 前言 logging模块提供的特性 logging模块的设计过程 logger的继承 logger在逻辑上的继承结构 logging.basicConfig( ...
- python logging 配置
python logging 配置 在python中,logging由logger,handler,filter,formater四个部分组成,logger是提供我们记录日志的方法:handler是让 ...
随机推荐
- WebStorm过期解决方法
第一步:先删除C:\Users\本机用户名\.WebStorm2016.3\config文件中eval文件. 第二步:打开webstrom 如图,填写许可证激活码:http://idea.imsxm. ...
- Win7 指定以某个用户运行某个程式
登陆的是用户A,想要以用户B执行某个程式,可以在cmd命令符下执行以下语句 runas /user:Domain\UserB /savecred notepad.exe 说明:/user:的后面即为 ...
- 对八皇后的补充以及自己解决2n皇后问题代码
有了上次的八皇后的基础.这次准备解决2n皇后的问题,: //问题描述// 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行./ ...
- 前端框架bootstrap(响应式布局)入门
Bootstrap,是基于HTML,CSS.javascript的前端框架 该框架已经预定义了一套CSS样式和与样式相对应的js代码(对应的样式有对应的特效.) 开发人员只需要编写HTML结构,添加b ...
- webview 监听及获取cookie
https://www.cnblogs.com/pjl43/p/9866753.html https://www.jianshu.com/p/55092eb06c17 requests: https: ...
- Kafka启动报错 : ERROR Processor got uncaught exception
参照我之前的一篇博文Kafka学习之(二)Centos下安装Kafka安装了kafka并启动,状况并不像我之前最初的预期,报错了,并且我在当前Linux环境下安装的Java版本.Kafka版本都是和之 ...
- Job for network.service failed because the control process exited with error code
转自:https://blog.csdn.net/dongfei2033/article/details/81124465 今天在centOS 7下更改完静态ip后发现network服务重启不了,翻遍 ...
- 第一次使用eclipse出现的问题
最近开始学习java,在一系列操作下安装好了eclipse后,按照书上的问题写了一个小程序 问题: 用户从键盘只能输入整数,程序输出这些整数的乘积. 看到这个问题后就感觉和c语言蛮像的,首先去ecli ...
- ace-editor线上代码编辑器
package.json { "name": "vue-cli", "version": "1.0.0", " ...
- Appium测试安卓apk遇到的问题及解决方法
1.Showing error - “Returned value cannot be converted to WebElement: {ELEMENT=1} 解决方法:https://sqa.s ...