Skip to content

Development Setup

This guide covers setting up a development environment for Gunicorn Prometheus Exporter.

Prerequisites

  • Python 3.8 or higher
  • Git
  • pip
  • tox (for testing)

Setup

Clone the Repository

git clone https://github.com/Agent-Hellboy/gunicorn-prometheus-exporter.git
cd gunicorn-prometheus-exporter

Install Development Dependencies

# Install in development mode with all dependencies
pip install -e ".[dev]"

# Or install specific extras
pip install -e ".[async,redis,dev]"

Development Dependencies

The [dev] extra includes:

  • pytest - Testing framework
  • pytest-cov - Coverage reporting
  • ruff - Linting and formatting
  • mypy - Type checking
  • tox - Testing across Python versions

Running Tests

Using pytest

# Run all tests
pytest

# Run with coverage
pytest --cov=src/gunicorn_prometheus_exporter --cov-report=html

# Run specific test file
pytest tests/test_plugin.py

# Run tests with verbose output
pytest -v

# Run tests in parallel
pytest -n auto

Using tox

# Run all test environments
tox

# Run specific environment
tox -e py311

# Run linting only
tox -e lint

# Run formatting only
tox -e format

Code Quality

Linting

# Check code with ruff
ruff check src/ tests/

# Fix auto-fixable issues
ruff check --fix src/ tests/

Formatting

# Format code with ruff
ruff format src/ tests/

# Check formatting without changes
ruff format --check src/ tests/

Type Checking

# Run mypy type checking
mypy src/gunicorn_prometheus_exporter/

Project Structure

gunicorn-prometheus-exporter/
├── src/
│   └── gunicorn_prometheus_exporter/
│       ├── __init__.py
│       ├── backend/           # Redis backend implementation
│       ├── config.py          # Configuration management
│       ├── hooks.py           # Gunicorn hooks
│       ├── logging.py         # Logging utilities
│       ├── master.py          # Master process monitoring
│       ├── metrics.py         # Metrics collection
│       ├── plugin.py          # Gunicorn plugin
│       └── utils.py           # Utility functions
├── tests/                     # Test files
├── docs/                      # Documentation
├── example/                   # Example applications
├── system-test/               # System integration tests
├── pyproject.toml            # Project configuration
├── tox.ini                   # Tox configuration
└── README.md

Adding New Features

1. Create a Feature Branch

git checkout -b feature/new-feature

2. Implement the Feature

  • Add your code to the appropriate module
  • Follow existing code patterns and style
  • Add type hints where appropriate
  • Include docstrings for public functions

3. Add Tests

  • Create test files in the tests/ directory
  • Test both success and failure cases
  • Aim for high test coverage

4. Update Documentation

  • Update relevant documentation files
  • Add examples if applicable
  • Update the changelog

5. Run Quality Checks

# Run all quality checks
tox

# Or run individually
ruff check src/ tests/
ruff format src/ tests/
mypy src/gunicorn_prometheus_exporter/
pytest

Testing Guidelines

Unit Tests

  • Test individual functions and methods
  • Mock external dependencies
  • Use descriptive test names
  • Follow AAA pattern (Arrange, Act, Assert)

Integration Tests

  • Test component interactions
  • Use real dependencies where appropriate
  • Test error handling and edge cases

System Tests

  • Test complete workflows
  • Use the system-test/ directory
  • Test with different worker types
  • Verify metrics collection

Code Style

Python Style

  • Follow PEP 8
  • Use type hints
  • Write descriptive docstrings
  • Use meaningful variable names

Import Organization

# Standard library imports
import os
import sys

# Third-party imports
import prometheus_client
from gunicorn import util

# Local imports
from .config import Config
from .metrics import Metrics

Error Handling

try:
    # Risky operation
    result = risky_function()
except SpecificException as e:
    logger.error(f"Specific error occurred: {e}")
    raise
except Exception as e:
    logger.error(f"Unexpected error: {e}")
    raise

Debugging

Enable Debug Logging

# Set debug environment variables
export PROMETHEUS_DEBUG="true"
export GUNICORN_DEBUG="true"
export REDIS_DEBUG="true"

Using pdb

import pdb; pdb.set_trace()

Using logging

import logging

logger = logging.getLogger(__name__)
logger.debug("Debug message")
logger.info("Info message")
logger.warning("Warning message")
logger.error("Error message")

Performance Testing

Load Testing

# Install load testing tools
pip install locust

# Run load tests
locust -f load_test.py --host=http://localhost:8000

Memory Profiling

# Install memory profiler
pip install memory-profiler

# Profile memory usage
python -m memory_profiler your_script.py

Release Process

1. Update Version

# Update version in pyproject.toml
# Update CHANGELOG.md

2. Create Release

# Create and push tag
git tag v1.0.0
git push origin v1.0.0

3. Build and Publish

# Build package
python -m build

# Publish to PyPI
python -m twine upload dist/*

Contributing

Pull Request Process

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Run quality checks
  6. Submit a pull request

Pull Request Guidelines

  • Include a clear description
  • Reference related issues
  • Ensure all tests pass
  • Update documentation if needed
  • Keep changes focused and atomic

Common Issues

Import Errors

# Ensure package is installed in development mode
pip install -e .

Test Failures

# Check test environment
pytest --collect-only

# Run tests with verbose output
pytest -v -s

Linting Errors

# Check specific file
ruff check src/gunicorn_prometheus_exporter/plugin.py

# Fix auto-fixable issues
ruff check --fix src/gunicorn_prometheus_exporter/plugin.py

Resources