Vasily.onl 2890ba2efa Implement Service Configuration Manager for data collection service
- Introduced `service_config.py` to manage configuration loading, validation, and schema management, enhancing modularity and security.
- Created a `ServiceConfig` class for handling configuration with robust error handling and default values.
- Refactored `DataCollectionService` to utilize the new `ServiceConfig`, streamlining configuration management and improving readability.
- Added a `CollectorFactory` to encapsulate collector creation logic, promoting separation of concerns.
- Updated `CollectorManager` and related components to align with the new architecture, ensuring better maintainability.
- Enhanced logging practices across the service for improved monitoring and debugging.

These changes significantly improve the architecture and maintainability of the data collection service, aligning with project standards for modularity and performance.
2025-06-10 12:55:27 +08:00

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()
}