option('clear')) { if ($this->confirm('Are you sure you want to clear all AMI peer events?')) { $redis->del('ami:peer_events:list'); $redis->del('ami:peer_events'); $this->info('✅ All AMI peer events cleared.'); } return 0; } $this->info('📡 AMI Peer Status Events'); $this->line('─────────────────────────────────────────────────────────────'); // Get events from list $limit = (int) $this->option('limit'); $events = $redis->lrange('ami:peer_events:list', 0, $limit - 1); if (empty($events)) { $this->warn('No peer events found in Redis.'); $this->line('Make sure the Go AMI listener is running and storing events.'); return 0; } $totalCount = $redis->llen('ami:peer_events:list'); $this->info("Total events stored: {$totalCount} (showing last {$limit})"); $this->line(''); // Parse and filter events $parsedEvents = []; foreach ($events as $eventJson) { $event = json_decode($eventJson, true); if (!is_array($event)) { continue; } // Apply filters if ($this->option('extension') && $event['extension'] !== $this->option('extension')) { continue; } if ($this->option('action') && strtolower($event['action']) !== strtolower($this->option('action'))) { continue; } $parsedEvents[] = $event; } if (empty($parsedEvents)) { $this->warn('No events match your filters.'); return 0; } // Display events in table format $tableData = []; foreach ($parsedEvents as $event) { $datetime = isset($event['datetime']) ? $event['datetime'] : (isset($event['timestamp']) ? date('Y-m-d H:i:s', $event['timestamp']) : 'N/A'); $action = $event['action'] ?? 'N/A'; $actionIcon = $action === 'Reachable' ? '✓' : ($action === 'Unreachable' ? '✗' : ($action === 'pause' ? '⏸' : ($action === 'unpause' ? '▶' : '?'))); $tableData[] = [ 'Time' => $datetime, 'Action' => $actionIcon . ' ' . $action, 'name' => $event['name'] ?? 'N/A', 'Extension' => $event['extension'] ?? 'N/A', 'Type' => $event['channel_type'] ?? 'N/A', 'IP' => $event['ip_address'] ?? 'N/A', ]; } $this->table( ['Time', 'Action', 'Name', 'Extension', 'Type', 'IP'], $tableData ); // Statistics $this->line(''); $this->info('📊 Statistics:'); $reachableCount = count(array_filter($parsedEvents, fn($e) => ($e['action'] ?? '') === 'Reachable')); $unreachableCount = count(array_filter($parsedEvents, fn($e) => ($e['action'] ?? '') === 'Unreachable')); $holdCount = count(array_filter($parsedEvents, fn($e) => ($e['action'] ?? '') === 'Hold')); $unholdCount = count(array_filter($parsedEvents, fn($e) => ($e['action'] ?? '') === 'Unhold')); $this->line(" Reachable: {$reachableCount}"); $this->line(" Unreachable: {$unreachableCount}"); $this->line(" Hold: {$holdCount}"); $this->line(" Unhold: {$unholdCount}"); // Group by extension $byExtension = []; foreach ($parsedEvents as $event) { $ext = $event['extension'] ?? 'unknown'; if (!isset($byExtension[$ext])) { $byExtension[$ext] = ['reachable' => 0, 'unreachable' => 0, 'hold' => 0, 'unhold' => 0]; } $action = strtolower($event['action'] ?? ''); if ($action === 'reachable') { $byExtension[$ext]['reachable']++; } elseif ($action === 'unreachable') { $byExtension[$ext]['unreachable']++; } elseif ($action === 'hold') { $byExtension[$ext]['hold']++; } elseif ($action === 'unhold') { $byExtension[$ext]['unhold']++; } } if (count($byExtension) > 0) { $this->line(''); $this->info('📞 By Extension:'); foreach ($byExtension as $ext => $counts) { $this->line(" Ext {$ext}: ↑{$counts['reachable']} ↓{$counts['unreachable']} ⏸{$counts['hold']} ▶{$counts['unhold']}"); } } return 0; } catch (\Exception $e) { $this->error('❌ Error: ' . $e->getMessage()); $this->line('Stack trace:'); $this->line($e->getTraceAsString()); return 1; } } }