diff --git a/app/classes/agent.php b/app/classes/agent.php index 1589fa3..a69be6e 100644 --- a/app/classes/agent.php +++ b/app/classes/agent.php @@ -494,6 +494,77 @@ class Agent { return null; } + /** + * Gets historical data for a specific metric from agent checks + * + * @param int $platform_id The platform ID + * @param string $agent_type The type of agent (e.g., 'jvb', 'jicofo') + * @param string $metric_type The type of metric to retrieve + * @param string $from_time Start time in Y-m-d format + * @param string $until_time End time in Y-m-d format + * @return array Array with the dataset from agent checks + */ + public function getHistoricalData($platform_id, $agent_type, $metric_type, $from_time, $until_time) { + // Get data from agent checks + $sql = 'SELECT + DATE(jac.timestamp) as date, + jac.response_content, + COUNT(*) as checks_count + FROM + jilo_agent_checks jac + JOIN + jilo_agents ja ON jac.agent_id = ja.id + JOIN + jilo_agent_types jat ON ja.agent_type_id = jat.id + WHERE + ja.platform_id = :platform_id + AND jat.description = :agent_type + AND jac.status_code = 200 + AND DATE(jac.timestamp) BETWEEN :from_time AND :until_time + GROUP BY + DATE(jac.timestamp) + ORDER BY + DATE(jac.timestamp)'; + + $query = $this->db->prepare($sql); + $query->execute([ + ':platform_id' => $platform_id, + ':agent_type' => $agent_type, + ':from_time' => $from_time, + ':until_time' => $until_time + ]); + + $results = $query->fetchAll(PDO::FETCH_ASSOC); + + $data = []; + foreach ($results as $row) { + $json_data = json_decode($row['response_content'], true); + if (json_last_error() === JSON_ERROR_NONE) { + $api_data = []; + if ($agent_type === 'jvb') { + $api_data = $json_data['jvb_api_data'] ?? []; + } elseif ($agent_type === 'jicofo') { + $api_data = $json_data['jicofo_api_data'] ?? []; + } elseif ($agent_type === 'jigasi') { + $api_data = $json_data['jigasi_api_data'] ?? []; + } elseif ($agent_type === 'prosody') { + $api_data = $json_data['prosody_api_data'] ?? []; + } elseif ($agent_type === 'nginx') { + $api_data = $json_data['nginx_api_data'] ?? []; + } + + $value = $this->getNestedValue($api_data, $metric_type); + if ($value !== null) { + $data[] = [ + 'date' => $row['date'], + 'value' => $value + ]; + } + } + } + + return $data; + } } ?> diff --git a/app/helpers/graph.php b/app/helpers/graph.php index b5c73a9..f455280 100644 --- a/app/helpers/graph.php +++ b/app/helpers/graph.php @@ -5,40 +5,30 @@ diff --git a/app/pages/data.php b/app/pages/data.php index 09790f6..5854898 100644 --- a/app/pages/data.php +++ b/app/pages/data.php @@ -9,154 +9,196 @@ $agent = $_REQUEST['agent'] ?? ''; require '../app/classes/config.php'; require '../app/classes/agent.php'; +require '../app/classes/conference.php'; $configObject = new Config(); $agentObject = new Agent($dbWeb); -switch ($item) { +// connect to Jilo database +$response = connectDB($config, 'jilo', $platformDetails[0]['jilo_database'], $platform_id); - case 'graphs': - // FIXME example data - $one = date('Y-m-d',strtotime("-5 days")); - $two = date('Y-m-d',strtotime("-4 days")); - $three = date('Y-m-d',strtotime("-2 days")); - $four = date('Y-m-d',strtotime("-1 days")); +// if DB connection has error, display it and stop here +if ($response['db'] === null) { + $error = $response['error']; + include '../app/templates/block-message.php'; - $graph[0]['data0'] = [ - ['date' => $one, 'value' => 10], - ['date' => $two, 'value' => 20], - ['date' => $three, 'value' => 15], - ['date' => $four, 'value' => 25], - ]; +// otherwise if DB connection is OK, go on +} else { + $db = $response['db']; - $graph[0]['data1'] = [ - ['date' => $one, 'value' => 12], - ['date' => $two, 'value' => 23], - ['date' => $three, 'value' => 11], - ['date' => $four, 'value' => 27], - ]; + $conferenceObject = new Conference($db); - $graph[0]['graph_name'] = 'conferences'; - $graph[0]['graph_title'] = 'Conferences in "' . htmlspecialchars($platformDetails[0]['name']) . '" over time'; - $graph[0]['graph_data0_label'] = 'Conferences from Jitsi logs (Jilo)'; - $graph[0]['graph_data1_label'] = 'Conferences from Jitsi API (Jilo Agents)'; + switch ($item) { - $graph[1]['data0'] = [ - ['date' => $one, 'value' => 20], - ['date' => $two, 'value' => 30], - ['date' => $three, 'value' => 15], - ['date' => $four, 'value' => 55], - ]; + case 'graphs': + // Connect to Jilo database for log data + $jilo_response = connectDB($config, 'jilo', $platformDetails[0]['jilo_database'], $platform_id); + if ($jilo_response['db'] === null) { + $error = $jilo_response['error']; + include '../app/templates/block-message.php'; + break; + } + $jilo_db = $jilo_response['db']; - $graph[1]['data1'] = [ - ['date' => $one, 'value' => 22], - ['date' => $two, 'value' => 33], - ['date' => $three, 'value' => 11], - ['date' => $four, 'value' => 57], - ]; + // Get date range for the last 7 days + $from_time = date('Y-m-d', strtotime('-7 days')); + $until_time = date('Y-m-d'); - $graph[1]['graph_name'] = 'participants'; - $graph[1]['graph_title'] = 'Participants in "' . htmlspecialchars($platformDetails[0]['name']) . '" over time'; - $graph[1]['graph_data0_label'] = 'Participants from Jitsi logs (Jilo)'; - $graph[1]['graph_data1_label'] = 'Participants from Jitsi API (Jilo Agents)'; - - include '../app/templates/graphs-combined.php'; - break; - - case 'latest': - // Define metrics to display - $metrics = [ - 'Basic stats' => [ - 'conferences' => ['label' => 'Current conferences', 'link' => 'conferences'], - 'participants' => ['label' => 'Current participants', 'link' => 'participants'], - 'total_conferences_created' => ['label' => 'Total conferences created'], - 'total_participants' => ['label' => 'Total participants'] - ], - 'Bridge stats' => [ - 'bridge_selector.bridge_count' => ['label' => 'Bridge count'], - 'bridge_selector.operational_bridge_count' => ['label' => 'Operational bridges'], - 'bridge_selector.in_shutdown_bridge_count' => ['label' => 'Bridges in shutdown'] - ], - 'Jibri stats' => [ - 'jibri_detector.count' => ['label' => 'Jibri count'], - 'jibri_detector.available' => ['label' => 'Jibri idle'], - 'jibri.live_streaming_active' => ['label' => 'Jibri active streaming'], - 'jibri.recording_active' => ['label' => 'Jibri active recording'], - - ], - 'System stats' => [ - 'threads' => ['label' => 'Threads'], - 'stress_level' => ['label' => 'Stress level'], - 'version' => ['label' => 'Version'] - ] - ]; - - // Get latest data for all the agents - $agents = ['jvb', 'jicofo', 'jibri', 'prosody', 'nginx']; - $widget['records'] = []; - - // Initialize records for each agent - foreach ($agents as $agent) { - $record = [ - 'table_headers' => strtoupper($agent), - 'metrics' => [], - 'timestamp' => null + // Define graphs to show + $graphs = [ + [ + 'graph_name' => 'conferences', + 'graph_title' => 'Conferences in "' . htmlspecialchars($platformDetails[0]['name']) . '" over time', + 'datasets' => [] + ], + [ + 'graph_name' => 'participants', + 'graph_title' => 'Participants in "' . htmlspecialchars($platformDetails[0]['name']) . '" over time', + 'datasets' => [] + ] ]; - // Fetch all metrics for this agent - foreach ($metrics as $section => $section_metrics) { - foreach ($section_metrics as $metric => $config) { - $data = $agentObject->getLatestData($platform_id, $agent, $metric); - if ($data !== null) { - $record['metrics'][$section][$metric] = [ - 'value' => $data['value'], - 'label' => $config['label'], - 'link' => isset($config['link']) ? $config['link'] : null - ]; - // Use the most recent timestamp - if ($record['timestamp'] === null || strtotime($data['timestamp']) > strtotime($record['timestamp'])) { - $record['timestamp'] = $data['timestamp']; + // Get Jitsi API data + $conferences_api = $agentObject->getHistoricalData( + $platform_id, + 'jicofo', + 'conferences', + $from_time, + $until_time + ); + $graphs[0]['datasets'][] = [ + 'data' => $conferences_api, + 'label' => 'Conferences from Jitsi API', + 'color' => 'rgba(75, 192, 192, 1)' + ]; + + // Get conference data from logs + $conferences_logs = $conferenceObject->conferenceNumber( + $from_time, + $until_time + ); + $graphs[0]['datasets'][] = [ + 'data' => $conferences_logs, + 'label' => 'Conferences from Logs', + 'color' => 'rgba(255, 99, 132, 1)' + ]; + + // Get participants data + $participants_api = $agentObject->getHistoricalData( + $platform_id, + 'jicofo', + 'participants', + $from_time, + $until_time + ); + $graphs[1]['datasets'][] = [ + 'data' => $participants_api, + 'label' => 'Participants from Jitsi API', + 'color' => 'rgba(75, 192, 192, 1)' + ]; + + // Prepare data for template + $graph = $graphs; + + include '../app/templates/graphs-combined.php'; + break; + + case 'latest': + // Define metrics to display + $metrics = [ + 'Basic stats' => [ + 'conferences' => ['label' => 'Current conferences', 'link' => 'conferences'], + 'participants' => ['label' => 'Current participants', 'link' => 'participants'], + 'total_conferences_created' => ['label' => 'Total conferences created'], + 'total_participants' => ['label' => 'Total participants'] + ], + 'Bridge stats' => [ + 'bridge_selector.bridge_count' => ['label' => 'Bridge count'], + 'bridge_selector.operational_bridge_count' => ['label' => 'Operational bridges'], + 'bridge_selector.in_shutdown_bridge_count' => ['label' => 'Bridges in shutdown'] + ], + 'Jibri stats' => [ + 'jibri_detector.count' => ['label' => 'Jibri count'], + 'jibri_detector.available' => ['label' => 'Jibri idle'], + 'jibri.live_streaming_active' => ['label' => 'Jibri active streaming'], + 'jibri.recording_active' => ['label' => 'Jibri active recording'], + + ], + 'System stats' => [ + 'threads' => ['label' => 'Threads'], + 'stress_level' => ['label' => 'Stress level'], + 'version' => ['label' => 'Version'] + ] + ]; + + // Get latest data for all the agents + $agents = ['jvb', 'jicofo', 'jibri', 'prosody', 'nginx']; + $widget['records'] = []; + + // Initialize records for each agent + foreach ($agents as $agent) { + $record = [ + 'table_headers' => strtoupper($agent), + 'metrics' => [], + 'timestamp' => null + ]; + + // Fetch all metrics for this agent + foreach ($metrics as $section => $section_metrics) { + foreach ($section_metrics as $metric => $config) { + $data = $agentObject->getLatestData($platform_id, $agent, $metric); + if ($data !== null) { + $record['metrics'][$section][$metric] = [ + 'value' => $data['value'], + 'label' => $config['label'], + 'link' => isset($config['link']) ? $config['link'] : null + ]; + // Use the most recent timestamp + if ($record['timestamp'] === null || strtotime($data['timestamp']) > strtotime($record['timestamp'])) { + $record['timestamp'] = $data['timestamp']; + } } } } + + if (!empty($record['metrics'])) { + $widget['records'][] = $record; + } } - if (!empty($record['metrics'])) { - $widget['records'][] = $record; + // prepare the widget + $widget['full'] = false; + $widget['name'] = 'LatestData'; + $widget['title'] = 'Latest data from Jilo Agents'; + $widget['collapsible'] = false; + $widget['collapsed'] = false; + $widget['filter'] = false; + $widget['metrics'] = $metrics; // Pass metrics configuration to template + if (!empty($widget['records'])) { + $widget['full'] = true; } - } + $widget['pagination'] = false; - // prepare the widget - $widget['full'] = false; - $widget['name'] = 'LatestData'; - $widget['title'] = 'Latest data from Jilo Agents'; - $widget['collapsible'] = false; - $widget['collapsed'] = false; - $widget['filter'] = false; - $widget['metrics'] = $metrics; // Pass metrics configuration to template - if (!empty($widget['records'])) { - $widget['full'] = true; - } - $widget['pagination'] = false; + include '../app/templates/latest-data.php'; + break; - include '../app/templates/latest-data.php'; - break; + case 'configjs': + $mode = $_REQUEST['mode'] ?? ''; + $raw = ($mode === 'raw'); + $platformConfigjs = $configObject->getPlatformConfigjs($platformDetails[0]['jitsi_url'], $raw); + include '../app/templates/data-configjs.php'; + break; - case 'configjs': - $mode = $_REQUEST['mode'] ?? ''; - $raw = ($mode === 'raw'); - $platformConfigjs = $configObject->getPlatformConfigjs($platformDetails[0]['jitsi_url'], $raw); - include '../app/templates/data-configjs.php'; - break; + case 'interfaceconfigjs': + $mode = $_REQUEST['mode'] ?? ''; + $raw = ($mode === 'raw'); + $platformInterfaceConfigjs = $configObject->getPlatformInterfaceConfigjs($platformDetails[0]['jitsi_url'], $raw); + include '../app/templates/data-interfaceconfigjs.php'; + break; - case 'interfaceconfigjs': - $mode = $_REQUEST['mode'] ?? ''; - $raw = ($mode === 'raw'); - $platformInterfaceConfigjs = $configObject->getPlatformInterfaceConfigjs($platformDetails[0]['jitsi_url'], $raw); - include '../app/templates/data-interfaceconfigjs.php'; - break; + default: + } - default: } ?>