diff --git a/code-server-like/app/__init__.py b/code-server-like/app/__init__.py index 4abdae6..46e3713 100644 --- a/code-server-like/app/__init__.py +++ b/code-server-like/app/__init__.py @@ -8,36 +8,41 @@ logging.getLogger('eventlet.greenio').setLevel(logging.CRITICAL) # 进行猴子补丁操作 eventlet.monkey_patch() -# 配置 eventlet hub 以更优雅地处理所有错误 +# 配置 eventlet 以更优雅地处理错误,避免疯狂报错 try: - from eventlet import hubs import eventlet import traceback - # 只修改存在的属性,避免引用错误 - if hasattr(hubs, 'trampoline'): - # 保存原始的trampoline方法 - original_trampoline = hubs.trampoline - - def custom_trampoline(fd, read=False, write=False, timeout=None, timeout_exc=None): - try: - return original_trampoline(fd, read, write, timeout, timeout_exc) - except Exception as e: - # 捕获 trampoline 方法中所有异常 - print(f"[Eventlet Trampoline Error] {type(e).__name__}: {e}") - print(f"[Params] fd: {fd}, read: {read}, write: {write}, timeout: {timeout}") - print("[Traceback]") - traceback.print_exc() - # 返回 None 继续运行,不往外传播错误 - return None - - # 替换原始方法 - hubs.trampoline = custom_trampoline + # 1. 首先,禁用 eventlet 的调试日志,减少输出 + import logging + logging.getLogger('eventlet').setLevel(logging.CRITICAL) + logging.getLogger('socketio').setLevel(logging.CRITICAL) + logging.getLogger('werkzeug').setLevel(logging.CRITICAL) - # 同样处理 greenio 模块的所有相关方法,捕获所有异常 + # 2. 配置 eventlet 只记录严重错误 + eventlet.debug.hub_prevent_multiple_readers(False) + + # 3. 避免重复打印相同错误的机制 + seen_errors = set() + max_error_logs = 5 # 每个错误最多打印5次 + error_counts = {} + + def is_duplicate_error(e): + """检查是否为重复错误""" + error_key = f"{type(e).__name__}: {e}" + if error_key in seen_errors: + error_counts[error_key] = error_counts.get(error_key, 0) + 1 + if error_counts[error_key] > max_error_logs: + return True + else: + seen_errors.add(error_key) + error_counts[error_key] = 1 + return False + + # 4. 只修改关键的 greenio 方法,确保在致命错误时彻底关闭连接 from eventlet import greenio - # 保存并替换原始的 greenio 方法(只修改存在的方法) + # 保存并替换原始的 greenio 方法 if hasattr(greenio.base.GreenSocket, '_recv_loop'): original_recv_loop = greenio.base.GreenSocket._recv_loop @@ -45,11 +50,15 @@ try: try: return original_recv_loop(self, recv_func, recv_args, *args, **kwargs) except Exception as e: - # 捕获所有 IO 操作异常 - print(f"[Eventlet IO Error] _recv_loop: {type(e).__name__}: {e}") - print("[Traceback]") - traceback.print_exc() - # 返回空字节串继续运行 + if not is_duplicate_error(e): + print(f"[Eventlet IO Error] _recv_loop: {type(e).__name__}: {e}") + print("[Traceback]") + traceback.print_exc() + # 彻底关闭连接,不再继续处理 + try: + self.close() + except Exception: + pass return b'' greenio.base.GreenSocket._recv_loop = custom_recv_loop @@ -61,11 +70,15 @@ try: try: return original_recv_into(self, buffer, nbytes, flags) except Exception as e: - # 捕获所有 IO 操作异常 - print(f"[Eventlet IO Error] recv_into: {type(e).__name__}: {e}") - print("[Traceback]") - traceback.print_exc() - # 返回 0 继续运行 + if not is_duplicate_error(e): + print(f"[Eventlet IO Error] recv_into: {type(e).__name__}: {e}") + print("[Traceback]") + traceback.print_exc() + # 彻底关闭连接,不再继续处理 + try: + self.close() + except Exception: + pass return 0 greenio.base.GreenSocket.recv_into = custom_recv_into @@ -77,11 +90,15 @@ try: try: return original_send_loop(self, send_func, data, *args, **kwargs) except Exception as e: - # 捕获所有 IO 操作异常 - print(f"[Eventlet IO Error] _send_loop: {type(e).__name__}: {e}") - print("[Traceback]") - traceback.print_exc() - # 返回 0 继续运行 + if not is_duplicate_error(e): + print(f"[Eventlet IO Error] _send_loop: {type(e).__name__}: {e}") + print("[Traceback]") + traceback.print_exc() + # 彻底关闭连接,不再继续处理 + try: + self.close() + except Exception: + pass return 0 greenio.base.GreenSocket._send_loop = custom_send_loop @@ -93,16 +110,20 @@ try: try: return original_send(self, data, flags) except Exception as e: - # 捕获所有 IO 操作异常 - print(f"[Eventlet IO Error] send: {type(e).__name__}: {e}") - print("[Traceback]") - traceback.print_exc() - # 返回 0 继续运行 + if not is_duplicate_error(e): + print(f"[Eventlet IO Error] send: {type(e).__name__}: {e}") + print("[Traceback]") + traceback.print_exc() + # 彻底关闭连接,不再继续处理 + try: + self.close() + except Exception: + pass return 0 greenio.base.GreenSocket.send = custom_send - # 处理 WSGI 中的所有错误 + # 5. 处理 WSGI 中的错误,确保彻底清理 try: import eventlet.wsgi @@ -113,12 +134,14 @@ try: try: return original_wsgi_handle_one_request(self) except Exception as e: - # 捕获 WSGI 请求处理中的所有异常 - print(f"[Eventlet WSGI Request Error] {type(e).__name__}: {e}") - print("[Traceback]") - traceback.print_exc() - # 清理连接状态并返回,不往外传播错误 + if not is_duplicate_error(e): + print(f"[Eventlet WSGI Request Error] {type(e).__name__}: {e}") + print("[Traceback]") + traceback.print_exc() + # 彻底清理连接,不再继续 try: + self.rfile.close() + self.wfile.close() self.finish() except Exception: pass @@ -133,12 +156,14 @@ try: try: return original_wsgi_handle_one_response(self) except Exception as e: - # 捕获 WSGI 响应处理中的所有异常 - print(f"[Eventlet WSGI Response Error] {type(e).__name__}: {e}") - print("[Traceback]") - traceback.print_exc() - # 清理连接状态并返回,不往外传播错误 + if not is_duplicate_error(e): + print(f"[Eventlet WSGI Response Error] {type(e).__name__}: {e}") + print("[Traceback]") + traceback.print_exc() + # 彻底清理连接,不再继续 try: + self.rfile.close() + self.wfile.close() self.finish() except Exception: pass @@ -149,7 +174,7 @@ try: # 如果修改失败,忽略错误 print(f"[WSGI Patch Error] {e}") - print("[Eventlet Error Handling] Eventlet errors will be caught and printed, not raised") + print("[Eventlet Error Handling] Configured to handle errors gracefully, avoiding duplicate logs") except Exception as e: # 如果修改失败,打印错误但继续运行 print(f"[Eventlet Patch Initialization Error] {e}")