-- Create metrics table CREATE TABLE IF NOT EXISTS metrics ( id SERIAL PRIMARY KEY, server_id VARCHAR(255) NOT NULL, timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), cpu_usage DECIMAL(5,2), cpu_cores INTEGER, memory_total DECIMAL(10,2), memory_used DECIMAL(10,2), memory_available DECIMAL(10,2), memory_percent DECIMAL(5,2), disk_total DECIMAL(10,2), disk_used DECIMAL(10,2), disk_free DECIMAL(10,2), disk_percent DECIMAL(5,2), disks JSONB, network_rx DECIMAL(10,2), network_tx DECIMAL(10,2), network_rx_total DECIMAL(10,2), network_tx_total DECIMAL(10,2), created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); -- Create indexes for better query performance CREATE INDEX IF NOT EXISTS idx_metrics_server_id ON metrics(server_id); CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics(timestamp); CREATE INDEX IF NOT EXISTS idx_metrics_server_timestamp ON metrics(server_id, timestamp DESC); -- Migration: Add disks column if it doesn't exist (for existing databases) DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'metrics' AND column_name = 'disks' ) THEN ALTER TABLE metrics ADD COLUMN disks JSONB; CREATE INDEX IF NOT EXISTS idx_metrics_disks ON metrics USING GIN (disks); END IF; END $$; -- Create index for disks column (will be created if column exists) CREATE INDEX IF NOT EXISTS idx_metrics_disks ON metrics USING GIN (disks); -- Migration: Add load average columns if they don't exist DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'metrics' AND column_name = 'load_avg_1min' ) THEN ALTER TABLE metrics ADD COLUMN load_avg_1min DECIMAL(5,2); ALTER TABLE metrics ADD COLUMN load_avg_5min DECIMAL(5,2); ALTER TABLE metrics ADD COLUMN load_avg_15min DECIMAL(5,2); END IF; END $$; -- Migration: Add swap columns if they don't exist DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'metrics' AND column_name = 'swap_total' ) THEN ALTER TABLE metrics ADD COLUMN swap_total DECIMAL(10,2); ALTER TABLE metrics ADD COLUMN swap_used DECIMAL(10,2); ALTER TABLE metrics ADD COLUMN swap_free DECIMAL(10,2); ALTER TABLE metrics ADD COLUMN swap_percent DECIMAL(5,2); END IF; END $$; -- Migration: Add process_count and uptime columns if they don't exist DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'metrics' AND column_name = 'process_count' ) THEN ALTER TABLE metrics ADD COLUMN process_count INTEGER; ALTER TABLE metrics ADD COLUMN uptime_seconds DECIMAL(10,2); END IF; END $$; -- Create servers table to track server metadata CREATE TABLE IF NOT EXISTS servers ( server_id VARCHAR(255) PRIMARY KEY, hostname VARCHAR(255), first_seen TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), last_seen TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), total_metrics_count INTEGER DEFAULT 0 ); -- Create function to update server last_seen and metrics count CREATE OR REPLACE FUNCTION update_server_stats() RETURNS TRIGGER AS $$ BEGIN INSERT INTO servers (server_id, hostname, first_seen, last_seen, total_metrics_count) VALUES (NEW.server_id, NEW.server_id, NOW(), NOW(), 1) ON CONFLICT (server_id) DO UPDATE SET last_seen = NOW(), total_metrics_count = servers.total_metrics_count + 1; RETURN NEW; END; $$ LANGUAGE plpgsql; -- Create trigger to automatically update server stats DROP TRIGGER IF EXISTS trigger_update_server_stats ON metrics; CREATE TRIGGER trigger_update_server_stats AFTER INSERT ON metrics FOR EACH ROW EXECUTE FUNCTION update_server_stats(); -- Create API keys table for client authentication CREATE TABLE IF NOT EXISTS api_keys ( id SERIAL PRIMARY KEY, key_hash VARCHAR(255) NOT NULL UNIQUE, server_id VARCHAR(255), name VARCHAR(255), created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), last_used TIMESTAMP WITH TIME ZONE, is_active BOOLEAN DEFAULT TRUE ); CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash); CREATE INDEX IF NOT EXISTS idx_api_keys_server_id ON api_keys(server_id);