136 lines
4.9 KiB
Python
136 lines
4.9 KiB
Python
|
|
"""
|
||
|
|
Manager Logger for centralized logging operations.
|
||
|
|
|
||
|
|
This module provides a centralized logging interface for the collector management system
|
||
|
|
with configurable log levels and error sanitization.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from typing import Optional, Any
|
||
|
|
|
||
|
|
|
||
|
|
class ManagerLogger:
|
||
|
|
"""Centralized logger wrapper for collector management operations."""
|
||
|
|
|
||
|
|
def __init__(self, logger=None, log_errors_only: bool = False):
|
||
|
|
"""
|
||
|
|
Initialize the manager logger.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
logger: Logger instance. If None, no logging will be performed.
|
||
|
|
log_errors_only: If True and logger is provided, only log error-level messages
|
||
|
|
"""
|
||
|
|
self.logger = logger
|
||
|
|
self.log_errors_only = log_errors_only
|
||
|
|
|
||
|
|
def _sanitize_error(self, message: str) -> str:
|
||
|
|
"""
|
||
|
|
Sanitize error message to prevent leaking internal details.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
message: Original error message
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Sanitized error message
|
||
|
|
"""
|
||
|
|
# Remove sensitive patterns that might leak internal information
|
||
|
|
sensitive_patterns = [
|
||
|
|
'password=',
|
||
|
|
'token=',
|
||
|
|
'key=',
|
||
|
|
'secret=',
|
||
|
|
'auth=',
|
||
|
|
'api_key=',
|
||
|
|
'api_secret=',
|
||
|
|
'access_token=',
|
||
|
|
'refresh_token='
|
||
|
|
]
|
||
|
|
|
||
|
|
sanitized = message
|
||
|
|
for pattern in sensitive_patterns:
|
||
|
|
if pattern.lower() in sanitized.lower():
|
||
|
|
# Replace the value part after = with [REDACTED]
|
||
|
|
parts = sanitized.split(pattern)
|
||
|
|
if len(parts) > 1:
|
||
|
|
# Find the end of the value (space, comma, or end of string)
|
||
|
|
value_part = parts[1]
|
||
|
|
end_chars = [' ', ',', ')', ']', '}', '\n', '\t']
|
||
|
|
end_idx = len(value_part)
|
||
|
|
|
||
|
|
for char in end_chars:
|
||
|
|
char_idx = value_part.find(char)
|
||
|
|
if char_idx != -1 and char_idx < end_idx:
|
||
|
|
end_idx = char_idx
|
||
|
|
|
||
|
|
# Replace the value with [REDACTED]
|
||
|
|
sanitized = parts[0] + pattern + '[REDACTED]' + value_part[end_idx:]
|
||
|
|
|
||
|
|
return sanitized
|
||
|
|
|
||
|
|
def log_debug(self, message: str) -> None:
|
||
|
|
"""Log debug message if logger is available and not in errors-only mode."""
|
||
|
|
if self.logger and not self.log_errors_only:
|
||
|
|
self.logger.debug(message)
|
||
|
|
|
||
|
|
def log_info(self, message: str) -> None:
|
||
|
|
"""Log info message if logger is available and not in errors-only mode."""
|
||
|
|
if self.logger and not self.log_errors_only:
|
||
|
|
self.logger.info(message)
|
||
|
|
|
||
|
|
def log_warning(self, message: str) -> None:
|
||
|
|
"""Log warning message if logger is available and not in errors-only mode."""
|
||
|
|
if self.logger and not self.log_errors_only:
|
||
|
|
self.logger.warning(message)
|
||
|
|
|
||
|
|
def log_error(self, message: str, exc_info: bool = False) -> None:
|
||
|
|
"""
|
||
|
|
Log error message if logger is available (always logs errors regardless of log_errors_only).
|
||
|
|
|
||
|
|
Args:
|
||
|
|
message: Error message to log
|
||
|
|
exc_info: Whether to include exception info
|
||
|
|
"""
|
||
|
|
if self.logger:
|
||
|
|
sanitized_message = self._sanitize_error(message)
|
||
|
|
self.logger.error(sanitized_message, exc_info=exc_info)
|
||
|
|
|
||
|
|
def log_critical(self, message: str, exc_info: bool = False) -> None:
|
||
|
|
"""
|
||
|
|
Log critical message if logger is available (always logs critical regardless of log_errors_only).
|
||
|
|
|
||
|
|
Args:
|
||
|
|
message: Critical message to log
|
||
|
|
exc_info: Whether to include exception info
|
||
|
|
"""
|
||
|
|
if self.logger:
|
||
|
|
sanitized_message = self._sanitize_error(message)
|
||
|
|
self.logger.critical(sanitized_message, exc_info=exc_info)
|
||
|
|
|
||
|
|
def is_enabled(self) -> bool:
|
||
|
|
"""Check if logging is enabled."""
|
||
|
|
return self.logger is not None
|
||
|
|
|
||
|
|
def is_debug_enabled(self) -> bool:
|
||
|
|
"""Check if debug logging is enabled."""
|
||
|
|
return self.logger is not None and not self.log_errors_only
|
||
|
|
|
||
|
|
def set_logger(self, logger) -> None:
|
||
|
|
"""Set or update the logger instance."""
|
||
|
|
self.logger = logger
|
||
|
|
|
||
|
|
def set_errors_only(self, errors_only: bool) -> None:
|
||
|
|
"""Set or update the errors-only mode."""
|
||
|
|
self.log_errors_only = errors_only
|
||
|
|
|
||
|
|
def get_logger_info(self) -> dict:
|
||
|
|
"""
|
||
|
|
Get information about the logger configuration.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Dictionary with logger configuration details
|
||
|
|
"""
|
||
|
|
return {
|
||
|
|
'logger_available': self.logger is not None,
|
||
|
|
'logger_name': getattr(self.logger, 'name', None) if self.logger else None,
|
||
|
|
'log_errors_only': self.log_errors_only,
|
||
|
|
'debug_enabled': self.is_debug_enabled()
|
||
|
|
}
|