From 7e9d8599f16d6ee32c6f421b29f8f4826a8f0ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=B0=B8=E8=B5=AB?= <1259085392@qq.com> Date: Tue, 10 Feb 2026 15:27:59 +0900 Subject: [PATCH] fix: capture runtime bootstrap logs after logger init - Add bootstrap record buffer in runtime_bootstrap for early TLS patch logs before logger is ready. - Flush buffered bootstrap logs to astrbot logger at process startup in main.py. - Include concrete exception details for TLS bootstrap failures to improve diagnosis. --- main.py | 4 +++- runtime_bootstrap.py | 51 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 9a84c4d6d..f9ca24eca 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,7 @@ import os import sys from pathlib import Path -import runtime_bootstrap # noqa: F401 +import runtime_bootstrap from astrbot.core import LogBroker, LogManager, db_helper, logger from astrbot.core.config.default import VERSION from astrbot.core.initial_loader import InitialLoader @@ -94,6 +94,8 @@ async def check_dashboard_files(webui_dir: str | None = None): if __name__ == "__main__": + runtime_bootstrap.flush_bootstrap_records(logger) + parser = argparse.ArgumentParser(description="AstrBot") parser.add_argument( "--webui-dir", diff --git a/runtime_bootstrap.py b/runtime_bootstrap.py index ce42e505b..0781147a9 100644 --- a/runtime_bootstrap.py +++ b/runtime_bootstrap.py @@ -1,17 +1,66 @@ import ssl +from collections.abc import Callable +from dataclasses import dataclass +from typing import Any import aiohttp.connector as aiohttp_connector import certifi +@dataclass +class BootstrapRecord: + level: str + message: str + + +_BOOTSTRAP_RECORDS: list[BootstrapRecord] = [] + + +def _record(level: str, message: str) -> None: + _BOOTSTRAP_RECORDS.append(BootstrapRecord(level=level, message=message)) + + +def flush_bootstrap_records(log_obj: Any) -> None: + if not _BOOTSTRAP_RECORDS: + return + + level_methods: dict[str, Callable[[str], Any]] = { + "info": getattr(log_obj, "info", None), + "warning": getattr(log_obj, "warning", None), + "error": getattr(log_obj, "error", None), + } + fallback = getattr(log_obj, "info", None) + + for record in _BOOTSTRAP_RECORDS: + logger_method = level_methods.get(record.level, fallback) + if callable(logger_method): + logger_method(record.message) + + _BOOTSTRAP_RECORDS.clear() + + def configure_runtime_ca_bundle() -> None: try: + _record("info", "Bootstrapping runtime CA bundle.") ssl_context = ssl.create_default_context() ssl_context.load_verify_locations(cafile=certifi.where()) if hasattr(aiohttp_connector, "_SSL_CONTEXT_VERIFIED"): aiohttp_connector._SSL_CONTEXT_VERIFIED = ssl_context - except Exception: + _record( + "info", + "Configured aiohttp verified SSL context with system+certifi trust chain.", + ) + else: + _record( + "warning", + "aiohttp connector does not expose _SSL_CONTEXT_VERIFIED; skipped patch.", + ) + except Exception as exc: + _record( + "error", + f"Failed to configure runtime CA bundle for aiohttp: {exc!r}", + ) return