Python日志记录失败,网络驱动器上有日志文件(windows 10)



我想使用python的日志记录模块将日志记录到网络驱动器上的文件中。我的问题是,日志记录在某个随机点失败,给了我这个错误:

--- Logging error ---
Traceback (most recent call last):
File "c:programmeanaconda3liblogging__init__.py", line 1085, in emit
self.flush()
File "c:programmeanaconda3liblogging__init__.py", line 1065, in flush
self.stream.flush()
OSError: [Errno 22] Invalid argument
Call stack:
File "log_test.py", line 67, in <module>
logger_root.error('FLUSH!!!'+str(i))
Message: 'Minute:120'
Arguments: ()
--- Logging error ---
Traceback (most recent call last):
File "c:programmeanaconda3liblogging__init__.py", line 1085, in emit
self.flush()
File "c:programmeanaconda3liblogging__init__.py", line 1065, in flush
self.stream.flush()
OSError: [Errno 22] Invalid argument
Call stack:
File "log_test.py", line 67, in <module>
logger_root.error('FLUSH!!!'+str(i))
Message: 'FLUSH!!!120'
Arguments: ()

我在一台装有Windows 10(1909版(的虚拟机上,使用的是Python 3.8.3和日志0.5.1.2。该脚本在存储日志文件的网络驱动器上的虚拟环境中运行。我正在编写一个脚本,该脚本正在自动执行一些数据质量控制任务,但我不能100%确定该脚本将在哪里(网络驱动器、本地驱动器等(结束,因此它应该能够在所有可能的情况下登录。错误不会出现在脚本中的同一位置/行,而是随机出现的。有时程序(总共约120分钟(完成时根本不会出现错误。

到目前为止我尝试了什么:

我相信日志文件在某个时候是关闭的,这样就不会有新的日志消息写入其中。我写了一个简单的脚本,基本上只做日志检查它是否与我的原始脚本或日志过程本身有关。由于";只记录脚本";也随机失败,当它在网络驱动器上运行时,但不是在我的本地驱动器上运行,我认为它与网络驱动器的连接有关。我曾想过将整个日志记录存储在内存中,然后写入文件,但MemoryHandler也会在脚本开始时打开文件,因此在某个时候会失败。

这是我的";只记录脚本";(log_test.py(:

import logging
import logging.handlers
import os
import datetime
import time
##################################################################
# setting up a logger to create a log file with information about this programm
logfile_dir = 'logfiles_test'
CHECK_FOLDER = os.path.isdir(logfile_dir)
# if folder doesn't exist, create it
if not CHECK_FOLDER:
os.makedirs(logfile_dir)
print("created folder : ", logfile_dir)
log_path = '.\'+logfile_dir+'\'
Current_Date = datetime.datetime.today().strftime ('%Y-%m-%d_')
log_filename = log_path+Current_Date+'logtest.log'
print(log_filename)
# Create a root logger
logger_root = logging.getLogger()
# Create handlers
f1_handler = logging.FileHandler(log_filename, mode='w+')
f2_handler = logging.StreamHandler() 
f1_handler.setLevel(logging.INFO)
f2_handler.setLevel(logging.INFO)
# Create formatters and add it to handlers
f1_format = logging.Formatter('%(asctime)s | %(name)s | %(levelname)s | %(message)s n')
f2_format = logging.Formatter('%(asctime)s | %(name)s | %(levelname)s | %(message)s n')
f1_handler.setFormatter(f1_format)
f2_handler.setFormatter(f2_format)
# create a memory handler
memoryhandler = logging.handlers.MemoryHandler(
capacity=1024*100,
flushLevel=logging.ERROR,
target=f1_handler,
flushOnClose=True
)

# Add handlers to the logger
logger_root.addHandler(memoryhandler)
logger_root.addHandler(f2_handler)
logger_root.setLevel(logging.INFO)
logger_root.info('Log-File initiated.')
fname = log_path+'test.log'
open(fname, mode='w+')
for i in range(60*4):
print(i)
logger_root.warning('Minute:'+str(i))
print('Write access:', os.access(fname, os.W_OK))
if(i%10==0):
logger_root.error('FLUSH!!!'+str(i))
time.sleep(60)

是我的日志记录过程出现了严重问题,还是因为网络驱动器?你们中有人对如何解决这个问题有什么想法吗?将整个信息存储在内存中并最终将其写入文件会解决问题吗?我该如何最好地实现这一点?另一个想法是登录本地驱动器,然后在脚本完成后自动将文件复制到网络驱动器。我们非常感谢您的帮助,因为我已经尝试识别并解决这个问题好几天了。

谢谢!

由于这不会真正在atm上发生,我将发布我对";解决";我的问题。这不是一个令人满意的解决方案,因为当代码失败时它会失败,但总比根本不记录要好。该解决方案的灵感来自于这个问题的答案:使用日志将消息记录到阵列/列表

以下是我所做的:

import io
#####################################
# first create an in-memory file-like object to save the logs to
log_messages = io.StringIO()
# create a stream handler that saves the log messages to that object
s1_handler = logging.StreamHandler(log_messages)
s1_handler.setLevel(logging.INFO)
# create a file handler just in case
f1_handler = logging.FileHandler(log_filename, mode='w+')
f1_handler.setLevel(logging.INFO)
# set the format for the log messages
log_format = '%(asctime)s | %(name)s | %(levelname)s | %(message)s n'
f1_format = logging.Formatter(log_format)
s1_handler.setFormatter(f1_format)
f1_format = logging.Formatter(log_format)
# add the handler to the logger
logger_root.addHandler(s1_handler)
logger_root.addHandler(f1_handler)
#####################################
# here would be the main code ...
#####################################
# at the end of my code I added this to write the in-memory-message to the file
contents = log_messages.getvalue()
# opening a file in 'w'
file = open(log_filename, 'w')
# write log message to file
file.write("{}n".format(contents))
# closing the file and the in-memory object
file.close()
log_messages.close()

显然,当代码失败,但代码试图捕捉大多数错误时,这会失败,所以我希望它能起作用。我去掉了内存处理程序,但保留了一个文件处理程序,这样在发生真正的故障时,至少会记录一些日志,直到文件处理程序出现故障。它远非理想,但它对我的atm很有效。如果你还有其他建议/改进,我很乐意听到!

最新更新