Initialize stderr stream logger early

and make the fastmcp configuration function do nothing if log handlers already exist
This commit is contained in:
Dominik Jain authored and Dominik Jain committed 2025-07-20 18:39:20 +02:00
1 parent 318f7124a3
commit cbd2184fdd
2 files changed
+13 -10

No files matched your search

+8 -1
View File
@@ -16,6 +16,7 @@ from serena.config.serena_config import ProjectConfig, SerenaConfig
from serena.constants import (
DEFAULT_CONTEXT,
DEFAULT_MODES,
SERENA_LOG_FORMAT,
SERENA_MANAGED_DIR_IN_HOME,
SERENAS_OWN_CONTEXT_YAMLS_DIR,
SERENAS_OWN_MODE_YAMLS_DIR,
@@ -138,11 +139,17 @@ class TopLevelCommands(AutoRegisteringGroup):
tool_timeout: float | None,
) -> None:
# initialize logging, using INFO level initially (will later be adjusted by SerenaAgent according to the config)
# * memory log handler (for use by GUI/Dashboard)
# * stream handler for stderr (for direct console output, which will also be captured by clients like Claude Desktop)
# (Note that stdout must never be used for logging, as it is used by the MCP server to communicate with the client.)
Logger.root.setLevel(logging.INFO)
memory_log_handler = MemoryLogHandler()
Logger.root.addHandler(memory_log_handler)
stderr_handler = logging.StreamHandler(stream=sys.stderr)
stderr_handler.formatter = logging.Formatter(SERENA_LOG_FORMAT)
Logger.root.addHandler(stderr_handler)
log.info("Starting Serena MCP server")
log.info("Initializing Serena MCP server")
project_file = project_file_arg or project
factory = SerenaMCPFactorySingleProcess(context=context, project=project_file, memory_log_handler=memory_log_handler)
server = factory.create_mcp_server(
+5 -9
View File
@@ -7,7 +7,6 @@ from abc import abstractmethod
from collections.abc import AsyncIterator, Iterator, Sequence
from contextlib import asynccontextmanager
from dataclasses import dataclass
from logging import Formatter, Logger, StreamHandler
from typing import Any, Literal, cast
import docstring_parser
@@ -22,22 +21,19 @@ from serena.agent import (
SerenaConfig,
)
from serena.config.context_mode import SerenaAgentContext, SerenaAgentMode
from serena.constants import DEFAULT_CONTEXT, DEFAULT_MODES
from serena.constants import DEFAULT_CONTEXT, DEFAULT_MODES, SERENA_LOG_FORMAT
from serena.tools import Tool
from serena.util.exception import show_fatal_exception_safe
from serena.util.logging import MemoryLogHandler
log = logging.getLogger(__name__)
LOG_FORMAT = "%(levelname)-5s %(asctime)-15s %(name)s:%(funcName)s:%(lineno)d - %(message)s"
LOG_LEVEL = logging.INFO
def configure_logging(*args, **kwargs) -> None: # type: ignore
# configure logging to stderr (will be captured by Claude Desktop); stdio is the MCP communication stream and cannot be used!
Logger.root.setLevel(LOG_LEVEL)
handler = StreamHandler(stream=sys.stderr)
handler.formatter = Formatter(LOG_FORMAT)
Logger.root.addHandler(handler)
# We only do something here if logging has not yet been configured.
# Normally, logging is configured in the MCP server startup script.
if not logging.is_enabled():
logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=SERENA_LOG_FORMAT)
# patch the logging configuration function in fastmcp, because it's hard-coded and broken