feat(core): add file logging capability to application

- Added log_to_file parameter to Application class constructor
- Integrated log_to_file option in logger initialization
- Updated ServiceContext to support file logging configuration
- Modified init_logger function to conditionally enable file logging
- Added log_to_file field to ServiceConfig schema
- Updated ReMe class to include file logging option
- Wrapped file logging setup in conditional check to prevent unnecessary operations
This commit is contained in:
方应 2026-04-09 17:53:00 +08:00
parent 99f84d9f7f
commit 84fa398e99
5 changed files with 39 additions and 22 deletions

View file

@ -44,6 +44,7 @@ class Application:
config_path: str | None = None,
enable_logo: bool = True,
log_to_console: bool = True,
log_to_file: bool = True,
enable_load_env: bool = True,
parser: type[PydanticConfigParser] | None = None,
default_as_llm_config: dict | None = None,
@ -73,6 +74,7 @@ class Application:
config_path=config_path,
enable_logo=enable_logo,
log_to_console=log_to_console,
log_to_file=log_to_file,
default_as_llm_config=default_as_llm_config,
default_as_llm_formatter_config=default_as_llm_formatter_config,
default_llm_config=default_llm_config,
@ -144,7 +146,10 @@ class Application:
logger.warning("Application has already started.")
return self
init_logger(log_to_console=self.service_config.log_to_console)
init_logger(
log_to_console=self.service_config.log_to_console,
log_to_file=self.service_config.log_to_file,
)
logger.info(f"Init ReMe with config: {self.service_config.model_dump_json()}")
working_path = Path(self.service_config.working_dir)

View file

@ -122,6 +122,7 @@ class ServiceConfig(BasicConfig):
)
ray_max_workers: int = Field(default=-1)
log_to_console: bool = Field(default=True)
log_to_file: bool = Field(default=True)
disabled_flows: list[str] = Field(default_factory=list)
enabled_flows: list[str] = Field(default_factory=list)

View file

@ -34,6 +34,7 @@ class ServiceContext(BaseDict):
config_path: str | None = None,
enable_logo: bool = True,
log_to_console: bool = True,
log_to_file: bool = True,
default_as_llm_config: dict | None = None,
default_as_llm_formatter_config: dict | None = None,
default_as_token_counter_config: dict | None = None,
@ -79,6 +80,7 @@ class ServiceContext(BaseDict):
{
"enable_logo": enable_logo,
"log_to_console": log_to_console,
"log_to_file": log_to_file,
"working_dir": working_dir,
},
)

View file

@ -5,13 +5,19 @@ import sys
from datetime import datetime
def init_logger(log_dir: str = "logs", level: str = "INFO", log_to_console: bool = True) -> None:
def init_logger(
log_dir: str = "logs",
level: str = "INFO",
log_to_console: bool = True,
log_to_file: bool = True,
) -> None:
"""Initialize the logger with both file and console handlers.
Args:
log_dir: Directory path for log files
level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
log_to_console: Whether to print logs to console/screen
log_to_file: Whether to persist logs to files under log_dir
"""
from loguru import logger
@ -28,25 +34,26 @@ def init_logger(log_dir: str = "logs", level: str = "INFO", log_to_console: bool
)
# Try to configure file-based logging (skip if permission denied)
try:
# Ensure the logging directory exists
os.makedirs(log_dir, exist_ok=True)
if log_to_file:
try:
# Ensure the logging directory exists
os.makedirs(log_dir, exist_ok=True)
# Generate filename based on the current timestamp
# Use dashes instead of colons for Windows compatibility
current_ts = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
log_filename = f"{current_ts}.log"
log_filepath = os.path.join(log_dir, log_filename)
# Generate filename based on the current timestamp
# Use dashes instead of colons for Windows compatibility
current_ts = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
log_filename = f"{current_ts}.log"
log_filepath = os.path.join(log_dir, log_filename)
# Configure file-based logging with rotation and compression
logger.add(
log_filepath,
level=level,
rotation="00:00",
retention="7 days",
compression="zip",
encoding="utf-8",
format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {file}:{line} | {function} | {message}",
)
except Exception as e:
logger.error(f"Error configuring file logging: {e}")
# Configure file-based logging with rotation and compression
logger.add(
log_filepath,
level=level,
rotation="00:00",
retention="7 days",
compression="zip",
encoding="utf-8",
format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {file}:{line} | {function} | {message}",
)
except Exception as e:
logger.error(f"Error configuring file logging: {e}")

View file

@ -46,6 +46,7 @@ class ReMe(Application):
config_path: str = "vector",
enable_logo: bool = True,
log_to_console: bool = True,
log_to_file: bool = True,
default_llm_config: dict | None = None,
default_embedding_model_config: dict | None = None,
default_vector_store_config: dict | None = None,
@ -81,6 +82,7 @@ class ReMe(Application):
config_path=config_path,
enable_logo=enable_logo,
log_to_console=log_to_console,
log_to_file=log_to_file,
parser=ReMeConfigParser,
default_llm_config=default_llm_config,
default_embedding_model_config=default_embedding_model_config,