Logging Writing Failed maximum recursion depth exceeded in comparison

这个报错是什么原因?

Logging Writing Failed maximum recursion depth exceeded in comparison Logging Writing Failed maximum recursion depth exceeded while calling a Python object Logging Writing Failed maximum recursion depth exceeded while calling a Python object Logging Writing Failed maximum recursion depth exceeded in comparison Logging Writing Failed maximum recursion depth exceeded while calling a Python object Logging Writing Failed maximum recursion depth exceeded while calling a Python object Logging Writing Failed maximum recursion depth exceeded while calling a Python object Logging Writing Failed maximum recursion depth exceeded in comparison Logging Writing Failed maximum recursion depth exceeded while calling a Python object Logging Writing Failed maximum recursion depth exceeded while calling a Python object

这个错误信息表明在你的Python程序中发生了递归深度超过最大限制的问题。Python设置了递归深度的最大限制,以防止无限递归导致栈溢出。通常情况下,递归深度超过1000或者更多次就会触发这个错误。

这种错误可能是由于代码中存在无限递归的情况,或者递归调用层次太深而触发的。要解决这个问题,你可以考虑以下几种方法:

  1. 优化递归算法:检查你的代码,确保递归函数正确地终止条件,并且递归调用不会无限制地进行。你可能需要重新设计递归算法,以减少递归深度。

  2. 使用迭代代替递归:有时,可以将递归算法改写成迭代算法,以避免递归深度问题。这通常需要使用循环来模拟递归过程。

  3. 增加递归深度限制:尽管这不是解决问题的最佳方法,但你可以使用sys.setrecursionlimit()函数来增加Python的递归深度限制。但要注意,这可能会导致栈溢出或其他不稳定的行为,因此谨慎使用。

  4. 重新审视问题:有时,递归并不是解决问题的最佳方法,可能存在更有效的非递归解决方案。重新审视问题并考虑其他算法可能有助于避免递归深度问题。

最好的方法是检查你的代码,确保递归算法被正确实现,并且没有导致无限递归的情况。如果问题仍然存在,考虑使用其他方法来解决问题或减少递归深度。

可以举例说明吗?

当出现"Logging Writing Failed maximum recursion depth exceeded"错误时,这通常是因为在记录日志或执行某些操作时发生了无限递归。以下是一个简单的例子,展示了如何触发这种错误以及如何解决它:

import logging

# 创建一个简单的日志记录器
logging.basicConfig()

def recursive_function(n):
    # 模拟递归操作,但存在无限递归的问题
    if n <= 0:
        return
    else:
        logging.error("Logging Writing Failed maximum recursion depth exceeded")
        recursive_function(n - 1)

try:
    recursive_function(10000)  # 尝试调用具有大量递归深度的函数
except RecursionError as e:
    print(f"RecursionError: {e}")

在这个例子中,recursive_function函数尝试执行递归操作,但没有正确的终止条件,导致无限递归。这将导致"Logging Writing Failed maximum recursion depth exceeded"错误。

要解决这个问题,你可以修改recursive_function函数,添加一个合适的终止条件,以确保递归的结束。例如:

def recursive_function(n):
    # 添加终止条件
    if n <= 0:
        return
    else:
        logging.error("Logging Writing Failed maximum recursion depth exceeded")
        recursive_function(n - 1)

try:
    recursive_function(1000)  # 调用带有终止条件的函数
except RecursionError as e:
    print(f"RecursionError: {e}")

在这个修改后的版本中,递归将在n达到0时终止,不再无限递归,因此不会触发递归深度错误。你应该根据你的具体问题检查代码,并确保递归函数有适当的终止条件,以避免递归深度错误。

我的代码使用了递归吗?如何修改成循环,避免这个报错:

def get_log_path(SERVER_ADDR,SERVER_PORT):

    file_path = os.path.abspath(__file__)

    file_name = os.path.basename(file_path).split(".")[0]

    return os.path.join(base_path, f'logs_{file_name}_{SERVER_ADDR}_{SERVER_PORT}')

 

def cleanup_logs():

    log_path = get_log_path(SERVER_ADDR,SERVER_PORT)

    current_time = time.time()

    for file_name in os.listdir(log_path):

        # 获取文件名中的时间部分

        try:

            creation_str = file_name.split("_")[0] + "_" + file_name.split("_")[1] + "_" + file_name.split("_")[2]

            creation_time = time.mktime(time.strptime(creation_str, "%Y-%m-%d_%H-%M_%S"))

 

        except (ValueError, IndexError):

            # 文件名格式不正确,跳过

            continue

 

        # 如果文件创建时间早于 180 天前,就删除

        if current_time - creation_time > (30 * 24 * 60 * 60):

            file_path = os.path.join(log_path, file_name)

            os.remove(file_path)

 

