Files
thrillwiki_django_no_react/history_tracking/monitoring.py

202 lines
6.5 KiB
Python

import logging
import time
from functools import wraps
from django.conf import settings
from django.db import connection
# Configure logger
logger = logging.getLogger('version_control')
def track_operation_timing(operation_name):
"""Decorator to track timing of version control operations"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
duration = time.time() - start_time
# Log timing metrics
logger.info(
'Version Control Operation Timing',
extra={
'operation': operation_name,
'duration': duration,
'success': True
}
)
return result
except Exception as e:
duration = time.time() - start_time
logger.error(
'Version Control Operation Failed',
extra={
'operation': operation_name,
'duration': duration,
'error': str(e),
'success': False
}
)
raise
return wrapper
return decorator
def track_merge_result(source_branch, target_branch, success, conflict_count=0):
"""Track the results of merge operations"""
logger.info(
'Branch Merge Operation',
extra={
'source_branch': source_branch.name,
'target_branch': target_branch.name,
'success': success,
'conflict_count': conflict_count
}
)
def track_branch_metrics(branch):
"""Track metrics for a specific branch"""
from history_tracking.models import ChangeSet
changes = ChangeSet.objects.filter(branch=branch)
applied_changes = changes.filter(status='applied')
pending_changes = changes.filter(status='pending')
logger.info(
'Branch Metrics',
extra={
'branch_name': branch.name,
'total_changes': changes.count(),
'applied_changes': applied_changes.count(),
'pending_changes': pending_changes.count(),
'is_active': branch.is_active
}
)
def track_database_metrics():
"""Track database metrics for version control operations"""
with connection.execute_wrapper(StatementLogger()):
yield
class StatementLogger:
"""Log database statements for monitoring"""
def __call__(self, execute, sql, params, many, context):
start = time.time()
try:
result = execute(sql, params, many, context)
duration = time.time() - start
# Log only version control related queries
if 'version' in sql.lower() or 'changeset' in sql.lower():
logger.info(
'Version Control DB Operation',
extra={
'sql': sql,
'duration': duration,
'success': True
}
)
return result
except Exception as e:
duration = time.time() - start
logger.error(
'Version Control DB Operation Failed',
extra={
'sql': sql,
'duration': duration,
'error': str(e),
'success': False
}
)
raise
class VersionControlMetrics:
"""Collect and report version control system metrics"""
@staticmethod
def collect_system_metrics():
"""Collect overall system metrics"""
from history_tracking.models import VersionBranch, ChangeSet
total_branches = VersionBranch.objects.count()
active_branches = VersionBranch.objects.filter(is_active=True).count()
total_changes = ChangeSet.objects.count()
pending_changes = ChangeSet.objects.filter(status='pending').count()
conflicted_merges = ChangeSet.objects.filter(
status='conflict'
).count()
logger.info(
'Version Control System Metrics',
extra={
'total_branches': total_branches,
'active_branches': active_branches,
'total_changes': total_changes,
'pending_changes': pending_changes,
'conflicted_merges': conflicted_merges
}
)
@staticmethod
def collect_performance_metrics():
"""Collect performance-related metrics"""
from django.db import connection
from django.core.cache import cache
# Database metrics
with connection.execute_wrapper(StatementLogger()):
db_metrics = {
'total_queries': len(connection.queries),
'total_time': sum(
float(q['time']) for q in connection.queries
)
}
# Cache metrics
cache_metrics = {
'hits': cache.get('version_control_cache_hits', 0),
'misses': cache.get('version_control_cache_misses', 0)
}
logger.info(
'Version Control Performance Metrics',
extra={
'database': db_metrics,
'cache': cache_metrics
}
)
@staticmethod
def track_user_operations(user, operation, success):
"""Track user operations on version control"""
logger.info(
'Version Control User Operation',
extra={
'user_id': user.id,
'username': user.username,
'operation': operation,
'success': success
}
)
def setup_monitoring():
"""Configure monitoring for version control system"""
if not settings.DEBUG:
# Configure logging handlers
handler = logging.handlers.RotatingFileHandler(
'logs/version_control.log',
maxBytes=10485760, # 10MB
backupCount=5
)
handler.setFormatter(logging.Formatter(
'%(asctime)s [%(levelname)s] %(message)s'
))
logger.addHandler(handler)
# Set up error reporting
import sentry_sdk # type: ignore
sentry_sdk.init(
dsn=settings.SENTRY_DSN,
traces_sample_rate=0.1,
profiles_sample_rate=0.1,
)