Python使用logging模块时,如何消除日志与时间的多余换行?
问题描述
使用Python的logging模块将日志写入外部文件,通过getLogger()指定日志名称时遇到问题:调用logger.warning()写入日志会自动换行,随后用write()写入时间又新增一行,导致日志内容和时间分两行显示。希望将两者合并为同一行,同时保证统计日志行数的for循环正常工作。
代码示例
#filename: loghelper.py import logging import datetime from logging import DEBUG, WARNING, FileHandler, StreamHandler logger = logging.getLogger(__name__) logger.level= WARNING logger.handlers = [FileHandler('loghelperDEBUG.txt', 'a')] t = datetime.datetime.now(tz= None).strftime('%d-%m-%Y - %H:%M:%S') with open('loghelperDEBUG.txt', 'r') as f: fil = f.read() n= 0 for i in fil: if i == '\n': n +=1 n+=1 logger.warning(f'LogHelper being used!, {n} times used') print("") print(f'loghelper used a total of {n} times by now.') with open('loghelperDEBUG.txt', 'a') as wf: wf.write(f' -- {t}\n') #need to deal with newlines
当前运行两次后的日志输出
LogHelper being used!, 1 times used 21-03-2023 - 14:21:13 LogHelper being used!, 3 times used 21-03-2023 - 14:21:23
期望输出
LogHelper being used!, 1 times used -- 21-03-2023 - 14:21:13 LogHelper being used!, 2 times used -- 21-03-2023 - 14:21:23
解决方案
核心问题是logging模块默认会在每条日志末尾添加换行符,导致后续write()的内容另起一行。以下两种方案都能解决问题,且保留行数统计逻辑的有效性:
方案1:直接将时间整合到日志内容(推荐)
这是最简洁的方式,不需要分开写入日志和时间,一次性输出整行内容,同时通过自定义Formatter去掉logging默认的换行控制:
#filename: loghelper.py import logging import datetime from logging import DEBUG, WARNING, FileHandler, Formatter logger = logging.getLogger(__name__) logger.level = WARNING # 自定义日志格式,只输出消息内容,不额外添加换行 formatter = Formatter('%(message)s') file_handler = FileHandler('loghelperDEBUG.txt', 'a') file_handler.setFormatter(formatter) logger.handlers = [file_handler] t = datetime.datetime.now(tz=None).strftime('%d-%m-%Y - %H:%M:%S') with open('loghelperDEBUG.txt', 'r') as f: fil = f.read() n = 0 for i in fil: if i == '\n': n += 1 n += 1 # 直接把时间拼进日志内容,末尾手动添加换行 logger.warning(f'LogHelper being used!, {n} times used -- {t}\n') print(f'\nloghelper used a total of {n} times by now.')
方案2:调整文件指针覆盖默认换行
如果必须分开写入日志和时间,可以在logger.warning()之后,将文件指针移到末尾的换行符位置,用时间内容覆盖该换行:
#filename: loghelper.py import logging import datetime import os from logging import DEBUG, WARNING, FileHandler, StreamHandler logger = logging.getLogger(__name__) logger.level = WARNING logger.handlers = [FileHandler('loghelperDEBUG.txt', 'a')] t = datetime.datetime.now(tz=None).strftime('%d-%m-%Y - %H:%M:%S') with open('loghelperDEBUG.txt', 'r') as f: fil = f.read() n = 0 for i in fil: if i == '\n': n += 1 n += 1 logger.warning(f'LogHelper being used!, {n} times used') print(f'\nloghelper used a total of {n} times by now.') # 移动文件指针到倒数第一个字节(即logger添加的换行符位置),覆盖写入时间和新换行 with open('loghelperDEBUG.txt', 'rb+') as wf: wf.seek(-1, os.SEEK_END) wf.write(f' -- {t}\n'.encode())
说明
两种方案最终都会让每条日志以\n结尾,原有的行数统计逻辑(统计\n数量再加1)可以正常工作。
内容的提问来源于stack exchange,提问作者Átila Lima de Brito
相关产品推荐
相关产品推荐