def configure_logging():

    log_path = get_log_path(SERVER_ADDR,SERVER_PORT)

    os.makedirs(log_path, exist_ok=True)

    log_filename = get_log_filename()

    log_file = os.path.join(log_path, log_filename)

    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', filename=log_file)

 

def get_log_filename():

    now = datetime.datetime.now()

    return now.strftime("%Y-%m-%d.log")

 

def create_new_log():

    log_path = get_log_path(SERVER_ADDR,SERVER_PORT)

    log_files = os.listdir(log_path)

    if len(log_files) >= 300:

        oldest_file = min(log_files)

        os.remove(os.path.join(log_path, oldest_file))

    log_filename = get_log_filename()

    log_filepath = os.path.join(log_path, log_filename)

    return log_filepath

 

def check_log_size(log_filepath):

    log_size = os.path.getsize(log_filepath)

    if log_size > 2 * 1024 * 1024:

        # 创建新的日志文件

        new_log_filepath = create_new_log()

        try:

            shutil.move(log_filepath, new_log_filepath)

            return new_log_filepath

        except PermissionError:

            insert_log(logger, f'{log_filepath} {PermissionError}', log_filepath)

            time.sleep(1)

            return log_filepath

    return log_filepath

 

def insert_log(logger, log_message, log_filepath):

    cleanup_logs()

    try:

        log_filepath = check_log_size(log_filepath)

        # 创建文件处理器

        file_handler = RotatingFileHandler(log_filepath, maxBytes=2 * 1024 * 1024, backupCount=1)

        file_handler.setLevel(logging.DEBUG)

        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

        file_handler.setFormatter(formatter)

        # 添加文件处理器到日志记录器

        logger.addHandler(file_handler)

 

        with log_lock:

            # 添加文件处理器到日志记录器

            logger.addHandler(file_handler)

            try:

                logger.debug(log_message)

                print("log:",log_message)

            except PermissionError:

                insert_log(logger, f'{log_message} {PermissionError}', log_filepath)

                time.sleep(1)  # 延迟0.1秒

 

            # 移除文件处理器

            logger.removeHandler(file_handler)

    except Exception as e:

        print(f"Logging Writing Failed {e}")

        insert_log(logger, f"Logging Writing Failed {e}", log_filepath)

你的代码中没有显式的递归函数,因此不是递归函数导致报错的问题。相反,你的代码涉及到文件处理和日志记录,这些操作通常不会导致递归深度错误。

根据你的代码,问题可能出现在以下几个地方:

  1. 文件处理:你的代码中涉及到了文件的创建、删除和移动操作。如果这些操作在某种情况下导致了无限循环或者递归操作,那么可能会触发递归深度错误。

  2. 日志记录:你的代码使用了Python的logging模块来记录日志,但并没有直接与递归有关的问题。但是,在insert_log函数中,你使用了一个RotatingFileHandler来处理日志文件,这可能会引发问题,尤其是在多线程或多进程环境中,因为你在该函数中多次调用logger.addHandler(file_handler),而没有移除处理器。

为了避免可能的问题,你可以考虑以下几个步骤:

  1. 检查文件操作:确保文件的创建、删除和移动操作没有导致无限循环或递归。你可以在文件操作之前添加日志来跟踪代码的执行。

  2. 日志处理器添加和移除:在insert_log函数中,确保只在必要时添加和移除处理器,以防止重复添加处理器。你可以在处理器添加和移除的地方加入日志来跟踪处理器的操作。

  3. 异常处理:在异常处理部分,你可以更仔细地记录错误信息,以便更好地理解问题的根本原因。

如果你可以提供更多关于具体报错信息或问题的上下文,我将能够提供更具体的建议来解决问题。如果问题仍然存在,请提供更多信息以便我可以帮助你进一步。

如何修改,详细一点

根据你提供的代码,我会逐步指导你如何修改代码以确保避免递归深度错误以及其他潜在问题。首先,我们将关注以下几个主要问题:

  1. 处理器添加和移除:确保只在必要时添加和移除处理器,以防止重复添加处理器。
  2. 异常处理:更仔细地记录错误信息,以便更好地理解问题的根本原因。

