Developer Guide - PANTHER Core Utilities¤
Development Environment Setup¤
Prerequisites¤
- Python 3.8+
- Access to PANTHER repository
- Optional:
colorlogfor colored logging output - Optional:
psutilfor performance monitoring
Local Development Setup¤
-
Clone and Navigate:
cd panther/core/utils -
Install Dependencies:
pip install colorlog # Optional for colors pip install psutil # Optional for performance monitoring -
Verify Installation:
from panther.core.utils import LoggerFactory, FeatureLoggerMixin print("Core utilities loaded successfully")
Running and Testing¤
Manual Testing¤
Basic Logger Testing¤
from panther.core.utils import LoggerFactory
# Initialize factory
LoggerFactory.initialize({
"level": "DEBUG",
"enable_colors": True,
"format": "%(asctime)s [%(levelname)s] - %(module)s - %(message)s"
})
# Test basic logging
logger = LoggerFactory.get_logger("test_component")
logger.info("Test message")
logger.debug("Debug message")
Feature Detection Testing¤
from panther.core.utils import FeatureLoggerMixin
class TestComponent(FeatureLoggerMixin):
def __init__(self):
self.__init_logger__()
def test_logging(self):
self.info(f"Feature detected: {self.get_effective_feature()}")
self.debug("Testing debug output")
# Test the component
component = TestComponent()
component.test_logging()
Statistics Testing¤
from panther.core.utils import LoggerFactory
# Enable statistics
LoggerFactory.enable_statistics({
"enabled": True,
"track_performance": True,
"buffer_size": 100
})
# Generate some log messages
logger = LoggerFactory.get_logger("stats_test")
for i in range(10):
logger.info(f"Test message {i}")
# Check statistics
stats = LoggerFactory.get_log_statistics()
print(f"Messages logged: {stats.get('total_messages', 0)}")
Debugging¤
Enable Debug Logging¤
LoggerFactory.initialize({
"level": "DEBUG",
"debug_file_logging": True,
"output_file": "debug.log"
})
Feature Detection Debugging¤
from panther.core.utils import LoggerFactory
# Test feature detection for your component
component_name = "your_component_name"
detected = LoggerFactory._detect_feature_from_name(component_name)
print(f"Component '{component_name}' detected as feature: {detected}")
# Check available features
print("Available feature mappings:")
for feature, patterns in LoggerFactory.FEATURE_MAPPINGS.items():
print(f" {feature}: {patterns}")
Configuration Verification¤
# Check current configuration
config = LoggerFactory._config
print(f"Current config: {config}")
# Check feature levels
levels = LoggerFactory._feature_levels
print(f"Feature levels: {levels}")
# Check if statistics are enabled
enabled = LoggerFactory.is_statistics_enabled()
print(f"Statistics enabled: {enabled}")
Extending the Utilities¤
Adding New Features¤
-
Register Feature Patterns:
from panther.core.utils import feature_registry # Add new feature with detection patterns feature_registry.register_feature("my_new_feature", [ "pattern1", "pattern2", "keyword" ]) -
Update Factory Mappings (for static mappings):
# Add to LoggerFactory.FEATURE_MAPPINGS in logger_factory.py "my_new_feature": ["component_name", "module_pattern"]
Custom Mixins¤
from panther.core.utils import FeatureLoggerMixin
class CustomMixin(FeatureLoggerMixin):
def __init__(self, custom_feature=None):
# Initialize with specific feature
self.__init_logger__(feature=custom_feature)
def log_operation(self, operation_name, **context):
"""Log operation with context."""
self.info(f"Operation: {operation_name}", extra=context)
def log_error_with_context(self, error, **context):
"""Enhanced error logging."""
self.error(f"Error: {error}", extra=context, exc_info=True)
Custom Statistics Collectors¤
from panther.core.utils.log_statistics_collector import LogStatisticsCollector
class CustomStatsCollector(LogStatisticsCollector):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.custom_metrics = {}
def collect_message(self, record):
"""Override to add custom metrics."""
super().collect_message(record)
# Add custom metric collection
feature = getattr(record, 'feature', 'unknown')
self.custom_metrics[feature] = self.custom_metrics.get(feature, 0) + 1
def get_custom_stats(self):
"""Get custom statistics."""
return self.custom_metrics.copy()
Code Quality Standards¤
Docstring Requirements¤
All public methods must have Google-style docstrings:
def example_function(param1: str, param2: Optional[int] = None) -> bool:
"""Brief one-line description under 72 characters.
Longer description explaining the function's purpose, behavior,
and any important implementation details.
Args:
param1: Description of first parameter
param2: Description of optional parameter with default
Returns:
Description of return value
Raises:
ValueError: When param1 is empty
RuntimeError: When system is not initialized
Examples:
>>> result = example_function("test", 42)
>>> assert result is True
"""
if not param1:
raise ValueError("param1 cannot be empty")
return True
Testing Requirements¤
- All new functionality must include doctest examples
- Critical paths must have manual testing procedures
- Performance-sensitive code should include timing tests
Code Style¤
- Use type hints for all parameters and return values
- Follow PEP 8 naming conventions
- Maximum line length: 88 characters
- Use f-strings for string formatting
Performance Guidelines¤
Optimization Practices¤
- Lazy Initialization: Initialize expensive resources only when needed
- Caching: Cache frequently accessed data (feature detection results, formatters)
- Efficient Data Structures: Use appropriate collections for different access patterns
- Resource Cleanup: Properly close handlers and clean up resources
Performance Testing¤
import time
from panther.core.utils import LoggerFactory
# Test logger creation performance
start_time = time.time()
for i in range(1000):
logger = LoggerFactory.get_logger(f"test_logger_{i}")
creation_time = time.time() - start_time
print(f"Created 1000 loggers in {creation_time:.3f}s")
# Test logging performance
logger = LoggerFactory.get_logger("perf_test")
start_time = time.time()
for i in range(10000):
logger.info(f"Test message {i}")
logging_time = time.time() - start_time
print(f"Logged 10000 messages in {logging_time:.3f}s")
Troubleshooting Common Issues¤
Logger Not Getting Feature-Specific Level¤
Problem: Logger is not using the expected feature-specific level.
Solution:
# Check feature detection
logger_name = "your_logger_name"
detected_feature = LoggerFactory._detect_feature_from_name(logger_name)
print(f"Detected feature: {detected_feature}")
# Check if feature has configured level
levels = LoggerFactory._feature_levels
print(f"Feature levels: {levels}")
# Manually set feature level
LoggerFactory.update_feature_level("your_feature", "DEBUG")
Statistics Not Working¤
Problem: Statistics collection is not capturing data.
Solution:
# Check if statistics are enabled
enabled = LoggerFactory.is_statistics_enabled()
print(f"Statistics enabled: {enabled}")
# Enable statistics if needed
if not enabled:
LoggerFactory.enable_statistics({
"enabled": True,
"track_performance": True
})
# Verify handler is attached
handler_stats = LoggerFactory.get_statistics_handler_stats()
print(f"Handler stats: {handler_stats}")
Memory Usage Growing¤
Problem: Memory usage increases over time.
Solution:
# Check statistics buffer size
collector = getattr(LoggerFactory, '_statistics_collector', None)
if collector:
print(f"Buffer size: {collector.buffer_size}")
print(f"Current buffer length: {len(collector.message_buffer)}")
# Reset statistics if needed
LoggerFactory.reset_statistics()
# Consider disabling statistics for production
LoggerFactory.disable_statistics()
Contributing Guidelines¤
Pull Request Process¤
- Feature Branch: Create feature branch from main
- Implementation: Add functionality with tests and documentation
- Testing: Verify all manual testing procedures pass
- Documentation: Update relevant documentation files
- Review: Submit PR for code review
Testing Checklist¤
- All doctest examples pass
- Manual testing procedures verified
- Performance impact assessed
- Memory usage tested for leaks
- Thread safety verified for concurrent usage
- Error handling tested with invalid inputs
Documentation Updates¤
When adding new features:
- Update API reference documentation
- Add usage examples to README
- Update this developer guide with new procedures
- Add troubleshooting section if applicable
- Update architecture diagrams if structure changes
IDE Integration¤
VSCode Settings¤
Recommended settings for development:
{
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"python.linting.mypyEnabled": true,
"files.trimTrailingWhitespace": true
}
Debugging Configuration¤
VSCode launch configuration for debugging:
{
"name": "Debug Core Utils",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/debug_runner.py",
"console": "integratedTerminal",
"env": {
"PYTHONPATH": "${workspaceFolder}"
}
}
Create debug_runner.py for testing:
#!/usr/bin/env python3
from panther.core.utils import LoggerFactory, FeatureLoggerMixin
# Your debugging code here
LoggerFactory.initialize({"level": "DEBUG", "enable_colors": True})
logger = LoggerFactory.get_logger(__name__)
logger.info("Debug session started")