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是让 ...
随机推荐
- window.location.search 在url中有?name=value时仍为‘’的情况
1,当页面有hash#值 而?name=value在hash #的串后面将会有这种结果 2,为什么 window.location.search 为空? 答:注意上面的search和hash的区别,如 ...
- npm命令
简介:npm(node.js package manager)是Node.js的包管理器 .它创建于2009年,作为一个 开源项目,帮助开发人员轻松共享打包的代码模块 ## 默认方式初始化npm.(进 ...
- Thinking in work
Scheduler? Realtime? sure SCI? Power supply and ECU life. how to assure? EMC?
- Html5 Page Creator,简易h5页面场景制作
- P2178 [NOI2015]品酒大会
思路 在后缀树上进行一些操作就好了 后缀树上LCA的maxlen就是两个后缀的LCP的长度了 然后统计每个点作为LCA的次数和最大值.次大值.最小值.次小值 然后就做完了 代码 #include &l ...
- [ZOJ 4014] Pretty Matrix
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5742 AC代码: /* * 反思: * 1.遇到简单题别激动,先把它 ...
- 8、Dockerfile详解
除了init之外,每一个进程都应该是其他进程的子进程(init是内核启动的),当手动启动nginx时,那么这个nginx就以shell子进程存在.当打开一个命令行提示符时,这个就相当于在运行一个she ...
- kali 32位 更换 xfce4 桌面
kali 32位默认是gnome桌面,我感觉又难看又卡.下面是换xfce4的方法: 1.安装xfce4: apt install kali-defaults kali-root-login deskt ...
- logic pro x 下载
https://pan.baidu.com/s/1gfO5KOV
- 学习笔记77—Iphone集
****************************************************** 如有谬误,请联系指正.转载请注明出处. 联系方式: e-mail: heyi9069@gm ...