2

我有以下方法来处理我的 python 程序中的日志记录

def createLogger(logger, logLang):
    """
    Setting up logger
    """
    log_format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    file_handler = logging.FileHandler(filename=(os.path.join(OUT_DIR_LOGS, logLang + '-userdynamics.log')))
    file_handler.setFormatter(log_format)
    logger.setLevel(logging.INFO)
    logger.addHandler(file_handler)

这是一个大型数据收集代码库,为了避免远程服务器上的配额限制,我实现了以下 gzip 和 tar 程序,

def gzipLogs(lang):
    """
    Compressing and tar
    """
    # Compressing logfiles and removing the old logfile
    original_filePath = OUT_DIR_LOGS + "/" +lang + "-userdynamics.log"
    gzip_filePath = OUT_DIR_LOGS + "/" + lang +"-userdynamics.gz"
    with open(original_filePath , 'rb') as original_file:
        with gzip.open(gzip_filePath, 'wb') as zipped_file:
            zipped_file.writelines(original_file)
    os.remove(original_filePath)
    # Compressing language folders that has data
    folder_path = OUT_DIR + "/" + lang
    tar_file = tarfile.open(folder_path + ".tgz", "w:gz")
    # add timestamp to arch file
    tar_file.add(folder_path, arcname = NOW + "_" + lang)
    tar_file.close()
    # delete the original file
    shutil.rmtree(folder_path)

我在嵌套的 for 循环中进行数据收集过程,并按如下所述调用记录器:

for something in somethings:
    for item in items:
        log = logging.getLogger()
        # Calling the logging configuration function.
        createLogger(log, lang)

一切正常,但是当它被执行时,在删除文件 .nsf 文件残留物后会留下,同时导致配额问题保持原样。

所以我添加了以下代码段来关闭日志文件处理程序,但现在我最终得到以下错误:

关闭日志文件的代码:

unclosed_logs = list(log.handlers)
for uFile in unclosed_logs:
    print uFile
    log.removeHandler(uFile)
    uFile.flush()
    uFile.close()

上面的代码最终给了我这个错误:

Traceback (most recent call last):
  File "/somefilepath/SomePythonFile.py", line 529, in <module>
    main()
  File "/somefilepath/SomePythonFile.py", line 521, in main
    gzipLogs(lang)
  File "/somefilepath/SomePythonFile.py", line 61, in gzipLogs
    with gzip.open(gzip_filePath, 'wb') as zipped_file:
AttributeError: GzipFile instance has no attribute '__exit__'

这是处理程序关闭代码段时 main 方法的样子:

for something in somethings:
    for item in items:
        log = logging.getLogger()
        # Calling the logging configuration function.
        createLogger(log, lang)
    unclosed_logs = list(log.handlers)
    for uFile in unclosed_logs:
        print uFile
        log.removeHandler(uFile)
        uFile.flush()
        uFile.close()

我究竟做错了什么?我处理记录器是否错误?还是我过早关闭文件?

4

2 回答 2

1

有很多事情可能会导致问题:

  1. 您应该只在程序的一处配置日志记录(例如设置级别、添加处理程序),最好从if __name__ == '__main__'子句中配置。你似乎没有这样做。请注意,您可以使用WatchedFileHandler和使用外部旋转器来旋转日志文件 - 例如logrotate提供旋转和压缩功能。
  2. 您的错误__exit__与日志记录无关 - 它可能与 Python 版本问题有关。GZipFile仅在 Python 2.7 / 3.2 中可用with- 在旧版本中,如果您尝试GZipFilewith语句中使用 a,您将收到错误消息。
于 2013-03-13T12:08:23.427 回答
0

经过一番研究,我意识到我正在执行该文件的服务器是针对 python 2.6 运行的,而在 2.6 GZip 模块中没有with open. 要回答这个问题,要么切换到 python 2.7,要么将实现更改为 try catch 块中的老式文件打开文件。

try:
    inOriginalFile = open(original_filePath, 'rb')
    outGZipFile = gzip.open(gzip_filePath, 'wb')
    try:
        outGZipFile.writelines(inOriginalFile)
    finally:
        outGZipFile.close()
        inOriginalFile.close()
except IOError as e:
    logging.error("Unable to open gzip files, GZIP FAILURE")

这就是我解决这个问题的方法。

于 2013-03-18T23:14:54.077 回答