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是让 ...
随机推荐
- Spring:容器基本用法
bean是Spring 最核心的东西,打个比方,假设Spring是一个水桶,那么bean就是水桶里的水,水桶离开水后,就没啥作用了.我们先来看一下bean的定义: public class Perso ...
- centos安装图形界面
1.首先安装X(X Window System),命令为 yum groupinstall "X Window System" 回车 2.由于这个软件组比较大,安装过程会比较 ...
- iOS绘制坐标图,折线图-Swift
坐标图,经常会在各种各样的App中使用,最常用的一种坐标图就是折线图,根据给定的点绘制出对应的坐标图是最基本的需求.由于本人的项目需要使用折线图,第一反应就是搜索已经存在的解决方案,因为这种需求应该很 ...
- 有关this
this是Javascript函数内部的一个特殊对象,引用的是函数运行时的环境对象,也就是说,this是动态的(箭头函数除外),是在运行时进行绑定的,并不是在编写时绑定(箭头函数是编写时绑定). th ...
- 王之泰201771010131《面向对象程序设计(java)》第十七周学习总结
第一部分:理论知识学习部分 第14章 并发 线程同步 多线程并发运行不确定性问题解决方案:引入线 程同步机制,使得另一线程要使用该方法,就只 能等待. ⚫ 在Java中解决多线程同步问题的方法有两种: ...
- Bootstrap3基础 栅格系统 列中有行,行中有列
内容 参数 OS Windows 10 x64 browser Firefox 65.0.2 framework Bootstrap 3.3.7 editor ...
- html知识点汇总(持续更新中)
本人从事前端行业三年多,打算从今天开始整理一些关于前端的一些比较经典的知识点,持续更新中...希望能对一些相关知识点有疑问的朋友有一些帮助! HTML篇: 1.常见的行内元素/块级元素/空元素有哪些? ...
- bootstrap:modal & iframe
form提交绑定到特定的iframe & form的结果在dialog上显示 form:target属性 <!-- when the form is submitted, the ser ...
- Matplotlib.pyplot 把画图保存为图片
在plt.show()之前执行plt.savefig()函数即可. 简单例子: import matplotlib.pyplot as plt x=[1,2,3,4,5] y=[10,5,15,10, ...
- jquery延迟加载(懒加载)插件
Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预 ...