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 hintsvalidate_output: Enable output validation using type hintslog_execution: Enable structured logginglog_level: Log level for the function ("DEBUG", "INFO", "WARNING", "ERROR")return_raw_result: Return original result on success, structured format on errorenable_memory_monitoring: Enable memory usage monitoringenable_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
- Production Usage: Use
return_raw_result=Truein production to avoid overhead - Input Validation: Enable input validation for external-facing functions
- Log File Management: Configure log rotation to prevent disk space issues
- Selective Monitoring: Disable CPU/memory monitoring for high-frequency functions if needed
- 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
psutilfor 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
- Import Errors: Ensure all dependencies are installed
- Permission Issues: Check file permissions for log files
- Memory Monitoring: Requires
psutilpackage - 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 validationvalidate_output(bool): Enable output validationlog_execution(bool): Enable execution logginglog_level(str): Logging levelreturn_raw_result(bool): Return format preferenceenable_memory_monitoring(bool): Enable memory trackingenable_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 valuestatus: "success" or "error"errors: List of error messages (if any)execution_time: Execution time in secondsmemory_usage: Memory usage statisticscpu_usage: CPU usage percentagetimestamp: ISO timestampfunction_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
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Run the test suite (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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
- Issues: GitHub Issues
- Documentation: Read the Docs
- PyPI: PyPI Package
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c9b25e3f42938816f13535597cf6633edd8806cbc542679e6b6d5faebc630f5
|
|
| MD5 |
32f27f5ac5e19ff648a24e8b8ca6523c
|
|
| BLAKE2b-256 |
e95f63b632195c10dbf59a9b178f7335dea58b067a3a8b622776138289a4df01
|
File details
Details for the file pyfuncmonitor-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pyfuncmonitor-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4d09751358283ee6765df0922c4280d644c6ab61db2f0f681bc88221b61ee66
|
|
| MD5 |
06400963952c23e1cbb3c83be8fee7ba
|
|
| BLAKE2b-256 |
a1425a6753faba7c54885434f12ffb316d70b501e80fd590bb7e327526c1eceb
|