我们都知道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系统的更多相关文章

  1. Python logging日志系统

    写我小小的日志系统 配置logging有以下几种方式: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件, ...

  2. python logging模块可能会令人困惑的地方

    python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调 ...

  3. Python LOGGING使用方法

    Python LOGGING使用方法 1. 简介 使用场景 场景 适合使用的方法 在终端输出程序或脚本的使用方法 print 报告一个事件的发生(例如状态的修改) logging.info()或log ...

  4. Python logging 模块和使用经验

    记录下常用的一些东西,每次用总是查文档有点小麻烦. py2.7 日志应该是生产应用的重要生命线,谁都不应该掉以轻心 有益原则 级别分离 日志系统通常有下面几种级别,看情况是使用 FATAL - 导致程 ...

  5. python logging模块使用流程

    #!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.debug('debug message') logging ...

  6. python logging详解及自动添加上下文信息

    之前写过一篇文章日志的艺术(The art of logging),提到了输出日志的时候记录上下文信息的重要性,我认为上下文信息包括: when:log事件发生的时间 where:log事件发生在哪个 ...

  7. python logging模块使用教程

    简单使用 #!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.debug('debug message') lo ...

  8. 0x01 Python logging模块

    目录 Python logging 模块 前言 logging模块提供的特性 logging模块的设计过程 logger的继承 logger在逻辑上的继承结构 logging.basicConfig( ...

  9. python logging 配置

    python logging 配置 在python中,logging由logger,handler,filter,formater四个部分组成,logger是提供我们记录日志的方法:handler是让 ...

随机推荐

  1. 关于linux系统CPU篇--->CPU使用率升高

    1.CPU使用率为单位时间内CPU使用情况的统计,以百分比的方式展示. LINUX作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运 ...

  2. 画多边形form并填充背景色(可以实现圆角边框 有锯齿)

    public Form1() { InitializeComponent(); this.BackColor = ColorTranslator.FromHtml("#F7F1F1" ...

  3. QGraphicsItem的paint函数的一些相关问题

    在QGraphicsItem中,一个成员函数paint(),其声明如下: void QGraphicsItem::paint ( QPainter * painter, const QStyleOpt ...

  4. JavaWeb案例:登陆和注册

    mvc开发模式简介 M: Model模型 JavaBeanV:view视图 JSPC:Controller控制器 Servlet 其实就是JSP + Servlet + JavaBean上面的Java ...

  5. day14

    迭代器什么是迭代器(iterator) 器指的是某种工具 迭代指的是更新换代的过程,例如应用程序的版本更新从1.0 变成 1.2 迭代的目的是要根据上一个结果,产生下一个结果,这是一个重复的过程,但不 ...

  6. Lesson 02-Linux基础命令(一)

    查看系统IP Linux:ifconfig/ip a Windows:ipconfig vi:创建文件并编辑 touch:创建空文件 mkdir ~/a 在用户家目录下创建名称为a的文件夹 -p 创建 ...

  7. 【NOIP2015普及组】推销员_详解

    题目 题目大意 阿明是一名推销员--螺丝街是一条直线,一端有入口,一共有 \(N(<100,000)\) 家住户,第 \(i\) 家住户到入口的距离为 \(S_i\) 米.由于同一栋房子里可以有 ...

  8. 找出 Xcode 编译C/C++过程文件及生成文件

    在使用 Xcode 编写C/C++时,会发现在项目的目录位置是没有编译过程的那些 .o .exe 文件,只有一个 C/C++ 源代码 .c 文件.如下图(在Mac OS的finder中右键窗口标题名称 ...

  9. Docker学习(转)

    1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这 ...

  10. Java核心知识盘点(三)- 框架篇-Spring

    Spring的两大核心特性:IOC.AOP IOC:控制反转.依赖注入,它并不是一种技术实现,而是一种思想.把一些相互依赖对象的创建.协调工作交给Spring容器来管理,每个对象只需要关注其自身的业务 ...