feat: Enhance logging configuration to support dynamic log levels

This commit is contained in:
Lorenzo Venerandi
2026-03-01 17:36:29 +01:00
parent 43d3b96364
commit fbc757f0a6
4 changed files with 43 additions and 7 deletions

View File

@@ -26,7 +26,7 @@ async def lifespan(app: FastAPI):
config = get_config() config = get_config()
# Initialize logging # Initialize logging
initialize_logging() initialize_logging(log_level=config.log_level)
app_logger = get_app_logger() app_logger = get_app_logger()
# Initialize database and run pending migrations before accepting traffic # Initialize database and run pending migrations before accepting traffic

View File

@@ -56,6 +56,8 @@ class Config:
user_agents_used_threshold: float = None user_agents_used_threshold: float = None
attack_urls_threshold: float = None attack_urls_threshold: float = None
log_level: str = "INFO"
_server_ip: Optional[str] = None _server_ip: Optional[str] = None
_server_ip_cache_time: float = 0 _server_ip_cache_time: float = 0
_ip_cache_ttl: int = 300 _ip_cache_ttl: int = 300
@@ -163,6 +165,7 @@ class Config:
behavior = data.get("behavior", {}) behavior = data.get("behavior", {})
analyzer = data.get("analyzer") or {} analyzer = data.get("analyzer") or {}
crawl = data.get("crawl", {}) crawl = data.get("crawl", {})
logging_cfg = data.get("logging", {})
# Handle dashboard_secret_path - auto-generate if null/not set # Handle dashboard_secret_path - auto-generate if null/not set
dashboard_path = dashboard.get("secret_path") dashboard_path = dashboard.get("secret_path")
@@ -217,6 +220,9 @@ class Config:
), ),
max_pages_limit=crawl.get("max_pages_limit", 250), max_pages_limit=crawl.get("max_pages_limit", 250),
ban_duration_seconds=crawl.get("ban_duration_seconds", 600), ban_duration_seconds=crawl.get("ban_duration_seconds", 600),
log_level=os.getenv(
"KRAWL_LOG_LEVEL", logging_cfg.get("level", "INFO")
).upper(),
) )

View File

@@ -848,6 +848,33 @@ class DatabaseManager:
session.rollback() session.rollback()
raise raise
def flag_all_ips_for_reevaluation(self) -> int:
"""
Flag ALL IPs for reevaluation, regardless of staleness.
Skips IPs that have a manual category set.
Returns:
Number of IPs flagged for reevaluation
"""
session = self.session
try:
count = (
session.query(IpStats)
.filter(
IpStats.need_reevaluation == False,
IpStats.manual_category == False,
)
.update(
{IpStats.need_reevaluation: True},
synchronize_session=False,
)
)
session.commit()
return count
except Exception as e:
session.rollback()
raise
def get_access_logs_paginated( def get_access_logs_paginated(
self, self,
page: int = 1, page: int = 1,

View File

@@ -36,12 +36,13 @@ class LoggerManager:
cls._instance._initialized = False cls._instance._initialized = False
return cls._instance return cls._instance
def initialize(self, log_dir: str = "logs") -> None: def initialize(self, log_dir: str = "logs", log_level: str = "INFO") -> None:
""" """
Initialize the logging system with rotating file handlers.loggers Initialize the logging system with rotating file handlers.loggers
Args: Args:
log_dir: Directory for log files (created if not exists) log_dir: Directory for log files (created if not exists)
log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
""" """
if self._initialized: if self._initialized:
return return
@@ -59,9 +60,11 @@ class LoggerManager:
max_bytes = 1048576 # 1MB max_bytes = 1048576 # 1MB
backup_count = 5 backup_count = 5
level = getattr(logging, log_level.upper(), logging.INFO)
# Setup application logger # Setup application logger
self._app_logger = logging.getLogger("krawl.app") self._app_logger = logging.getLogger("krawl.app")
self._app_logger.setLevel(logging.INFO) self._app_logger.setLevel(level)
self._app_logger.handlers.clear() self._app_logger.handlers.clear()
app_file_handler = RotatingFileHandler( app_file_handler = RotatingFileHandler(
@@ -78,7 +81,7 @@ class LoggerManager:
# Setup access logger # Setup access logger
self._access_logger = logging.getLogger("krawl.access") self._access_logger = logging.getLogger("krawl.access")
self._access_logger.setLevel(logging.INFO) self._access_logger.setLevel(level)
self._access_logger.handlers.clear() self._access_logger.handlers.clear()
access_file_handler = RotatingFileHandler( access_file_handler = RotatingFileHandler(
@@ -95,7 +98,7 @@ class LoggerManager:
# Setup credential logger (special format, no stream handler) # Setup credential logger (special format, no stream handler)
self._credential_logger = logging.getLogger("krawl.credentials") self._credential_logger = logging.getLogger("krawl.credentials")
self._credential_logger.setLevel(logging.INFO) self._credential_logger.setLevel(level)
self._credential_logger.handlers.clear() self._credential_logger.handlers.clear()
# Credential logger uses a simple format: timestamp|ip|username|password|path # Credential logger uses a simple format: timestamp|ip|username|password|path
@@ -152,6 +155,6 @@ def get_credential_logger() -> logging.Logger:
return _logger_manager.credentials return _logger_manager.credentials
def initialize_logging(log_dir: str = "logs") -> None: def initialize_logging(log_dir: str = "logs", log_level: str = "INFO") -> None:
"""Initialize the logging system.""" """Initialize the logging system."""
_logger_manager.initialize(log_dir) _logger_manager.initialize(log_dir, log_level)