我正在努力在我的Python项目中实现日志记录,并且遇到了一些障碍。我正在尝试设置我的日志记录,以便处理程序和格式化程序都组织到一个配置文件中。我现在要做的是设置我的fileHandler
,以便创建一个类似于这样的日志文件:YYYY_MM_DD.log
显然Y代表年份,M代表月份,D代表着这一天。
这是我尝试使用我的配置文件:
[loggers]
keys=root,MainLogger
[handlers]
keys=fileHandler, consoleHandler
[formatters]
keys=logFormatter, consoleFormatter
[logger_root]
level=DEBUG
handlers=fileHandler
[logger_MainLogger]
level=DEBUG
handlers=fileHandler, consoleHandler
qualname=MainLogger
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=consoleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=logFormatter
args=(datetime.now().strftime('%Y_%m_%d.log'), 'a')
[formatter_logFormatter]
format=%(asctime)s | %(levelname)-8s | %(lineno)04d | %(message)s
[formatter_consoleFormatter]
format=%(asctime)s | %(levelname)-8s | %(fillname)s-%(funcName)s-%(lineno)04d | %message)s
我用来测试配置的文件非常简单:
import logging
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('MainLogger')
logger.debug("TEST")
我目前得到的具体错误是:
configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: "%Y_%m_%d.log'), 'a')"
我已尝试更改%Y
,%m
和%d
,因为错误说明了,但这并不能解决问题。我如何设置配置文件,以便我的日志文件看起来像我想要的那样?
我应该注意当我将文件名更改为test.log
时一切正常,所以这是我似乎唯一的错误。
答案 0 :(得分:4)
您无法在配置文件中使用datetime
,因为它不知道它的含义。但是,您可以在python文件中添加Filehandler
:
import logging.config
from datetime import datetime
logging.config.fileConfig('aaa.conf')
logger = logging.getLogger('MainLogger')
fh = logging.FileHandler('{:%Y-%m-%d}.log'.format(datetime.now()))
formatter = logging.Formatter('%(asctime)s | %(levelname)-8s | %(lineno)04d | %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.debug("TEST")
这样您就可以在处理程序中将日期设置为文件名。
这是配置文件,请注意您在上一个格式化程序中输入了拼写错误,您放置了fillname
而不是filename
而忘记了(
中的message
。< / p>
[loggers]
keys=root,MainLogger
[handlers]
keys=consoleHandler
[formatters]
keys=consoleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_MainLogger]
level=DEBUG
handlers=consoleHandler
qualname=MainLogger
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=consoleFormatter
args=(sys.stdout,)
[formatter_consoleFormatter]
format=%(asctime)s | %(levelname)-8s | %(filename)s-%(funcName)s-%(lineno)04d | %(message)s
这应该可以正常工作。
答案 1 :(得分:4)
这对我有用。
更新此: args =(datetime.now()。strftime(&#39;%Y_%m_%d.log&#39;),&#39; a&#39;)
到
args =(__ import __(&#34; datetime&#34;)。datetime.now()。strftime(&#39;%Y_%m_%d.log&#39;),&#39; a&#39; ;)
参考(例3):http://python-reference.readthedocs.io/en/latest/docs/functions/eval.html
答案 2 :(得分:3)
也许您可以使用Python TimedRotatingFileHandler
代替。您可以设置每天创建新日志文件的时间间隔,并将日期作为后缀。
文档 -
请注意,当天的日志文件没有日期。此文件处理程序仅在新的一天开始时添加日期后缀。
此外,它使用的后缀是&#34;%Y-%m-%d&#34;,这与您想要的略有不同。但是有一个关于如何改变它的问题here。
答案 3 :(得分:1)
也许在之后尝试更改名称您已加载配置文件:
from datetime inport datetime
logging.config.fileConfig('logging.conf')
logging.basicConfig(filename = datetime.now().strftime('%Y_%m_%d.log'))
答案 4 :(得分:1)
在格式字符串中使用双'%'字符与Abhishek建议的方法结合使用,得出了我的情况下可行的解决方案(Python 3.5):
然后,配置文件中的文件处理程序应类似于此文件处理程序:
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=defaultFormatter
args=(__import__("datetime").datetime.now().strftime('/your_path/your_file_name_%%Y-%%m-%%d_%%H-%%M-%%S.log'), 'a')
答案 5 :(得分:1)
我想通过配置文件保持我所有的日志可配置,并且对这里通过代码手动添加处理程序的答案不满意。我想出的解决方案是创建一个继承 FileHandler 的处理程序类,它在调用 FileHandler 构造函数之前将日期附加到文件名参数:
import os
from logging import FileHandler
from datetime import datetime
class TimestampedFileHandler(FileHandler):
def __init__(self, filename, mode='a', encoding=None, delay=False):
filename, extension = os.path.splitext(filename)
filename = f"{filename}_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}{extension}"
FileHandler.__init__(self, filename, mode, encoding, delay)
然后,您可以在配置文件中使用 TimestampedFileHandler,并与其他处理程序一起设置其级别、格式化程序和参数。
答案 6 :(得分:0)
这使用配置文件中的内容,但不直接访问该文件。您可以创建自己的文件处理程序,然后将其添加到记录器中。
import logging
from datetime import datetime
# Create logger.
logger = logging.getLogger('MainLogger')
logger.setLevel(logging.DEBUG)
# Create filehandler with desired filename.
fh = logging.FileHandler('{}.log'.format(datetime.now().strftime('%Y_%m_%d')))
fh.setLevel(logging.DEBUG)
log_formatter = logging.Formatter('%(asctime)s | %(levelname)-8s | %(lineno)04d | %(message)s')
fh.setFormatter(log_formatter)
# Add filehandler to logger.
logger.addHandler(fh)
请注意,a
(append)是FileHandler的默认mode
参数。
答案 7 :(得分:0)
这也有效
from dateime import datetime
log_file = str(datetime.utcnow().strftime('%m_%d_%Y_%I_%M_%S')) + '.log'
logging.basicConfig(filename=log_file, format='%(levelname)s | %(asctime)s | %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.DEBUG)
日志文件名称:04_30_2018_10_03_01.log
答案 8 :(得分:0)
这篇文章很老,但是对于仍在为logging.conf动态命名文件名而困扰的任何人 在调用logging.config.fileConfig()时,您可以传递变量并在日志配置文件中使用它们。 例如:
logging.conf
args=('my_log_%(date)s.log','w')
python.py
import logging.conf
logging.conf.fileConfig('logging.conf', defaults={'date':datetime.now()}
您可能想在此处使用日期格式。
以相同的方式,可以使用任意数量的变量。
答案 9 :(得分:0)
我对python产品的解决方案是保留配置文件的路径到固定日志文件,例如:
[handler_fileHandler] <br>
class=FileHandler <br>
level=DEBUG <br>
formatter=defaultFormatter <br>
args=('../projectnamespace/data/logs/logfile.log',)
并且每天我都会将日志文件移动到较旧的文件夹日志中,这样可以避免拥有庞大的日志文件供以后阅读...。
log_path = str((Path(__file__).parent / 'data' / 'logs' / 'logfile.log').absolute())
log_file_date_created = None
if platform.system() == 'Windows':
log_file_date_created = datetime.fromtimestamp(os.path.getctime(log_path))
else:
stat = os.stat(log_path)
try:
log_file_date_created = stat.st_birthtime
except AttributeError:
# running in Linux. No easy way to get creation dates here,
# we get when its content was last modified.
return stat.st_mtime
if log_file_date_created != None and abs(datetime.today().day - log_file_date_created.day) >= 1:
file_date = str(log_file_date_created.strftime("%m_%d_%Y")) + '_logfile.log'
log_path_new_name = str((Path(__file__).parent / 'data' / 'logs' / 'older' / file_date ).absolute())
os.replace(log_path, log_path_new_name)