omni-node-broker / server.js
AnberAziz5's picture
Update broker files
0cbb9f9
Raw
History Blame Contribute Delete
4.91 kB
require('dotenv').config();
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const cors = require('cors');
const axios = require('axios');
const { GoogleGenAI } = require('@google/genai');
const mongoose = require('mongoose');
const app = express();
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, { cors: { origin: '*' } });
// --- 1. MONGODB LEDGER CONNECTION ---
mongoose.connect(process.env.MONGO_URI)
.then(() => console.log('[Database] MongoDB Audit Ledger Connected'))
.catch(err => console.error('[Database] Connection Failed. Check your password and IP settings in Atlas:', err.message));
// --- 2. DEFINE THE DATA SCHEMA ---
const AuditLogSchema = new mongoose.Schema({
component_id: String,
cpu_load: Number,
memory_usage: Number,
api_latency: Number,
ml_anomaly_score: Number,
ai_diagnosis: String,
ai_remediation_command: String,
timestamp: { type: Date, default: Date.now }
});
const AuditLog = mongoose.model('AuditLog', AuditLogSchema);
// --- 3. PIPELINE SETUP ---
const PYTHON_URL = process.env.PYTHON_ENGINE_URL;
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
function generateTelemetry() {
const isSpike = Math.random() > 0.70; // 30% chance of anomaly
return {
component_id: `SRV-${Math.floor(Math.random() * 1000)}`,
cpu_load: isSpike ? 98.5 : 45 + (Math.random() * 10),
memory_usage: isSpike ? 62.0 : 16 + (Math.random() * 4),
api_latency: isSpike ? 1500.0 : 120 + (Math.random() * 20)
};
}
io.on('connection', (socket) => {
console.log(`[Mesh Control] Dashboard connected: ${socket.id}`);
const telemetryInterval = setInterval(async () => {
const payload = generateTelemetry();
console.log(`[Mesh Pulse] Emitting data for ${payload.component_id}`);
socket.emit('telemetry_update', payload);
try {
const mlResponse = await axios.post(PYTHON_URL, payload);
const { is_critical, anomaly_score } = mlResponse.data;
if (is_critical) {
socket.emit('alert_status', { component: payload.component_id, message: 'Anomaly Detected. Spawning Gemini Agent...' });
// Trigger AI Engine
const remediation = await triggerAutonomousAgent(payload, anomaly_score);
// Stream Resolution to Frontend UI
socket.emit('remediation_plan', { component: payload.component_id, plan: remediation });
// --- 4. PERMANENTLY LOG TO MONGODB ---
await AuditLog.create({
component_id: payload.component_id,
cpu_load: payload.cpu_load,
memory_usage: payload.memory_usage,
api_latency: payload.api_latency,
ml_anomaly_score: anomaly_score,
ai_diagnosis: remediation.root_cause_diagnosis,
ai_remediation_command: remediation.bash_mitigation_command
});
console.log(`[Ledger] Wrote AI Audit Log to MongoDB for ${payload.component_id}`);
}
} catch (error) {
console.error('[Pipeline Error]', error.message);
}
}, 6000);
socket.on('disconnect', () => clearInterval(telemetryInterval));
});
async function triggerAutonomousAgent(telemetry, score) {
const prompt = `CRITICAL ALERT on ${telemetry.component_id}. CPU: ${telemetry.cpu_load.toFixed(1)}%, RAM: ${telemetry.memory_usage.toFixed(1)}GB, Latency: ${telemetry.api_latency.toFixed(0)}ms. ML Anomaly Score: ${score}. Provide a concise JSON response with keys: "root_cause_diagnosis" and "bash_mitigation_command".`;
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt,
config: {
systemInstruction: "You are an elite Site Reliability Engineer. Output ONLY valid JSON.",
responseMimeType: "application/json",
}
});
return JSON.parse(response.text);
} catch (err) {
console.error('\n[Gemini API Error Details]:', err.message);
return {
root_cause_diagnosis: `Agent Execution Failure: ${err.message}`,
bash_mitigation_command: "sudo systemctl restart networking"
};
}
}
// --- 5. AUDIT LOG RETRIEVAL ENDPOINT ---
app.get('/api/logs', async (req, res) => {
try {
const logs = await AuditLog.find().sort({ timestamp: -1 }).limit(50);
res.json(logs);
} catch (err) {
res.status(500).json({ error: 'Failed to fetch ledger data' });
}
});
const PORT = process.env.PORT || 7860;
server.listen(PORT, () => console.log(`[Broker] Orchestrator online on port ${PORT}`));