【发布时间】:2015-04-05 17:46:12
【问题描述】:
我正在使用日志记录模块将脚本中的打印语句输出到控制台和日志文件。但是,每次我运行脚本时,输出似乎都会附加到控制台和日志中打印的内容,而不是覆盖那里的内容。例如,第一次运行脚本时,我会在控制台和日志文件中得到以下输出:
This print statement is going to both the console and the log
The year is: 2015
我第二次运行脚本时,我在控制台中得到了这个:
This print statement is going to both the console and the log
This print statement is going to both the console and the log
The year is: 2015
The year is: 2015
第三次:
This print statement is going to both the console and the log
This print statement is going to both the console and the log
This print statement is going to both the console and the log
The year is: 2015
The year is: 2015
The year is: 2015
等等..并且日志文件不断追加,所以我最终得到:
This print statement is going to both the console and the log
The year is: 2015
This print statement is going to both the console and the log
This print statement is going to both the console and the log
The year is: 2015
The year is: 2015
This print statement is going to both the console and the log
This print statement is going to both the console and the log
This print statement is going to both the console and the log
The year is: 2015
The year is: 2015
The year is: 2015
我想要的是日志文件和控制台都只给我以下内容,无论我重新运行脚本多少次:
This print statement is going to both the console and the log
The year is: 2015
注意:我目前能够得到我想要的唯一方法是在脚本运行之间关闭 Python,但这不是一个实际的解决方案。
我已经尝试过使用 flush() 并尝试过这样做:
logger = logging.basicConfig(filemode='w', level=logging.DEBUG)
但我无法让它与我的代码一起使用。有人可以帮忙吗?这是我的代码:
import inspect
import logging
import datetime
def getDate():
now = datetime.datetime.now()
m = now.month
d = now.day
y = str(now.year)
if m < 10:
m = "0"+str(m)
else:
m = str(m)
if d < 10:
d = "0"+str(d)
else:
d = str(d)
y = y[2:]
formatted_date = m+d+y
return formatted_date
def function_logger(file_level, console_level = None):
function_name = inspect.stack()[1][3]
logger = logging.getLogger(function_name)
logger.setLevel(logging.DEBUG) #By default, logs all messages
if console_level != None:
ch = logging.StreamHandler() #StreamHandler logs to console
ch.setLevel(console_level)
ch_format = logging.Formatter('%(message)s')
ch.setFormatter(ch_format)
logger.addHandler(ch)
log_name = 'Test_log' + getDate() + '.log'
fh = logging.FileHandler(log_name.format(function_name))
fh.setLevel(file_level)
fh_format = logging.Formatter('%(message)s')
fh.setFormatter(fh_format)
logger.addHandler(fh)
return logger
def f1():
global logger
year = '2015'
logger.info("The year is: %s" % (year))
def main():
global logger
logger = function_logger(logging.INFO, logging.INFO)
logger.info('This print statement is going to both the console and the log')
f1()
logging.shutdown()
if __name__ == '__main__':
main()
【问题讨论】:
-
您看到这一点是因为每个处理程序都会发出一次记录,如果您多次运行脚本,您将在每个
addHandler()调用中注册一个新的处理程序。跟踪您的日志处理程序并在try..finally中再次删除它们,或者在添加它们之前检查是否已经为您要添加的类型注册了一个。 -
(在每次运行期间打印
logger.handlers以查看发生了什么) -
谢谢。将我的两个 addHandlers 都放在 if not logger.handlers: 下解决了重复条目的问题。但是,还有一个仅与日志文件有关的次要问题,即日志仍然被附加到而不是被覆盖。我该如何解决这个剩余的日志问题?
-
如果您查看
FileHandler的构造函数,它的mode默认为'a'(附加)。所以使用FileHandler(log_name.format(function_name), mode='w')覆盖现有文件而不是追加(mode的语义与open()相同)。