日前上班時,因為想要有效的對用來debug的字串做formatting,所以就查了一下python的文件.
一開始看到的是logging這個module,他的功能相當易用且實用,可以自訂一些字串和日期在log時的格式,還有一些logger應該幫你做的事可以設定.但是有個我很想要的功能:"自動印出caller的位置(file, function, etc.)"沒有辦法做到,因為它不是設計來做這件事的.
很來又在python裡翻滾了一下,發現理面有個似乎可以用的module叫inspect.這個模組是用來讓你抓取python runtime的資訊用的.
其中就有方法可以把目前的stack抓出來,當下就覺得我找到對的東西了,稍微試著寫了個簡單的Logger,果然是我要的東西啊!
下面是我寫的簡單的Logger,可以幫你把caller的file, function, line number印出來:
import inspect
import os.path
class Logger( object):
LEVEL_MESSAGE, LEVEL_WARNING, LEVEL_ERROR, LEVEL_CRITICAL = range( 4)
@staticmethod
def __getLevelName( level):
if level == Logger.LEVEL_MESSAGE:
return 'MESSAGE'
elif level == Logger.LEVEL_WARNING:
return 'WARNING'
elif level == Logger.LEVEL_ERROR:
return 'ERROR'
elif level == Logger.LEVEL_CRITICAL:
return 'CRITICAL'
else:
return 'UNKNOWN'
__slots__ = ( 'logLevel')
def __init__( self, logLevel = LEVEL_WARNING):
self.__initVariables( logLevel)
def __initVariables( self, logLevel):
self.logLevel = logLevel
def log( self, logLevel, message, reverseStackCount = 1):
if logLevel >= self.logLevel:
stack = inspect.stack()
if len( stack) >= reverseStackCount:
frame = stack[ reverseStackCount]
file = os.path.split( frame[ 1])[ 1]
output = '[%s] [%s:%d] [%s]' % ( Logger.__getLevelName( logLevel), file, frame[ 2], frame[ 3])
print output, message
def message( self, message):
self.log( Logger.LEVEL_MESSAGE, message, reverseStackCount = 2)
def warning( self, message):
self.log( Logger.LEVEL_WARNING, message, reverseStackCount = 2)
def error( self, message):
self.log( Logger.LEVEL_ERROR, message, reverseStackCount = 2)
def critical( self, message):
self.log( Logger.LEVEL_CRITICAL, message, reverseStackCount = 2)
def test(obj):
obj.message( 'testing:test')
def test2(obj):
obj.error( 'testing:test2')
if __name__ == '__main__':
obj = Logger()
obj.log( Logger.LEVEL_ERROR, 'testing')
test(obj)
test2(obj)