Skip to main content

Overview

The WebSocket endpoint provides real-time streaming of Sentinel AI system logs and events. This allows clients to receive live updates about agent activities, service monitoring, errors, and system events.

Connect to WebSocket

const ws = new WebSocket('ws://localhost:8000/ws/logs');

ws.onopen = () => {
  console.log('Connected to log stream');
};

ws.onmessage = (event) => {
  const logEvent = JSON.parse(event.data);
  console.log(`[${logEvent.type}] ${logEvent.message}`);
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = () => {
  console.log('Disconnected from log stream');
};
Establishes a WebSocket connection to receive real-time log events. Endpoint: ws://localhost:8000/ws/logs Protocol: WebSocket

Event Structure

All events are sent as JSON objects with the following structure:
type
string
The event type/category. Common values include:
  • "system": System-level events (startup, shutdown, state changes)
  • "agent": Agent execution events
  • "monitor": Service monitoring events
  • "error": Error messages
  • "config": Configuration changes
  • "security": Security-related events
message
string
Human-readable log message describing the event
timestamp
string
ISO 8601 timestamp when the event occurred
data
object
Additional structured data related to the event (event-specific)

Event Types

System Events

System-level events related to Sentinel AI’s operation:
{
  "type": "system",
  "message": "Sentinel AI Iniciado (Modo API) 🚀",
  "timestamp": "2026-03-09T14:00:00.123456"
}
{
  "type": "system",
  "message": "Ejecutando ciclo de analisis bajo demanda...",
  "timestamp": "2026-03-09T14:05:00.123456"
}
{
  "type": "system",
  "message": "Agente pausado esperando aprobacion.",
  "timestamp": "2026-03-09T14:10:00.123456"
}
{
  "type": "system",
  "message": "Ciclo de analisis completado.",
  "timestamp": "2026-03-09T14:15:00.123456"
}

Error Events

Error and exception events:
{
  "type": "error",
  "message": "Error critico durante la ejecucion del agente: Connection timeout",
  "timestamp": "2026-03-09T14:20:00.123456",
  "data": {
    "error_type": "ConnectionTimeout",
    "service": "postgresql"
  }
}

Configuration Events

Configuration change events:
{
  "type": "config",
  "message": "Servicio 'mongodb' agregado al monitoreo.",
  "timestamp": "2026-03-09T14:25:00.123456",
  "data": {
    "service_name": "mongodb",
    "action": "added"
  }
}
{
  "type": "config",
  "message": "Servicio 'oldservice' eliminado del monitoreo.",
  "timestamp": "2026-03-09T14:30:00.123456",
  "data": {
    "service_name": "oldservice",
    "action": "removed"
  }
}

Agent Events

Agent execution and decision events:
{
  "type": "agent",
  "message": "Diagnosticando servicio postgresql",
  "timestamp": "2026-03-09T14:35:00.123456",
  "data": {
    "step": "diagnose",
    "service": "postgresql"
  }
}
{
  "type": "agent",
  "message": "Ejecutando remediacion: reiniciar servicio",
  "timestamp": "2026-03-09T14:40:00.123456",
  "data": {
    "step": "remediate",
    "action": "restart",
    "service": "postgresql"
  }
}

Monitor Events

Service monitoring events:
{
  "type": "monitor",
  "message": "Servicio nginx esta funcionando correctamente",
  "timestamp": "2026-03-09T14:45:00.123456",
  "data": {
    "service": "nginx",
    "status": "running"
  }
}
{
  "type": "monitor",
  "message": "Servicio redis no responde",
  "timestamp": "2026-03-09T14:50:00.123456",
  "data": {
    "service": "redis",
    "status": "stopped"
  }
}

Connection Lifecycle

Connection Established

When a client connects to the WebSocket, the connection is immediately accepted and the client is subscribed to the event bus.

Receiving Events

Events are pushed to all connected clients in real-time as they occur. There is no request/response pattern - the client only receives events.

Connection Closed

When the connection is closed (either by the client or server), the client is automatically unsubscribed from the event bus.

Error Handling

If an error occurs on the WebSocket connection, the connection will be closed and the client will be unsubscribed.

Implementation Example

React Component

import { useEffect, useState } from 'react';

function LogViewer() {
  const [logs, setLogs] = useState([]);
  const [connected, setConnected] = useState(false);

  useEffect(() => {
    const ws = new WebSocket('ws://localhost:8000/ws/logs');

    ws.onopen = () => {
      setConnected(true);
      console.log('Connected to log stream');
    };

    ws.onmessage = (event) => {
      const logEvent = JSON.parse(event.data);
      setLogs(prev => [...prev, logEvent]);
    };

    ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };

    ws.onclose = () => {
      setConnected(false);
      console.log('Disconnected from log stream');
    };

    return () => {
      ws.close();
    };
  }, []);

  return (
    <div>
      <div>Status: {connected ? 'Connected' : 'Disconnected'}</div>
      <div>
        {logs.map((log, i) => (
          <div key={i}>
            <span>[{log.type}]</span>
            <span>{log.timestamp}</span>
            <span>{log.message}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

Python Log Aggregator

import asyncio
import websockets
import json
from datetime import datetime

class LogAggregator:
    def __init__(self, uri="ws://localhost:8000/ws/logs"):
        self.uri = uri
        self.logs = []
        self.filters = set()
    
    def add_filter(self, event_type):
        """Only show logs of specific types"""
        self.filters.add(event_type)
    
    async def connect(self):
        async with websockets.connect(self.uri) as websocket:
            print(f"Connected to {self.uri}")
            
            try:
                async for message in websocket:
                    log_event = json.loads(message)
                    
                    # Apply filters
                    if self.filters and log_event['type'] not in self.filters:
                        continue
                    
                    # Store log
                    self.logs.append(log_event)
                    
                    # Display log
                    timestamp = log_event.get('timestamp', '')
                    log_type = log_event['type']
                    message = log_event['message']
                    
                    print(f"[{timestamp}] [{log_type}] {message}")
                    
            except websockets.exceptions.ConnectionClosed:
                print("Connection closed")
    
    def get_logs(self, event_type=None):
        """Retrieve stored logs"""
        if event_type:
            return [log for log in self.logs if log['type'] == event_type]
        return self.logs

# Usage
aggregator = LogAggregator()
aggregator.add_filter('error')  # Only show errors
aggregator.add_filter('system')  # And system events

asyncio.run(aggregator.connect())

Reconnection Strategy

WebSocket connections can drop due to network issues. Implement automatic reconnection:
class LogStreamClient {
  constructor(url, onMessage) {
    this.url = url;
    this.onMessage = onMessage;
    this.reconnectDelay = 1000;
    this.maxReconnectDelay = 30000;
    this.connect();
  }

  connect() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      console.log('Connected');
      this.reconnectDelay = 1000; // Reset delay
    };

    this.ws.onmessage = (event) => {
      const logEvent = JSON.parse(event.data);
      this.onMessage(logEvent);
    };

    this.ws.onclose = () => {
      console.log('Disconnected. Reconnecting...');
      setTimeout(() => this.connect(), this.reconnectDelay);
      
      // Exponential backoff
      this.reconnectDelay = Math.min(
        this.reconnectDelay * 2,
        this.maxReconnectDelay
      );
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
  }

  close() {
    this.ws.close();
  }
}

// Usage
const client = new LogStreamClient(
  'ws://localhost:8000/ws/logs',
  (log) => console.log(log)
);

Use Cases

Real-time Monitoring

Build live dashboards showing agent activity and system status

Log Aggregation

Collect and store all events for analysis and auditing

Alert Systems

Trigger alerts based on specific error or security events

Debug Tools

Monitor agent execution flow during development and troubleshooting

Best Practices

Implement Reconnection: Network issues can cause disconnections. Always implement automatic reconnection with exponential backoff.
Filter Client-Side: The WebSocket sends all events. Filter events on the client side based on your needs to reduce processing overhead.
Buffer Management: If processing events is slow, implement buffering to prevent memory issues from queued events.
Security Consideration: The WebSocket endpoint is not authenticated. In production, implement proper authentication and authorization.

Build docs developers (and LLMs) love