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):
|
def parse_arguments(args=None):
|
||||||
ANTHROPIC_DEFAULT_MODEL = "claude-3-7-sonnet-20250219"
|
ANTHROPIC_DEFAULT_MODEL = "claude-3-7-sonnet-20250219"
|
||||||
OPENAI_DEFAULT_MODEL = "gpt-4o"
|
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(
|
parser = argparse.ArgumentParser(
|
||||||
description="RA.Aid - AI Agent for executing programming and research tasks",
|
description="RA.Aid - AI Agent for executing programming and research tasks",
|
||||||
|
|
@ -148,6 +157,12 @@ Examples:
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--pretty-logger", action="store_true", help="Enable pretty logging output"
|
"--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(
|
parser.add_argument(
|
||||||
"--temperature",
|
"--temperature",
|
||||||
type=float,
|
type=float,
|
||||||
|
|
@ -333,7 +348,7 @@ def build_status(
|
||||||
def main():
|
def main():
|
||||||
"""Main entry point for the ra-aid command line tool."""
|
"""Main entry point for the ra-aid command line tool."""
|
||||||
args = parse_arguments()
|
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)
|
logger.debug("Starting RA.Aid with arguments: %s", args)
|
||||||
|
|
||||||
# Launch web interface if requested
|
# Launch web interface if requested
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.markdown import Markdown
|
from rich.markdown import Markdown
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
|
|
@ -36,21 +41,89 @@ class PrettyHandler(logging.Handler):
|
||||||
self.handleError(record)
|
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 = logging.getLogger("ra_aid")
|
||||||
logger.setLevel(logging.DEBUG if verbose else logging.WARNING)
|
logger.setLevel(numeric_level)
|
||||||
|
|
||||||
if not logger.handlers:
|
# Clear existing handlers to avoid duplicates
|
||||||
if pretty:
|
if logger.handlers:
|
||||||
handler = PrettyHandler()
|
logger.handlers.clear()
|
||||||
else:
|
|
||||||
handler = logging.StreamHandler(sys.stdout)
|
# Create console handler
|
||||||
formatter = logging.Formatter(
|
if pretty:
|
||||||
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
console_handler = PrettyHandler()
|
||||||
)
|
else:
|
||||||
handler.setFormatter(formatter)
|
console_handler = logging.StreamHandler(sys.stdout)
|
||||||
logger.addHandler(handler)
|
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:
|
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