diff --git a/.replit b/.replit index 30bea15..10e17b3 100644 --- a/.replit +++ b/.replit @@ -14,6 +14,10 @@ run = ["npm", "run", "start"] localPort = 5000 externalPort = 80 +[[ports]] +localPort = 40859 +externalPort = 3001 + [[ports]] localPort = 41303 externalPort = 3002 diff --git a/attached_assets/Pasted--VERIFICA-SISTEMA-Log-backend-tail-f-var-log-ids-backend-log-Log-frontend-tail-f--1763740954834_1763740954834.txt b/attached_assets/Pasted--VERIFICA-SISTEMA-Log-backend-tail-f-var-log-ids-backend-log-Log-frontend-tail-f--1763740954834_1763740954834.txt new file mode 100644 index 0000000..6446abf --- /dev/null +++ b/attached_assets/Pasted--VERIFICA-SISTEMA-Log-backend-tail-f-var-log-ids-backend-log-Log-frontend-tail-f--1763740954834_1763740954834.txt @@ -0,0 +1,70 @@ + + VERIFICA SISTEMA: + • Log backend: tail -f /var/log/ids/backend.log + • Log frontend: tail -f /var/log/ids/frontend.log + • API backend: curl http://localhost:8000/health + • Frontend: curl http://localhost:5000 + + STATO SERVIZI: +ids 5038 0.2 2.0 1894024 331912 ? Sl 09:20 1:10 /usr/bin/python3.11 main.py +root 10798 0.0 0.1 730192 31688 pts/2 Rl+ 17:01 0:00 /usr/bin/node /usr/bin/npm run dev + +[root@ids ids]# sudo -u ids /opt/ids/deployment/restart_all.sh +pkill: killing pid 10842 failed: Operation not permitted +pkill: killing pid 10798 failed: Operation not permitted +[root@ids ids]# curl http://localhost:5000/api/stats +curl http://localhost:5000/api/routers +curl http://localhost:5000/api/detections +{"error":"Failed to fetch stats"}{"error":"Failed to fetch routers"}{"error":"Failed to fetch detections"}[root@ids ids]# +[root@ids ids]# tail -50 /var/log/ids/frontend.log +> NODE_ENV=development tsx server/index.ts + +5:00:00 PM [express] serving on port 5000 + +A PostCSS plugin did not pass the `from` option to `postcss.parse`. This may cause imported assets to be incorrectly transformed. If you've recently added a PostCSS plugin that raised this warning, please contact the package author to fix the issue. +5:00:03 PM [express] GET /api/training-history 500 in 70ms :: {"error":"Failed to fetch training his… +5:00:03 PM [express] GET /api/ml/stats 304 in 70ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:00:13 PM [express] GET /api/training-history 500 in 5ms :: {"error":"Failed to fetch training hist… +5:00:13 PM [express] GET /api/ml/stats 304 in 17ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:00:18 PM [express] GET /api/stats 500 in 6ms :: {"error":"Failed to fetch stats"} +5:00:23 PM [express] GET /api/training-history 500 in 6ms :: {"error":"Failed to fetch training hist… +5:00:23 PM [express] GET /api/ml/stats 304 in 18ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:00:26 PM [express] GET /api/routers 500 in 5ms :: {"error":"Failed to fetch routers"} +5:00:33 PM [express] GET /api/training-history 500 in 5ms :: {"error":"Failed to fetch training hist… +5:00:33 PM [express] GET /api/ml/stats 304 in 17ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:00:35 PM [express] GET /api/detections 500 in 5ms :: {"error":"Failed to fetch detections"} +5:00:43 PM [express] GET /api/training-history 500 in 5ms :: {"error":"Failed to fetch training hist… +5:00:43 PM [express] GET /api/ml/stats 304 in 17ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:00:53 PM [express] GET /api/training-history 500 in 5ms :: {"error":"Failed to fetch training hist… +5:00:53 PM [express] GET /api/ml/stats 304 in 16ms :: {"logs":{"total":0,"last_hour":0},"detections"… +[Fri Nov 21 17:01:08 CET 2025] Frontend Node NON attivo, riavvio... +[Fri Nov 21 17:01:10 CET 2025] Frontend riavviato con PID: 10798 + +> rest-express@1.0.0 dev +> NODE_ENV=development tsx server/index.ts + +5:01:12 PM [express] serving on port 5000 + +A PostCSS plugin did not pass the `from` option to `postcss.parse`. This may cause imported assets to be incorrectly transformed. If you've recently added a PostCSS plugin that raised this warning, please contact the package author to fix the issue. +5:01:15 PM [express] GET /api/training-history 500 in 64ms :: {"error":"Failed to fetch training his… +5:01:15 PM [express] GET /api/ml/stats 304 in 65ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:01:19 PM [express] GET /api/stats 500 in 10ms :: {"error":"Failed to fetch stats"} +5:01:19 PM [express] GET /api/detections 500 in 7ms :: {"error":"Failed to fetch detections"} +5:01:19 PM [express] GET /api/routers 500 in 6ms :: {"error":"Failed to fetch routers"} +5:01:21 PM [express] GET /api/detections 500 in 4ms :: {"error":"Failed to fetch detections"} +5:01:22 PM [express] GET /api/training-history 500 in 5ms :: {"error":"Failed to fetch training hist… +5:01:23 PM [express] GET /api/ml/stats 304 in 18ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:01:33 PM [express] GET /api/training-history 500 in 5ms :: {"error":"Failed to fetch training hist… +5:01:33 PM [express] GET /api/ml/stats 304 in 19ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:01:43 PM [express] GET /api/training-history 500 in 7ms :: {"error":"Failed to fetch training hist… +5:01:43 PM [express] GET /api/ml/stats 304 in 18ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:01:53 PM [express] GET /api/training-history 500 in 6ms :: {"error":"Failed to fetch training hist… +5:01:53 PM [express] GET /api/ml/stats 304 in 20ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:02:03 PM [express] GET /api/training-history 500 in 6ms :: {"error":"Failed to fetch training hist… +5:02:03 PM [express] GET /api/ml/stats 304 in 16ms :: {"logs":{"total":0,"last_hour":0},"detections"… +5:02:08 PM [express] GET /api/stats 500 in 5ms :: {"error":"Failed to fetch stats"} +5:02:08 PM [express] GET /api/routers 500 in 4ms :: {"error":"Failed to fetch routers"} +5:02:08 PM [express] GET /api/detections 500 in 3ms :: {"error":"Failed to fetch detections"} +5:02:13 PM [express] GET /api/training-history 500 in 4ms :: {"error":"Failed to fetch training hist… +5:02:13 PM [express] GET /api/ml/stats 304 in 17ms :: {"logs":{"total":0,"last_hour":0},"detections"… +[root@ids ids]# \ No newline at end of file diff --git a/replit.md b/replit.md index 07e9675..c9ef5f1 100644 --- a/replit.md +++ b/replit.md @@ -43,6 +43,25 @@ Sistema di rilevamento intrusioni per router MikroTik basato su Machine Learning ## Fix Recenti (Novembre 2025) +### ✅ Database Driver Fix - Dual Mode Neon/PostgreSQL (21 Nov 2025 - 17:10) +- **Problema**: Frontend Node.js falliva con errore 500 su tutte le query database (`/api/stats`, `/api/routers`, ecc.) +- **Causa ROOT**: `@neondatabase/serverless` usa WebSocket ed è compatibile SOLO con Neon Cloud, non con PostgreSQL locale su AlmaLinux +- **Diagnosi**: + - ✅ DATABASE_URL caricato correttamente (verificato con `psql`) + - ✅ Backend Python funzionava (usa `psycopg2` compatibile con PostgreSQL locale) + - ❌ Backend Node.js falliva (usava `@neondatabase/serverless`) +- **Soluzione**: + - Modificato `server/db.ts` per **dual-mode**: + - Su Replit (Neon Cloud): usa `@neondatabase/serverless` + WebSocket + - Su AlmaLinux (PostgreSQL locale): usa `pg` standard driver + - Auto-detection basata su `DATABASE_URL.includes('neon.tech')` + - Import corretto `pg` per ES modules: `import pg from 'pg'; const { Pool } = pg;` + - Aggiunto health-check database: `SELECT 1` all'avvio + - Aggiunto logging dettagliato errori DB: `[DB ERROR]` prefix +- **Risultato**: + - ✅ Replit: `📦 Using Neon serverless database` + `✅ Database connection successful` + - ⏳ AlmaLinux: `🐘 Using standard PostgreSQL database` (da testare dopo push) + ### ✅ Frontend Environment Variables Fix (21 Nov 2025 - 17:00) - **Problema**: Frontend Node.js non si avviava su server AlmaLinux con errore `DATABASE_URL must be set` - **Causa 1**: Script `check_frontend.sh` non caricava variabili d'ambiente dal file `.env` diff --git a/server/db.ts b/server/db.ts index 66779a9..43676e6 100644 --- a/server/db.ts +++ b/server/db.ts @@ -1,9 +1,12 @@ -import { Pool, neonConfig } from '@neondatabase/serverless'; -import { drizzle } from 'drizzle-orm/neon-serverless'; +import { drizzle as drizzleNeon } from 'drizzle-orm/neon-serverless'; +import { drizzle as drizzleNode } from 'drizzle-orm/node-postgres'; +import { Pool as NeonPool, neonConfig } from '@neondatabase/serverless'; +import pg from 'pg'; +import type { Pool as PgPoolType } from 'pg'; import ws from "ws"; import * as schema from "@shared/schema"; -neonConfig.webSocketConstructor = ws; +const { Pool: PgPool } = pg; if (!process.env.DATABASE_URL) { throw new Error( @@ -11,5 +14,34 @@ if (!process.env.DATABASE_URL) { ); } -export const pool = new Pool({ connectionString: process.env.DATABASE_URL }); -export const db = drizzle({ client: pool, schema }); +// Check if running on Replit (Neon) or AlmaLinux (PostgreSQL) +const isNeon = process.env.DATABASE_URL.includes('neon.tech') || + process.env.DATABASE_URL.includes('neon.aws'); + +let pool: NeonPool | PgPoolType; +let db: ReturnType | ReturnType; + +if (isNeon) { + // Neon serverless (Replit) + neonConfig.webSocketConstructor = ws; + pool = new NeonPool({ connectionString: process.env.DATABASE_URL }); + db = drizzleNeon(pool, { schema }); + console.log('📦 Using Neon serverless database'); +} else { + // PostgreSQL standard (AlmaLinux) + pool = new PgPool({ connectionString: process.env.DATABASE_URL }); + db = drizzleNode(pool, { schema }); + console.log('🐘 Using standard PostgreSQL database'); +} + +// Health check: test database connection on startup +pool.query('SELECT 1') + .then(() => console.log('✅ Database connection successful')) + .catch((err) => { + console.error('❌ Database connection failed:', err.message); + // Mask entire connection string for security + const dbType = isNeon ? 'Neon Cloud' : 'PostgreSQL'; + console.error(`Database type: ${dbType}`); + }); + +export { pool, db }; diff --git a/server/routes.ts b/server/routes.ts index 41a1667..57d6359 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -10,6 +10,7 @@ export async function registerRoutes(app: Express): Promise { const routers = await storage.getAllRouters(); res.json(routers); } catch (error) { + console.error('[DB ERROR] Failed to fetch routers:', error); res.status(500).json({ error: "Failed to fetch routers" }); } }); @@ -64,6 +65,7 @@ export async function registerRoutes(app: Express): Promise { const detections = await storage.getAllDetections(limit); res.json(detections); } catch (error) { + console.error('[DB ERROR] Failed to fetch detections:', error); res.status(500).json({ error: "Failed to fetch detections" }); } }); @@ -83,6 +85,7 @@ export async function registerRoutes(app: Express): Promise { const whitelist = await storage.getAllWhitelist(); res.json(whitelist); } catch (error) { + console.error('[DB ERROR] Failed to fetch whitelist:', error); res.status(500).json({ error: "Failed to fetch whitelist" }); } }); @@ -116,6 +119,7 @@ export async function registerRoutes(app: Express): Promise { const history = await storage.getTrainingHistory(limit); res.json(history); } catch (error) { + console.error('[DB ERROR] Failed to fetch training history:', error); res.status(500).json({ error: "Failed to fetch training history" }); } }); @@ -162,6 +166,7 @@ export async function registerRoutes(app: Express): Promise { latestTraining: latestTraining }); } catch (error) { + console.error('[DB ERROR] Failed to fetch stats:', error); res.status(500).json({ error: "Failed to fetch stats" }); } });