Skip to main content

A Python decorator for comprehensive function monitoring with execution timing, memory usage tracking, CPU monitoring, input/output validation, and structured logging.

Project description

Function Monitor

A Python decorator for comprehensive function monitoring with execution timing, memory usage tracking, CPU monitoring, input/output validation, and structured logging.

Features

  • Execution Monitoring: Track function execution time, memory usage, and CPU utilization
  • Input/Output Validation: Automatic validation using Pydantic models and type hints
  • Structured Logging: Configurable structured logging with support for file output
  • Error Handling: Comprehensive exception handling and error reporting
  • Flexible Configuration: Global and per-function configuration options
  • Production Ready: Designed for production use with proper error handling and performance considerations

Installation

pip install function-monitor

Quick Start

from function_monitor import monitor_function

@monitor_function()
def add_numbers(a: int, b: int) -> int:
    return a + b

result = add_numbers(5, 3)
print(result)

This will output a dictionary containing the function result, execution metrics, and monitoring data:

{
    'result': 8,
    'status': 'success',
    'errors': None,
    'execution_time': 0.0001,
    'memory_usage': {
        'before': 15728640,
        'after': 15728640,
        'peak': 15728640,
        'delta': 0
    },
    'cpu_usage': 0.0,
    'timestamp': '2024-01-15T10:30:45.123456',
    'function_name': 'add_numbers'
}

Configuration

Global Configuration

Configure the monitor globally for your application:

from function_monitor import configure_monitor

configure_monitor(
    log_to_file=True,
    log_file_path="./app_monitor.log",
    log_level=20,  # INFO level
    default_return_raw_result=True
)

Environment Variables

You can also configure using environment variables:

export FUNCTION_MONITOR_LOG_LEVEL=10  # DEBUG level
export FUNCTION_MONITOR_LOG_TO_FILE=true
export FUNCTION_MONITOR_LOG_FILE=./debug.log

Per-Function Configuration

Override global settings for specific functions:

@monitor_function(
    validate_input=True,
    validate_output=False,
    log_level="DEBUG",
    return_raw_result=True
)
def my_function(x: int) -> str:
    return str(x * 2)

Advanced Usage

Input/Output Validation with Pydantic

from pydantic import BaseModel
from function_monitor import monitor_function

class User(BaseModel):
    name: str
    age: int
    email: str

class UserResponse(BaseModel):
    user: User
    message: str

@monitor_function(validate_input=True, validate_output=True)
def create_user(user_data: User) -> UserResponse:
    return UserResponse(
        user=user_data,
        message=f"User {user_data.name} created successfully"
    )

# Usage
user = User(name="John Doe", age=30, email="john@example.com")
result = create_user(user)

Custom Monitor Instances

from function_monitor import FunctionMonitor

# Create custom monitor with specific settings
production_monitor = FunctionMonitor(
    validate_input=True,
    validate_output=True,
    log_execution=True,
    return_raw_result=True
)

debug_monitor = FunctionMonitor(
    validate_input=True,
    validate_output=False,
    log_level="DEBUG",
    return_raw_result=False
)

@production_monitor
def critical_function(data: dict) -> dict:
    # Process critical data
    return {"processed": True}

@debug_monitor
def experimental_function(x: int) -> int:
    # Experimental code
    return x ** 2

Error Handling

The monitor automatically captures and reports errors:

@monitor_function()
def divide_numbers(a: float, b: float) -> float:
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

result = divide_numbers(10, 0)
print(result["status"])  # "error"
print(result["errors"])  # List of error messages

Memory and CPU Monitoring

Monitor resource usage:

@monitor_function(
    enable_memory_monitoring=True,
    enable_cpu_monitoring=True
)
def memory_intensive_function(size: int) -> list:
    # Create a large list
    return list(range(size))

result = memory_intensive_function(1000000)
print(result["memory_usage"])  # Memory usage statistics
print(result["cpu_usage"])     # CPU usage percentage

Configuration Options

Global Configuration Parameters

  • log_level: Logging level (default: INFO)
  • log_to_file: Enable file logging (default: False)
  • log_file_path: Path to log file (default: "./function_monitor.log")
  • log_file_max_size: Maximum log file size in bytes (default: 10MB)
  • log_file_backup_count: Number of backup log files (default: 5)
  • default_validate_input: Default input validation setting (default: True)
  • default_validate_output: Default output validation setting (default: True)
  • default_log_execution: Default execution logging setting (default: True)
  • default_return_raw_result: Default return format setting (default: False)
  • enable_memory_monitoring: Enable memory monitoring (default: True)
  • enable_cpu_monitoring: Enable CPU monitoring (default: True)

Decorator Parameters

  • validate_input: Enable input validation using type hints
  • validate_output: Enable output validation using type hints
  • log_execution: Enable structured logging
  • log_level: Log level for the function ("DEBUG", "INFO", "WARNING", "ERROR")
  • return_raw_result: Return original result on success, structured format on error
  • enable_memory_monitoring: Enable memory usage monitoring
  • enable_cpu_monitoring: Enable CPU usage monitoring

Logging

The monitor uses structured logging with configurable output formats:

Console Logging (Development)

configure_monitor(log_to_file=False)  # Logs to console with readable format