我将针对每个问题提供详细的建议。

处理器添加和移除:

在你的代码中,你在insert_log函数中多次添加处理器,但并没有在必要时将它们移除。这可能导致处理器重复添加,可能会导致日志文件被多次写入。为了解决这个问题,你可以修改insert_log函数如下:

def insert_log(logger, log_message, log_filepath):
    cleanup_logs()

    try:
        log_filepath = check_log_size(log_filepath)

        # 创建文件处理器
        file_handler = RotatingFileHandler(log_filepath, maxBytes=2 * 1024 * 1024, backupCount=1)
        file_handler.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        file_handler.setFormatter(formatter)

        # 添加文件处理器到日志记录器
        logger.addHandler(file_handler)

        with log_lock:
            try:
                logger.debug(log_message)
                print("log:", log_message)
            except PermissionError:
                insert_log(logger, f'{log_message} {PermissionError}', log_filepath)
                time.sleep(1)  # 延迟0.1秒

        # 移除文件处理器,以避免重复添加
        logger.removeHandler(file_handler)

    except Exception as e:
        print(f"Logging Writing Failed {e}")
        insert_log(logger, f"Logging Writing Failed {e}", log_filepath)

在上述修改中,我添加了一个移除处理器的步骤,确保每次只添加一个处理器并在使用后将其移除。这可以防止处理器的重复添加。

异常处理:

在异常处理部分,你可以更仔细地记录错误信息,以便更好地理解问题的根本原因。修改如下:

except Exception as e:
    print(f"Logging Writing Failed {e}")
    insert_log(logger, f"Logging Writing Failed {e}", log_filepath)

这段代码将错误信息以字符串的形式记录下来,并将其传递给insert_log函数,以便更好地诊断问题。你可以根据需要进一步处理错误信息,以便更好地理解问题的来源。

通过这些修改,你的代码应该更容易管理处理器的添加和移除,以及更好地记录错误信息。这将有助于避免递归深度错误以及其他潜在的问题。如果还有其他特定问题或需要进一步的修改,请提供更多信息,我将尽力提供更多帮助。

根本问题:log的数量超过了设定值,处理机制不够科学

解决办法就是当log数量达到限制,则新建一个log。

def get_log_path(SERVER_ADDR, SERVER_PORT):
    file_path = os.path.abspath(__file__)
    file_name = os.path.basename(file_path).split(".")[0]
    return os.path.join(base_path, f'logs_{file_name}_{SERVER_ADDR}_{SERVER_PORT}')

def cleanup_logs():
    log_path = get_log_path(SERVER_ADDR,SERVER_PORT)
    current_time = time.time()
    for file_name in os.listdir(log_path):
        # 获取文件名中的时间部分
        try:
            creation_str = file_name.split("_")[0] + "_" + file_name.split("_")[1] + "_" + file_name.split("_")[2]
            creation_time = time.mktime(time.strptime(creation_str, "%Y-%m-%d_%H-%M_%S"))

        except (ValueError, IndexError):
            # 文件名格式不正确,跳过
            continue

        # 如果文件创建时间早于 180 天前,就删除
        if current_time - creation_time > (30 * 24 * 60 * 60):
            file_path = os.path.join(log_path, file_name)
            os.remove(file_path)

def configure_logging():
    log_path = get_log_path(SERVER_ADDR,SERVER_PORT)
    os.makedirs(log_path, exist_ok=True)
    log_filename = get_log_filename()
    log_file = os.path.join(log_path, log_filename)
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', filename=log_file)

def get_log_filename():
    now = datetime.datetime.now()
    return now.strftime("%Y-%m-%d_%H-%M.log")

def create_new_log():
    log_path = get_log_path(SERVER_ADDR,SERVER_PORT)
    log_files = os.listdir(log_path)
    if len(log_files) >= 300:
        oldest_file = min(log_files)
        os.remove(os.path.join(log_path, oldest_file))
    log_filename = get_log_filename()
    log_filepath = os.path.join(log_path, log_filename)
    return log_filepath

def check_log_size(log_filepath):
    log_size = os.path.getsize(log_filepath)
    print("======================================================================")
    print("log_size:", log_size)
    if log_size > 2*1024*1024:
        # 创建新的日志文件
        new_log_filepath = create_new_log()
        return new_log_filepath
    return log_filepath
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值