workspace-v1/projects/gamilit/database/seeds/dev/audit_logging/02-system-metrics.sql
Adrian Flores Cortes 967ab360bb Initial commit: Workspace v1 with 3-layer architecture
Structure:
- control-plane/: Registries, SIMCO directives, CI/CD templates
- projects/: Gamilit, ERP-Suite, Trading-Platform, Betting-Analytics
- shared/: Libs catalog, knowledge-base

Key features:
- Centralized port, domain, database, and service registries
- 23 SIMCO directives + 6 fundamental principles
- NEXUS agent profiles with delegation rules
- Validation scripts for workspace integrity
- Dockerfiles for all services
- Path aliases for quick reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 00:35:19 -06:00

618 lines
15 KiB
SQL

-- =====================================================
-- GLIT Platform - System Metrics & Alerts Seeds
-- =====================================================
-- Schema: audit_logging
-- Description: Performance metrics, system alerts, user activity logs
-- Dependencies: auth schema (users)
-- =====================================================
SET search_path TO audit_logging, auth, public;
-- =====================================================
-- PERFORMANCE METRICS: Métricas históricas
-- =====================================================
INSERT INTO audit_logging.performance_metrics (
metric_name, metric_type, metric_metric_value,
unit, component, environment,
dimensions, recorded_at, created_at
) VALUES
-- ============ DATABASE METRICS ============
(
'database_connections_active',
'gauge',
15.0,
'connections',
'postgresql',
'development',
'{
"pool_size": 20,
"utilization_percentage": 75,
"idle_connections": 5,
"waiting_clients": 0
}'::jsonb,
NOW() - INTERVAL '10 minutes',
NOW() - INTERVAL '10 minutes'
),
(
'database_query_avg_duration',
'histogram',
45.5,
'milliseconds',
'postgresql',
'development',
'{
"queries_sampled": 1250,
"p50": 25.0,
"p75": 55.0,
"p95": 85.0,
"p99": 150.0,
"max": 500.0
}'::jsonb,
NOW() - INTERVAL '10 minutes',
NOW() - INTERVAL '10 minutes'
),
(
'database_cache_hit_ratio',
'gauge',
98.5,
'percentage',
'postgresql',
'development',
'{
"cache_hits": 9850,
"cache_misses": 150,
"total_queries": 10000,
"shared_buffers_mb": 128
}'::jsonb,
NOW() - INTERVAL '15 minutes',
NOW() - INTERVAL '15 minutes'
),
(
'database_transactions_per_second',
'gauge',
45.8,
'transactions',
'postgresql',
'development',
'{
"commits": 2748,
"rollbacks": 12,
"sample_duration_seconds": 60
}'::jsonb,
NOW() - INTERVAL '20 minutes',
NOW() - INTERVAL '20 minutes'
),
-- ============ APPLICATION METRICS ============
(
'api_requests_total',
'counter',
5432.0,
'requests',
'api_server',
'development',
'{
"endpoint": "/api/exercises",
"method": "GET",
"status_2xx": 5200,
"status_4xx": 200,
"status_5xx": 32,
"time_window_hours": 1
}'::jsonb,
NOW() - INTERVAL '1 hour',
NOW() - INTERVAL '1 hour'
),
(
'api_response_time',
'histogram',
125.5,
'milliseconds',
'api_server',
'development',
'{
"endpoint": "/api/modules",
"method": "GET",
"p50": 95.0,
"p75": 180.0,
"p95": 250.0,
"p99": 450.0,
"requests_count": 850
}'::jsonb,
NOW() - INTERVAL '30 minutes',
NOW() - INTERVAL '30 minutes'
),
(
'api_error_rate',
'gauge',
0.8,
'percentage',
'api_server',
'development',
'{
"total_requests": 5000,
"errors": 40,
"status_5xx": 32,
"status_4xx": 8,
"threshold_percentage": 2.0
}'::jsonb,
NOW() - INTERVAL '45 minutes',
NOW() - INTERVAL '45 minutes'
),
(
'websocket_connections_active',
'gauge',
12.0,
'connections',
'websocket_server',
'development',
'{
"max_connections": 1000,
"utilization_percentage": 1.2,
"messages_per_second": 45
}'::jsonb,
NOW() - INTERVAL '5 minutes',
NOW() - INTERVAL '5 minutes'
),
-- ============ USER ACTIVITY METRICS ============
(
'active_users_daily',
'gauge',
5.0,
'users',
'application',
'development',
'{
"date": "2025-11-02",
"students": 3,
"instructors": 1,
"admins": 1,
"total_sessions": 8,
"avg_session_duration_minutes": 45
}'::jsonb,
NOW() - INTERVAL '6 hours',
NOW() - INTERVAL '6 hours'
),
(
'exercises_completed',
'counter',
12.0,
'exercises',
'application',
'development',
'{
"period": "24h",
"module_breakdown": {
"MOD-01-LITERAL": 8,
"MOD-02-INFERENCIAL": 3,
"MOD-03-CRITICA": 1
},
"avg_score_percentage": 75.5
}'::jsonb,
NOW() - INTERVAL '1 hour',
NOW() - INTERVAL '1 hour'
),
(
'ml_coins_transactions',
'counter',
45.0,
'transactions',
'gamification',
'development',
'{
"period": "24h",
"total_earned": 1250,
"total_spent": 350,
"net_change": 900,
"unique_users": 3
}'::jsonb,
NOW() - INTERVAL '2 hours',
NOW() - INTERVAL '2 hours'
),
(
'mission_completion_rate',
'gauge',
65.5,
'percentage',
'application',
'development',
'{
"missions_assigned": 20,
"missions_completed": 13,
"missions_in_progress": 5,
"missions_overdue": 2
}'::jsonb,
NOW() - INTERVAL '3 hours',
NOW() - INTERVAL '3 hours'
),
-- ============ SYSTEM RESOURCES ============
(
'memory_usage',
'gauge',
512.5,
'megabytes',
'system',
'development',
'{
"total_mb": 2048,
"utilization_percentage": 25,
"heap_used_mb": 380,
"heap_total_mb": 512,
"rss_mb": 650
}'::jsonb,
NOW() - INTERVAL '5 minutes',
NOW() - INTERVAL '5 minutes'
),
(
'cpu_usage',
'gauge',
35.2,
'percentage',
'system',
'development',
'{
"cores": 4,
"load_average": [1.2, 1.5, 1.3],
"user_percentage": 25.5,
"system_percentage": 9.7
}'::jsonb,
NOW() - INTERVAL '5 minutes',
NOW() - INTERVAL '5 minutes'
),
(
'disk_usage',
'gauge',
1024.0,
'megabytes',
'system',
'development',
'{
"total_gb": 50,
"used_gb": 1.0,
"available_gb": 49.0,
"utilization_percentage": 2.0
}'::jsonb,
NOW() - INTERVAL '10 minutes',
NOW() - INTERVAL '10 minutes'
),
(
'network_throughput',
'gauge',
2.5,
'megabytes_per_second',
'system',
'development',
'{
"inbound_mbps": 1.8,
"outbound_mbps": 0.7,
"packets_per_second": 1250,
"errors": 0
}'::jsonb,
NOW() - INTERVAL '5 minutes',
NOW() - INTERVAL '5 minutes'
),
-- ============ CACHE METRICS ============
(
'cache_hit_rate',
'gauge',
85.5,
'percentage',
'redis',
'development',
'{
"total_requests": 5000,
"hits": 4275,
"misses": 725,
"evictions": 12
}'::jsonb,
NOW() - INTERVAL '15 minutes',
NOW() - INTERVAL '15 minutes'
),
(
'cache_memory_usage',
'gauge',
128.5,
'megabytes',
'redis',
'development',
'{
"max_memory_mb": 256,
"utilization_percentage": 50.2,
"keys_count": 1250,
"expired_keys": 45
}'::jsonb,
NOW() - INTERVAL '10 minutes',
NOW() - INTERVAL '10 minutes'
)
ON CONFLICT DO NOTHING;
-- =====================================================
-- SYSTEM ALERTS: Alertas generadas
-- =====================================================
INSERT INTO audit_logging.system_alerts (
alert_type, severity, title, message,
component, threshold_metric_value, current_metric_value,
status, triggered_at, resolved_at,
dimensions, created_at, updated_at
) VALUES
-- ============ RESOLVED ALERTS ============
-- High memory usage (resolved)
(
'resource',
'warning',
'High Memory Usage Detected',
'Memory usage exceeded 80% threshold',
'system',
80.0,
85.5,
'resolved',
NOW() - INTERVAL '2 hours',
NOW() - INTERVAL '1 hour',
'{
"actions_taken": [
"Memory cache cleared",
"Garbage collection forced",
"Unused connections closed"
],
"resolution_time_minutes": 60,
"peak_memory_mb": 1740,
"final_memory_mb": 512
}'::jsonb,
NOW() - INTERVAL '2 hours',
NOW() - INTERVAL '1 hour'
),
-- Failed login attempts (resolved)
(
'security',
'info',
'Multiple Failed Login Attempts',
'User exceeded login attempt threshold',
'authentication',
5.0,
6.0,
'resolved',
NOW() - INTERVAL '3 hours',
NOW() - INTERVAL '2 hours 55 minutes',
'{
"user_email": "test@example.com",
"ip_address": "203.0.113.42",
"actions_taken": [
"Account locked for 15 minutes",
"Security notification sent"
],
"resolution": "User successfully logged in after password reset",
"lockout_duration_minutes": 15
}'::jsonb,
NOW() - INTERVAL '3 hours',
NOW() - INTERVAL '2 hours 55 minutes'
),
-- Database backup success (acknowledged)
(
'maintenance',
'info',
'Automated Backup Completed',
'Daily database backup completed successfully',
'database',
NULL,
NULL,
'acknowledged',
NOW() - INTERVAL '6 hours',
NOW() - INTERVAL '6 hours',
'{
"backup_size_mb": 450,
"duration_seconds": 45,
"location": "/backups/glit_dev_2025-11-02.sql.gz",
"compression_ratio": 4.5,
"integrity_check": "passed"
}'::jsonb,
NOW() - INTERVAL '6 hours',
NOW() - INTERVAL '6 hours'
),
-- ============ ACTIVE ALERTS ============
-- Slow API endpoint (active)
(
'performance',
'warning',
'Slow API Response Time',
'Endpoint /api/leaderboards exceeding SLA',
'api_server',
200.0,
450.0,
'active',
NOW() - INTERVAL '15 minutes',
NULL,
'{
"endpoint": "/api/leaderboards",
"method": "GET",
"sla_ms": 200,
"p99_ms": 450,
"requests_affected": 25,
"suggested_actions": [
"Add database index on leaderboards.student_id",
"Implement Redis caching for leaderboard data",
"Consider pagination for large result sets"
]
}'::jsonb,
NOW() - INTERVAL '15 minutes',
NOW()
),
-- High error rate (active)
(
'performance',
'error',
'High API Error Rate',
'Error rate exceeded 2% threshold',
'api_server',
2.0,
3.5,
'active',
NOW() - INTERVAL '25 minutes',
NULL,
'{
"total_requests": 1000,
"errors": 35,
"error_breakdown": {
"500_internal_error": 20,
"503_service_unavailable": 10,
"504_gateway_timeout": 5
},
"affected_endpoints": [
"/api/exercises/submit",
"/api/ml-coins/transactions"
],
"investigating": true
}'::jsonb,
NOW() - INTERVAL '25 minutes',
NOW()
),
-- ============ ACKNOWLEDGED ALERTS ============
-- SSL certificate expiry warning (acknowledged)
(
'security',
'warning',
'SSL Certificate Expiring Soon',
'SSL certificate will expire in 30 days',
'security',
30.0,
30.0,
'acknowledged',
NOW() - INTERVAL '1 day',
NOW() - INTERVAL '1 day',
'{
"domain": "*.glit.edu.mx",
"expiry_date": "2025-12-02",
"days_remaining": 30,
"renewal_initiated": true,
"auto_renewal": true
}'::jsonb,
NOW() - INTERVAL '1 day',
NOW() - INTERVAL '1 day'
),
-- Disk space warning (acknowledged)
(
'resource',
'info',
'Disk Space Usage',
'Disk usage reached 70% threshold',
'system',
70.0,
72.5,
'acknowledged',
NOW() - INTERVAL '8 hours',
NOW() - INTERVAL '8 hours',
'{
"mount_point": "/var/lib/postgresql",
"total_gb": 100,
"used_gb": 72.5,
"available_gb": 27.5,
"cleanup_scheduled": true,
"retention_policy": "90 days"
}'::jsonb,
NOW() - INTERVAL '8 hours',
NOW() - INTERVAL '8 hours'
)
ON CONFLICT DO NOTHING;
-- =====================================================
-- USER ACTIVITY LOGS: Actividad de usuarios
-- =====================================================
DO $$
DECLARE
student_record RECORD;
activity_types TEXT[] := ARRAY['page_view', 'exercise_start', 'exercise_complete', 'mission_view', 'leaderboard_view', 'store_visit', 'achievement_view'];
pages TEXT[] := ARRAY['/modules', '/missions', '/leaderboard', '/ml-store', '/profile', '/achievements'];
BEGIN
-- Generar activity logs para cada estudiante
FOR student_record IN
SELECT user_id, email FROM auth.users WHERE role = 'student' LIMIT 3
LOOP
-- 5 actividades por estudiante
FOR i IN 1..5 LOOP
INSERT INTO audit_logging.user_activity_logs (
user_id, activity_type, activity_description,
ip_address, user_agent, session_id,
dimensions, created_at
) VALUES (
student_record.user_id,
activity_types[1 + floor(random() * array_length(activity_types, 1))::int],
'User activity: ' || pages[1 + floor(random() * array_length(pages, 1))::int],
'192.168.1.' || (50 + i)::TEXT,
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120.0.0.0',
gen_random_uuid(),
jsonb_build_object(
'page', pages[1 + floor(random() * array_length(pages, 1))::int],
'duration_seconds', 30 + floor(random() * 120)::int,
'interactions', 1 + floor(random() * 5)::int,
'referrer', '/dashboard',
'device_type', CASE WHEN random() > 0.7 THEN 'mobile' ELSE 'desktop' END
),
NOW() - (random() * INTERVAL '24 hours')
)
ON CONFLICT DO NOTHING;
END LOOP;
END LOOP;
-- Logs específicos adicionales
INSERT INTO audit_logging.user_activity_logs (
user_id, activity_type, activity_description,
ip_address, user_agent, session_id,
dimensions, created_at
)
SELECT
u.user_id,
'logout',
'User logged out',
'192.168.1.45',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120.0.0.0',
gen_random_uuid(),
'{
"session_duration_minutes": 45,
"activities_count": 12,
"logout_type": "manual"
}'::jsonb,
NOW() - INTERVAL '30 minutes'
FROM auth.users u
WHERE u.email = 'estudiante1@demo.glit.edu.mx'
ON CONFLICT DO NOTHING;
END $$;
-- =====================================================
-- SUMMARY
-- =====================================================
DO $$
DECLARE
metrics_count INT;
alerts_count INT;
activity_count INT;
BEGIN
SELECT COUNT(*) INTO metrics_count FROM audit_logging.performance_metrics;
SELECT COUNT(*) INTO alerts_count FROM audit_logging.system_alerts;
SELECT COUNT(*) INTO activity_count FROM audit_logging.user_activity_logs;
RAISE NOTICE 'System metrics seeds completed successfully';
RAISE NOTICE '- % performance_metrics inserted', metrics_count;
RAISE NOTICE '- % system_alerts inserted', alerts_count;
RAISE NOTICE '- % user_activity_logs inserted', activity_count;
END $$;