File Logging (Production)

configure_monitor(
    log_to_file=True,
    log_file_path="/var/log/myapp/monitor.log"
)  # Logs to file in JSON format

Custom Log Levels

@monitor_function(log_level="DEBUG")
def debug_function():
    pass

@monitor_function(log_level="ERROR")  # Only log errors
def critical_function():
    pass

Best Practices

  1. Production Usage: Use return_raw_result=True in production to avoid overhead
  2. Input Validation: Enable input validation for external-facing functions
  3. Log File Management: Configure log rotation to prevent disk space issues
  4. Selective Monitoring: Disable CPU/memory monitoring for high-frequency functions if needed
  5. Error Handling: Always handle the case where monitoring might return error status
# Production configuration example
configure_monitor(
    log_to_file=True,
    log_file_path="/var/log/myapp/function_monitor.log",
    log_level=20,  # INFO
    default_return_raw_result=True,
    default_validate_input=True,
    default_validate_output=False  # Disable output validation for performance
)

@monitor_function()
def api_endpoint(request_data: RequestModel) -> ResponseModel:
    # Your business logic here
    return process_request(request_data)

# Usage with error handling
result = api_endpoint(request)
if isinstance(result, dict) and result.get("status") == "error":
    # Handle error case
    logger.error("Function failed", errors=result["errors"])
    return error_response()
else:
    # Success case - result is the actual return value
    return result

Performance Considerations

  • Minimal Overhead: The monitor is designed to have minimal impact on function performance
  • Selective Monitoring: Disable features you don't need for better performance
  • Memory Monitoring: Uses psutil for accurate memory measurements
  • CPU Monitoring: Lightweight CPU usage tracking
  • Logging: Structured logging with configurable levels to reduce I/O overhead

Error Handling and Debugging

Common Issues

  1. Import Errors: Ensure all dependencies are installed
  2. Permission Issues: Check file permissions for log files
  3. Memory Monitoring: Requires psutil package
  4. Type Validation: Requires proper type hints for validation to work

Debug Mode

Enable debug mode for detailed logging:

from function_monitor import configure_monitor

configure_monitor(
    log_level=10,  # DEBUG level
    log_to_file=True,
    log_file_path="./debug.log"
)

API Reference

Decorators

monitor_function(**kwargs)

Main decorator for function monitoring.

Parameters:

  • validate_input (bool): Enable input validation
  • validate_output (bool): Enable output validation
  • log_execution (bool): Enable execution logging
  • log_level (str): Logging level
  • return_raw_result (bool): Return format preference
  • enable_memory_monitoring (bool): Enable memory tracking
  • enable_cpu_monitoring (bool): Enable CPU tracking

FunctionMonitor(**kwargs)

Class-based monitor for reusable configurations.

Configuration Functions

configure_monitor(**kwargs)

Configure global monitoring settings.

get_config() -> MonitorConfig

Get current global configuration.

set_config(config: MonitorConfig)

Set global configuration from MonitorConfig instance.

Models

ExecutionResult

  • result: Function return value
  • status: "success" or "error"
  • errors: List of error messages (if any)
  • execution_time: Execution time in seconds
  • memory_usage: Memory usage statistics
  • cpu_usage: CPU usage percentage
  • timestamp: ISO timestamp
  • function_name: Function name

MemoryUsage

  • before: Memory before execution (bytes)
  • after: Memory after execution (bytes)
  • peak: Peak memory usage (bytes)
  • delta: Memory difference (bytes)

Testing

Run the test suite:

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=function_monitor

# Run specific test file
pytest tests/test_monitor.py

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite (pytest)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/yourusername/function-monitor.git
cd function-monitor

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

# Install pre-commit hooks
pre-commit install

# Run tests
pytest

Changelog

v0.1.0 (Initial Release)

  • Basic function monitoring with execution timing
  • Memory and CPU usage tracking
  • Input/output validation with Pydantic
  • Structured logging with configurable output
  • Comprehensive error handling
  • Global and per-function configuration
  • Production-ready design

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Acknowledgments

  • Built with Pydantic for data validation
  • Uses structlog for structured logging
  • System monitoring powered by psutil

Note: This package is designed for production use but always test thoroughly in your specific environment before deploying to production.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyfuncmonitor-0.1.1.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyfuncmonitor-0.1.1-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file pyfuncmonitor-0.1.1.tar.gz.

File metadata

  • Download URL: pyfuncmonitor-0.1.1.tar.gz
  • Upload date:
  • Size: 9.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.12

File hashes

Hashes for pyfuncmonitor-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2c9b25e3f42938816f13535597cf6633edd8806cbc542679e6b6d5faebc630f5
MD5 32f27f5ac5e19ff648a24e8b8ca6523c
BLAKE2b-256 e95f63b632195c10dbf59a9b178f7335dea58b067a3a8b622776138289a4df01

See more details on using hashes here.

File details

Details for the file pyfuncmonitor-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pyfuncmonitor-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d4d09751358283ee6765df0922c4280d644c6ab61db2f0f681bc88221b61ee66
MD5 06400963952c23e1cbb3c83be8fee7ba
BLAKE2b-256 a1425a6753faba7c54885434f12ffb316d70b501e80fd590bb7e327526c1eceb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page