feat: Enhance logging configuration to support dynamic log levels
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user