Development Guide¶
Project Structure¶
logxide/
├── src/ # Rust source code
│ ├── lib.rs # Python bindings
│ ├── core.rs # Core logging types
│ ├── handler.rs # Log handlers
│ ├── formatter.rs # Format processing
│ └── ...
├── logxide/ # Python package
│ └── __init__.py # Python API
├── tests/ # Test suite
│ ├── test_basic_logging.py
│ ├── test_integration.py
│ └── README.md
├── examples/ # Usage examples
├── benchmark/ # Performance benchmarks
└── docs/ # Documentation
Development Setup¶
Prerequisites¶
- Rust: 1.70+ (install via rustup)
- Python: 3.12+
- maturin: For building Python extensions
Initial Setup¶
# Clone the repository
git clone https://github.com/Indosaram/logxide
cd logxide
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install development dependencies
pip install maturin pytest pytest-cov pytest-xdist
Building¶
Development Build¶
# Build and install in development mode
maturin develop
# Build with debug symbols
maturin develop --profile dev
# Build with optimizations
maturin develop --release
Release Build¶
# Build wheel for distribution
maturin build --release
# Build for specific Python version
maturin build --release --interpreter python3.12
Testing¶
Running Tests¶
# Run all tests
pytest tests/
# Run with coverage
pytest tests/ --cov=logxide --cov-report=term-missing
# Run specific test categories
pytest tests/ -m unit # Unit tests only
pytest tests/ -m integration # Integration tests only
pytest tests/ -m threading # Threading tests only
pytest tests/ -m "not slow" # Exclude slow tests
# Parallel execution for faster testing
pytest tests/ -n auto
Test Categories¶
- Unit Tests: Basic functionality, API compatibility
- Integration Tests: Real-world scenarios, drop-in replacement testing
- Threading Tests: Multi-threaded logging, thread safety
- Formatting Tests: Format specifiers, padding, date formatting
- Performance Tests: High-throughput scenarios, stress testing
Writing Tests¶
import pytest
from logxide import logging
def test_basic_logging():
"""Test basic logging functionality."""
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("test")
# Your test code here
logger.info("Test message")
# Ensure all messages are processed
logging.flush()
@pytest.mark.threading
def test_thread_safety():
"""Test thread safety."""
# Threading test code
pass
@pytest.mark.slow
def test_performance():
"""Performance test - marked as slow."""
# Performance test code
pass
Code Style and Linting¶
Rust Code¶
# Format code
cargo fmt
# Run clippy lints
cargo clippy --all-targets --all-features -- -D warnings
# Run tests
cargo test
Python Code¶
# Format with black
black tests/ examples/
# Sort imports
isort tests/ examples/
# Type checking with mypy
mypy tests/
# Lint with ruff
ruff check tests/ examples/
Debugging¶
Rust Debugging¶
# Build with debug symbols
maturin develop --profile dev
# Run with RUST_BACKTRACE for stack traces
RUST_BACKTRACE=1 python your_test.py
# Use logging for debugging
RUST_LOG=debug python your_test.py
Python Debugging¶
import logging
import logxide
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
# Use flush to ensure messages are processed
logxide.flush()
Performance Profiling¶
Benchmarking¶
# Run handler benchmarks
python benchmark/real_handlers_comparison.py
# Run memory benchmarks
python benchmark/compare_loggers.py
# Full library comparison
python benchmark/basic_handlers_benchmark.py
Memory Profiling¶
# Install memory profiler
pip install memory-profiler
# Profile memory usage
python -m memory_profiler your_script.py
CPU Profiling¶
# Install profiling tools
pip install py-spy
# Profile running application
py-spy record -o profile.svg -- python your_script.py
Contributing¶
Workflow¶
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Make your changes
- Add tests for new functionality
- Ensure all tests pass:
pytest tests/
- Format code:
cargo fmt && black .
- Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Pull Request Guidelines¶
- Clear description of changes and motivation
- Tests for new functionality
- Documentation updates if needed
- Backwards compatibility unless breaking change is necessary
- Performance impact analysis for performance-critical changes
Code Review Process¶
- Automated checks must pass (CI/CD)
- At least one maintainer review
- Address review feedback
- Maintainer approval and merge
Release Process¶
Version Management¶
LogXide uses semantic versioning (MAJOR.MINOR.PATCH):
- MAJOR: Breaking changes
- MINOR: New features, backwards compatible
- PATCH: Bug fixes, backwards compatible
Creating a Release¶
# Update version in Cargo.toml and pyproject.toml
# Update CHANGELOG.md
# Build and test
maturin build --release
pytest tests/
# Create git tag
git tag v0.2.0
git push origin v0.2.0
# Publish to PyPI
maturin publish
Documentation¶
Building Documentation¶
# Install documentation dependencies
pip install mkdocs mkdocs-material
# Serve documentation locally
mkdocs serve
# Build documentation
mkdocs build
Writing Documentation¶
- Use clear, concise language
- Include code examples for all features
- Add cross-references between related topics
- Update API reference for any API changes
Troubleshooting¶
Common Issues¶
Build Failures¶
Import Errors¶
# Ensure virtual environment is activated
source .venv/bin/activate
# Reinstall in development mode
maturin develop --force
Test Failures¶
# Run tests with verbose output
pytest tests/ -v
# Run specific failing test
pytest tests/test_specific.py::test_function -v
Getting Help¶
- GitHub Issues: Report bugs and request features
- Discussions: Ask questions and share ideas
- Documentation: Check existing documentation first
- Code Examples: Look at examples/ directory
Advanced Development¶
Custom Handlers¶
// In src/handler.rs
use crate::core::LogRecord;
use async_trait::async_trait;
#[async_trait]
pub trait Handler: Send + Sync {
async fn emit(&self, record: &LogRecord);
}
pub struct CustomHandler {
// Your handler implementation
}
#[async_trait]
impl Handler for CustomHandler {
async fn emit(&self, record: &LogRecord) {
// Your custom logic here
}
}
Performance Optimization¶
- Profile before optimizing: Use benchmarks to identify bottlenecks
- Measure impact: Verify optimizations actually improve performance
- Consider trade-offs: Balance performance vs. complexity
- Test thoroughly: Ensure optimizations don't break functionality
Adding New Features¶
- Design first: Consider API design and backwards compatibility
- Implement: Start with Rust core, then Python bindings
- Test extensively: Unit tests, integration tests, performance tests
- Document: Update documentation and examples
- Review: Get feedback before finalizing