From f176f424b5a6cb44df4426bd4b2d817568db2073 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 6 Jun 2026 09:33:16 -0500 Subject: [PATCH] feat: monitor plugin sends heartbeat to MokoWaaSBase REST API Replace ad-hoc Grafana receiver with MokoWaaSBase API integration. The heartbeat now posts to /api/index.php/v1/mokowaasbase/heartbeat with token, domain, site_name, versions. Configurable base URL (defaults to mokoconsulting.tech). Removed hardcoded HEARTBEAT_URL and HEARTBEAT_KEY constants. Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- .../en-GB/plg_system_mokowaas_monitor.ini | 10 +- .../mokowaas_monitor.xml | 8 ++ .../src/Extension/Monitor.php | 104 +++++++++++++----- 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/source/packages/plg_system_mokowaas_monitor/language/en-GB/plg_system_mokowaas_monitor.ini b/source/packages/plg_system_mokowaas_monitor/language/en-GB/plg_system_mokowaas_monitor.ini index 62115221..9be4380c 100644 --- a/source/packages/plg_system_mokowaas_monitor/language/en-GB/plg_system_mokowaas_monitor.ini +++ b/source/packages/plg_system_mokowaas_monitor/language/en-GB/plg_system_mokowaas_monitor.ini @@ -3,9 +3,11 @@ ; License: GPL-3.0-or-later PLG_SYSTEM_MOKOWAAS_MONITOR="System - MokoWaaS Monitor" -PLG_SYSTEM_MOKOWAAS_MONITOR_DESC="Site health monitoring, Grafana heartbeat integration, and diagnostics." +PLG_SYSTEM_MOKOWAAS_MONITOR_DESC="Sends heartbeat data to a MokoWaaSBase control panel for centralized site monitoring." PLG_SYSTEM_MOKOWAAS_MONITOR_FIELDSET_BASIC="Monitoring" -PLG_SYSTEM_MOKOWAAS_MONITOR_FIELDSET_BASIC_DESC="Configure health monitoring and heartbeat settings." -PLG_SYSTEM_MOKOWAAS_MONITOR_HEARTBEAT_LABEL="Grafana Heartbeat" -PLG_SYSTEM_MOKOWAAS_MONITOR_HEARTBEAT_DESC="Send heartbeat registration to the Grafana monitoring receiver when plugin settings are saved." +PLG_SYSTEM_MOKOWAAS_MONITOR_FIELDSET_BASIC_DESC="Configure heartbeat reporting to MokoWaaSBase." +PLG_SYSTEM_MOKOWAAS_MONITOR_HEARTBEAT_LABEL="Send Heartbeat" +PLG_SYSTEM_MOKOWAAS_MONITOR_HEARTBEAT_DESC="Send heartbeat data to MokoWaaSBase when plugin settings are saved." +PLG_SYSTEM_MOKOWAAS_MONITOR_BASE_URL_LABEL="MokoWaaSBase URL" +PLG_SYSTEM_MOKOWAAS_MONITOR_BASE_URL_DESC="URL of the MokoWaaSBase control panel (e.g. https://mokoconsulting.tech). The heartbeat is sent to /api/index.php/v1/mokowaasbase/heartbeat on this host." diff --git a/source/packages/plg_system_mokowaas_monitor/mokowaas_monitor.xml b/source/packages/plg_system_mokowaas_monitor/mokowaas_monitor.xml index 328563aa..38a213d1 100644 --- a/source/packages/plg_system_mokowaas_monitor/mokowaas_monitor.xml +++ b/source/packages/plg_system_mokowaas_monitor/mokowaas_monitor.xml @@ -36,6 +36,14 @@ + + diff --git a/source/packages/plg_system_mokowaas_monitor/src/Extension/Monitor.php b/source/packages/plg_system_mokowaas_monitor/src/Extension/Monitor.php index af199793..750da3a7 100644 --- a/source/packages/plg_system_mokowaas_monitor/src/Extension/Monitor.php +++ b/source/packages/plg_system_mokowaas_monitor/src/Extension/Monitor.php @@ -14,15 +14,16 @@ use Joomla\CMS\Factory; use Joomla\CMS\Log\Log; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Uri\Uri; +use Joomla\CMS\Version; use Joomla\Event\SubscriberInterface; use Moko\Plugin\System\MokoWaaS\Helper\MokoWaaSHelper; /** * MokoWaaS Health Monitor Plugin * - * Provides Grafana heartbeat integration and site health diagnostics. - * The detailed 14-check health endpoint remains in the core plugin's API - * for now; this plugin handles the proactive monitoring side. + * Sends heartbeat data to a MokoWaaSBase control panel instance. + * The heartbeat includes site identity, version info, and optionally + * the full health check payload from the core plugin. * * @since 02.32.00 */ @@ -30,9 +31,6 @@ class Monitor extends CMSPlugin implements SubscriberInterface { protected $autoloadLanguage = true; - private const HEARTBEAT_URL = 'https://bench.mokoconsulting.tech/api/waas-heartbeat'; - private const HEARTBEAT_KEY = 'moko-waas-hb-2026-x9k4m'; - public static function getSubscribedEvents(): array { return [ @@ -79,10 +77,20 @@ class Monitor extends CMSPlugin implements SubscriberInterface } /** - * Send heartbeat registration to the Grafana monitoring receiver. + * Send heartbeat to the MokoWaaSBase control panel. + * + * Posts site identity and version info to the MokoWaaSBase REST API. + * The control panel looks up the site by domain and verifies the token. */ private function sendHeartbeat(): void { + $baseUrl = rtrim($this->params->get('base_url', ''), '/'); + + if (empty($baseUrl)) + { + return; + } + $coreParams = MokoWaaSHelper::getCoreParams(); $healthToken = $coreParams->get('health_api_token', ''); @@ -91,28 +99,39 @@ class Monitor extends CMSPlugin implements SubscriberInterface return; } - $app = $this->getApplication(); - $siteUrl = rtrim(Uri::root(), '/'); - $siteName = Factory::getConfig()->get('sitename', 'Joomla'); + $siteUrl = rtrim(Uri::root(), '/'); + $domain = parse_url($siteUrl, PHP_URL_HOST) ?: ''; - $payload = json_encode([ - 'site_url' => $siteUrl, - 'site_name' => $siteName, - 'health_token' => $healthToken, - 'action' => 'register', - ], JSON_UNESCAPED_SLASHES); + if (empty($domain)) + { + return; + } - $ch = curl_init(self::HEARTBEAT_URL . '/register'); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Content-Type: application/json', - 'X-MokoWaaS-Key: ' . self::HEARTBEAT_KEY, + $app = $this->getApplication(); + + $payload = [ + 'token' => $healthToken, + 'domain' => $domain, + 'site_name' => Factory::getConfig()->get('sitename', 'Joomla'), + 'site_url' => $siteUrl, + 'joomla_version' => (new Version())->getShortVersion(), + 'php_version' => PHP_VERSION, + 'mokowaas_version' => $this->getMokoWaaSVersion(), + ]; + + $endpoint = $baseUrl . '/api/index.php/v1/mokowaasbase/heartbeat'; + $json = json_encode($payload, JSON_UNESCAPED_SLASHES); + + $ch = curl_init($endpoint); + curl_setopt_array($ch, [ + CURLOPT_POST => true, + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + CURLOPT_POSTFIELDS => $json, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 15, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_SSL_VERIFYPEER => false, ]); - curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 15); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); @@ -123,11 +142,11 @@ class Monitor extends CMSPlugin implements SubscriberInterface { Log::add('Monitor heartbeat failed: ' . $error, Log::WARNING, 'mokowaas'); } - elseif ($code === 200) + elseif ($code >= 200 && $code < 300) { $body = json_decode($response, true); $app->enqueueMessage( - 'Grafana heartbeat: ' . ($body['status'] ?? 'ok'), + 'MokoWaaSBase heartbeat: ' . ($body['status'] ?? 'ok'), 'message' ); } @@ -139,6 +158,35 @@ class Monitor extends CMSPlugin implements SubscriberInterface Log::WARNING, 'mokowaas' ); + $app->enqueueMessage( + 'MokoWaaSBase heartbeat failed (HTTP ' . $code . ')', + 'warning' + ); + } + } + + /** + * Get the installed MokoWaaS package version. + */ + private function getMokoWaaSVersion(): string + { + try + { + $db = Factory::getDbo(); + $db->setQuery( + $db->getQuery(true) + ->select($db->quoteName('manifest_cache')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote('pkg_mokowaas')) + ->where($db->quoteName('type') . ' = ' . $db->quote('package')) + ); + $mc = json_decode($db->loadResult() ?? '{}'); + + return $mc->version ?? ''; + } + catch (\Throwable $e) + { + return ''; } } }