log to file
This commit is contained in:
parent
23d5e267f4
commit
f89d40527d
|
|
@ -55,6 +55,15 @@ def launch_webui(host: str, port: int):
|
|||
def parse_arguments(args=None):
|
||||
ANTHROPIC_DEFAULT_MODEL = "claude-3-7-sonnet-20250219"
|
||||
OPENAI_DEFAULT_MODEL = "gpt-4o"
|
||||
|
||||
# Case-insensitive log level argument type
|
||||
def log_level_type(value):
|
||||
value = value.lower()
|
||||
if value not in ["debug", "info", "warning", "error", "critical"]:
|
||||
raise argparse.ArgumentTypeError(
|
||||
f"Invalid log level: {value}. Choose from debug, info, warning, error, critical."
|
||||
)
|
||||
return value
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="RA.Aid - AI Agent for executing programming and research tasks",
|
||||
|
|
@ -148,6 +157,12 @@ Examples:
|
|||
parser.add_argument(
|
||||
"--pretty-logger", action="store_true", help="Enable pretty logging output"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--log-level",
|
||||
type=log_level_type,
|
||||
default="warning",
|
||||
help="Set specific logging level (case-insensitive, overrides --verbose)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--temperature",
|
||||
type=float,
|
||||
|
|
@ -333,7 +348,7 @@ def build_status(
|
|||
def main():
|
||||
"""Main entry point for the ra-aid command line tool."""
|
||||
args = parse_arguments()
|
||||
setup_logging(args.verbose, args.pretty_logger)
|
||||
setup_logging(args.verbose, args.pretty_logger, args.log_level)
|
||||
logger.debug("Starting RA.Aid with arguments: %s", args)
|
||||
|
||||
# Launch web interface if requested
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import logging
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
|
||||
from rich.console import Console
|
||||
from rich.markdown import Markdown
|
||||
from rich.panel import Panel
|
||||
|
|
@ -36,21 +41,89 @@ class PrettyHandler(logging.Handler):
|
|||
self.handleError(record)
|
||||
|
||||
|
||||
def setup_logging(verbose: bool = False, pretty: bool = False) -> None:
|
||||
def setup_logging(verbose: bool = False, pretty: bool = False, log_level: Optional[str] = None) -> None:
|
||||
"""
|
||||
Configure logging for ra_aid.
|
||||
|
||||
Args:
|
||||
verbose: Set to True to enable verbose logging (implies DEBUG level if log_level not specified)
|
||||
pretty: Set to True to enable pretty console logging
|
||||
log_level: Optional explicit log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
||||
Takes precedence over verbose flag if specified
|
||||
"""
|
||||
# Create .ra-aid/logs directory if it doesn't exist
|
||||
cwd = os.getcwd()
|
||||
ra_aid_dir_str = os.path.join(cwd, ".ra-aid")
|
||||
logs_dir_str = os.path.join(ra_aid_dir_str, "logs")
|
||||
|
||||
# Create directory structure
|
||||
for directory in [ra_aid_dir_str, logs_dir_str]:
|
||||
path = Path(directory)
|
||||
if not path.exists():
|
||||
try:
|
||||
path.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to create log directory {directory}: {str(e)}")
|
||||
|
||||
# Determine log level
|
||||
if log_level is not None:
|
||||
# Use provided log level if specified (case-insensitive)
|
||||
numeric_level = getattr(logging, log_level.upper(), None)
|
||||
if not isinstance(numeric_level, int):
|
||||
# If invalid log level is provided, fall back to default
|
||||
print(f"Invalid log level: {log_level}")
|
||||
numeric_level = logging.DEBUG if verbose else logging.WARNING
|
||||
else:
|
||||
# Use verbose flag to determine log level
|
||||
numeric_level = logging.DEBUG if verbose else logging.WARNING
|
||||
|
||||
# Configure root logger
|
||||
logger = logging.getLogger("ra_aid")
|
||||
logger.setLevel(logging.DEBUG if verbose else logging.WARNING)
|
||||
|
||||
if not logger.handlers:
|
||||
if pretty:
|
||||
handler = PrettyHandler()
|
||||
else:
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
formatter = logging.Formatter(
|
||||
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
handler.setFormatter(formatter)
|
||||
logger.addHandler(handler)
|
||||
logger.setLevel(numeric_level)
|
||||
|
||||
# Clear existing handlers to avoid duplicates
|
||||
if logger.handlers:
|
||||
logger.handlers.clear()
|
||||
|
||||
# Create console handler
|
||||
if pretty:
|
||||
console_handler = PrettyHandler()
|
||||
else:
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
formatter = logging.Formatter(
|
||||
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
console_handler.setFormatter(formatter)
|
||||
|
||||
# Add console handler to logger
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# Create file handler with rotation
|
||||
try:
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
log_filename = os.path.join(logs_dir_str, f"ra_aid_{timestamp}.log")
|
||||
|
||||
# RotatingFileHandler with 5MB max size and 100 backup files
|
||||
file_handler = RotatingFileHandler(
|
||||
log_filename,
|
||||
maxBytes=5 * 1024 * 1024, # 5MB
|
||||
backupCount=100,
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
file_formatter = logging.Formatter(
|
||||
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
file_handler.setFormatter(file_formatter)
|
||||
file_handler.setLevel(numeric_level)
|
||||
|
||||
# Add file handler to logger
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
logger.info(f"Log file created: {log_filename}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to set up file logging: {str(e)}")
|
||||
|
||||
|
||||
def get_logger(name: Optional[str] = None) -> logging.Logger:
|
||||
return logging.getLogger(f"ra_aid.{name}" if name else "ra_aid")
|
||||
return logging.getLogger(f"ra_aid.{name}" if name else "ra_aid")
|
||||
Loading…
Reference in New Issue