likes
comments
collection
share

Python用模拟logging模块,组装变量型日志

作者站长头像
站长
· 阅读数 4

最近研究Python的日志模块,发现要么往文件里写,要么打印到控制台上,就没找到存到变量以及数据库的,这篇文章就是来探究如何取得和日志模块一样的数据。

原始的日志模块

下面是一个简单的日志模块,设置了控制台和文件两种日志形式,日志级别是一致的。其中message_fmt中,%(XXX)s代表的是一些约定好的名称,用于取得系统信息,常用的有asctime时间,lineno行号,levelname日志级别,filename文件名,funcName函数名,process进程id,thread线程id,threadName线程名称,以及message日志信息。

 

import logging  
  
  
class Logger:  
    def __init__(self):  
        self.logger = logging.getLogger('MyLogger')  
        message_fmt = '%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'  
        date_fmt = '%Y-%m-%d %H:%M:%S'  
        fmt = logging.Formatter(fmt=message_fmt, datefmt=date_fmt)  
        self.logger.setLevel(logging.INFO)  
        stream_handler = logging.StreamHandler()  
        file_handler = logging.FileHandler('log.txt', encoding='utf-8')  
        stream_handler.setFormatter(fmt)  
        file_handler.setFormatter(fmt)  
        self.logger.addHandler(stream_handler)  
        self.logger.addHandler(file_handler)  
  
  
if __name__ == '__main__':  
    my_logger = Logger().logger  
    my_logger.info('1233')

日志的显示效果如下:

Python用模拟logging模块,组装变量型日志

模拟日志相关信息

时间模拟

时间模拟是最简单的了,使用datetime模块即可,并转换为指定格式的字符串

time_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

 

文件名、函数名和行号模拟

可以使用inspect模块中的getframeinfo获取当前frame的信息中关于文件名字、函数名和行号的部分,局限性在于只能在当前位置获取这几个信息,封装到函数里就是函数的信息了。

current_frame = inspect.currentframe()  
file_pathname = inspect.getframeinfo(current_frame).filename  
filename = file_pathname.split('/')[-1]  
print(filename)  
func_name = inspect.getframeinfo(current_frame).function  
lineno = inspect.getframeinfo(current_frame).lineno  
print(func_name,lineno)

文件名也可以通过os模块获取

print(os.path.basename(__file__))

函数名和行号也可以通过sys模块获取

print(sys._getframe().f_code.co_name)

print(sys._getframe().f_lineno)

进程、线程id名称模拟

线程方面使用threading模块获得当前线程的信息。

t = threading.currentThread()

print(t.ident) print(t.getName())

进程方面,使用os模块直接获取id

pid = os.getpid() print(pid)

如果还需要获得进程的更详细信息,需要安装psutil模块,查看进程名称,状态和父进程id如下,此处的进程名称其实就是Python自己

s = psutil.Process(pid) print(s.name()) print(s.status()) print(s.ppid())

 

组装

至此已经能够模拟出全部的功能,日志级别和消息是自己写进去的,组装简易版和复杂版分别如下:


message = '1233'  
log_str = f'{time_str} - {filename}[line:{lineno}] - INFO: {message}'  
print(log_str)  
log_str = f'{time_str} - {filename}[line:{lineno}] -pid:{pid}-threadName:{t.getName()}-threadId:{t.ident}- INFO: {func_name} {message} '  
print(log_str)

打印效果如下:

Python用模拟logging模块,组装变量型日志