290 lines
9.3 KiB
Python
290 lines
9.3 KiB
Python
"""
|
|
Admin configuration for monitoring models
|
|
"""
|
|
from django.contrib import admin
|
|
from django.utils.html import format_html
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
|
|
from monitoring.models import (
|
|
MonitoringTarget, HealthCheck, SystemMetric, MetricMeasurement,
|
|
AlertRule, Alert, MonitoringDashboard, SystemStatus
|
|
)
|
|
|
|
|
|
@admin.register(MonitoringTarget)
|
|
class MonitoringTargetAdmin(admin.ModelAdmin):
|
|
"""Admin for MonitoringTarget model"""
|
|
|
|
list_display = [
|
|
'name', 'target_type', 'status', 'last_status', 'last_checked',
|
|
'health_check_enabled', 'related_module', 'created_at'
|
|
]
|
|
list_filter = ['target_type', 'status', 'last_status', 'health_check_enabled', 'related_module']
|
|
search_fields = ['name', 'description', 'endpoint_url']
|
|
readonly_fields = ['id', 'created_at', 'updated_at', 'last_checked']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('id', 'name', 'description', 'target_type', 'related_module')
|
|
}),
|
|
('Connection Details', {
|
|
'fields': ('endpoint_url', 'connection_config')
|
|
}),
|
|
('Monitoring Configuration', {
|
|
'fields': (
|
|
'check_interval_seconds', 'timeout_seconds', 'retry_count',
|
|
'health_check_enabled', 'health_check_endpoint', 'expected_status_codes'
|
|
)
|
|
}),
|
|
('Status', {
|
|
'fields': ('status', 'last_checked', 'last_status')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_by', 'created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('created_by')
|
|
|
|
|
|
@admin.register(HealthCheck)
|
|
class HealthCheckAdmin(admin.ModelAdmin):
|
|
"""Admin for HealthCheck model"""
|
|
|
|
list_display = [
|
|
'target_name', 'check_type', 'status', 'response_time_ms',
|
|
'status_code', 'checked_at'
|
|
]
|
|
list_filter = ['check_type', 'status', 'target__target_type']
|
|
search_fields = ['target__name', 'error_message']
|
|
readonly_fields = ['id', 'checked_at']
|
|
date_hierarchy = 'checked_at'
|
|
|
|
def target_name(self, obj):
|
|
return obj.target.name
|
|
target_name.short_description = 'Target'
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('target')
|
|
|
|
|
|
@admin.register(SystemMetric)
|
|
class SystemMetricAdmin(admin.ModelAdmin):
|
|
"""Admin for SystemMetric model"""
|
|
|
|
list_display = [
|
|
'name', 'metric_type', 'category', 'unit', 'is_active',
|
|
'is_system_metric', 'related_module', 'created_at'
|
|
]
|
|
list_filter = ['metric_type', 'category', 'is_active', 'is_system_metric', 'related_module']
|
|
search_fields = ['name', 'description']
|
|
readonly_fields = ['id', 'created_at', 'updated_at']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('id', 'name', 'description', 'metric_type', 'category', 'unit')
|
|
}),
|
|
('Configuration', {
|
|
'fields': (
|
|
'aggregation_method', 'collection_interval_seconds', 'retention_days',
|
|
'warning_threshold', 'critical_threshold'
|
|
)
|
|
}),
|
|
('Status', {
|
|
'fields': ('is_active', 'is_system_metric', 'related_module')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_by', 'created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('created_by')
|
|
|
|
|
|
@admin.register(MetricMeasurement)
|
|
class MetricMeasurementAdmin(admin.ModelAdmin):
|
|
"""Admin for MetricMeasurement model"""
|
|
|
|
list_display = [
|
|
'metric_name', 'value', 'unit', 'timestamp'
|
|
]
|
|
list_filter = ['metric__metric_type', 'metric__category', 'timestamp']
|
|
search_fields = ['metric__name']
|
|
readonly_fields = ['id', 'timestamp']
|
|
date_hierarchy = 'timestamp'
|
|
|
|
def metric_name(self, obj):
|
|
return obj.metric.name
|
|
metric_name.short_description = 'Metric'
|
|
|
|
def unit(self, obj):
|
|
return obj.metric.unit
|
|
unit.short_description = 'Unit'
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('metric')
|
|
|
|
|
|
@admin.register(AlertRule)
|
|
class AlertRuleAdmin(admin.ModelAdmin):
|
|
"""Admin for AlertRule model"""
|
|
|
|
list_display = [
|
|
'name', 'alert_type', 'severity', 'status', 'is_enabled',
|
|
'metric_name', 'target_name', 'created_at'
|
|
]
|
|
list_filter = ['alert_type', 'severity', 'status', 'is_enabled']
|
|
search_fields = ['name', 'description']
|
|
readonly_fields = ['id', 'created_at', 'updated_at']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('id', 'name', 'description', 'alert_type', 'severity')
|
|
}),
|
|
('Rule Configuration', {
|
|
'fields': ('condition', 'evaluation_interval_seconds')
|
|
}),
|
|
('Related Objects', {
|
|
'fields': ('metric', 'target')
|
|
}),
|
|
('Notifications', {
|
|
'fields': ('notification_channels', 'notification_template')
|
|
}),
|
|
('Status', {
|
|
'fields': ('status', 'is_enabled')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_by', 'created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
})
|
|
)
|
|
|
|
def metric_name(self, obj):
|
|
return obj.metric.name if obj.metric else '-'
|
|
metric_name.short_description = 'Metric'
|
|
|
|
def target_name(self, obj):
|
|
return obj.target.name if obj.target else '-'
|
|
target_name.short_description = 'Target'
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('metric', 'target', 'created_by')
|
|
|
|
|
|
@admin.register(Alert)
|
|
class AlertAdmin(admin.ModelAdmin):
|
|
"""Admin for Alert model"""
|
|
|
|
list_display = [
|
|
'title', 'severity', 'status', 'rule_name', 'triggered_value',
|
|
'threshold_value', 'triggered_at', 'acknowledged_by', 'resolved_by'
|
|
]
|
|
list_filter = ['severity', 'status', 'rule__alert_type', 'triggered_at']
|
|
search_fields = ['title', 'description', 'rule__name']
|
|
readonly_fields = ['id', 'triggered_at']
|
|
date_hierarchy = 'triggered_at'
|
|
|
|
fieldsets = (
|
|
('Alert Information', {
|
|
'fields': ('id', 'rule', 'title', 'description', 'severity', 'status')
|
|
}),
|
|
('Values', {
|
|
'fields': ('triggered_value', 'threshold_value', 'context_data')
|
|
}),
|
|
('Timestamps', {
|
|
'fields': ('triggered_at', 'acknowledged_at', 'resolved_at')
|
|
}),
|
|
('Assignment', {
|
|
'fields': ('acknowledged_by', 'resolved_by')
|
|
})
|
|
)
|
|
|
|
def rule_name(self, obj):
|
|
return obj.rule.name
|
|
rule_name.short_description = 'Rule'
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related(
|
|
'rule', 'acknowledged_by', 'resolved_by'
|
|
)
|
|
|
|
|
|
@admin.register(MonitoringDashboard)
|
|
class MonitoringDashboardAdmin(admin.ModelAdmin):
|
|
"""Admin for MonitoringDashboard model"""
|
|
|
|
list_display = [
|
|
'name', 'dashboard_type', 'is_active', 'is_public',
|
|
'auto_refresh_enabled', 'created_by', 'created_at'
|
|
]
|
|
list_filter = ['dashboard_type', 'is_active', 'is_public', 'auto_refresh_enabled']
|
|
search_fields = ['name', 'description']
|
|
readonly_fields = ['id', 'created_at', 'updated_at']
|
|
filter_horizontal = ['allowed_users']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('id', 'name', 'description', 'dashboard_type')
|
|
}),
|
|
('Configuration', {
|
|
'fields': ('layout_config', 'widget_configs')
|
|
}),
|
|
('Access Control', {
|
|
'fields': ('is_public', 'allowed_users', 'allowed_roles')
|
|
}),
|
|
('Refresh Settings', {
|
|
'fields': ('auto_refresh_enabled', 'refresh_interval_seconds')
|
|
}),
|
|
('Status', {
|
|
'fields': ('is_active',)
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_by', 'created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('created_by')
|
|
|
|
|
|
@admin.register(SystemStatus)
|
|
class SystemStatusAdmin(admin.ModelAdmin):
|
|
"""Admin for SystemStatus model"""
|
|
|
|
list_display = [
|
|
'status', 'message', 'started_at', 'resolved_at', 'is_resolved',
|
|
'created_by'
|
|
]
|
|
list_filter = ['status', 'started_at', 'resolved_at']
|
|
search_fields = ['message', 'affected_services']
|
|
readonly_fields = ['id', 'started_at', 'updated_at', 'is_resolved']
|
|
date_hierarchy = 'started_at'
|
|
|
|
fieldsets = (
|
|
('Status Information', {
|
|
'fields': ('id', 'status', 'message', 'affected_services')
|
|
}),
|
|
('Timeline', {
|
|
'fields': ('started_at', 'updated_at', 'resolved_at', 'estimated_resolution')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_by', 'is_resolved'),
|
|
'classes': ('collapse',)
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('created_by')
|
|
|
|
|
|
# Custom admin site configuration
|
|
admin.site.site_header = "ETB-API Monitoring Administration"
|
|
admin.site.site_title = "ETB-API Monitoring"
|
|
admin.site.index_title = "Monitoring System Administration"
|