diff --git a/Linear Gauge Dashlet/linear_gauge.zip b/Linear Gauge Dashlet/linear_gauge.zip new file mode 100644 index 0000000..af4aebc Binary files /dev/null and b/Linear Gauge Dashlet/linear_gauge.zip differ diff --git a/Linear Gauge Dashlet/linear_gauge/gaugeshelper.php b/Linear Gauge Dashlet/linear_gauge/gaugeshelper.php new file mode 100644 index 0000000..5225637 --- /dev/null +++ b/Linear Gauge Dashlet/linear_gauge/gaugeshelper.php @@ -0,0 +1,245 @@ + 0) + return true; + return false; + } +} + + +/** + * @return mixed|string + */ +if(!function_exists('get_gauge_json')) { + function get_gauge_json() + { + $host = grab_request_var('host', ''); + $service = grab_request_var('service', ''); + $ds = grab_request_var('ds'); + + if (empty($host) || empty($service) || empty($ds)) { + return json_encode(get_datasources($host, $service, $ds)); + } + + $result = get_datasources($host, $service, $ds); + foreach ($result as $services) + foreach ($services as $service) + foreach ($service as $ds) + return json_encode($ds); + } +} + +if(!function_exists('gauges_get_host_services')) { + function gauges_get_host_services() + { + $host = grab_request_var('host', ''); + + $backendargs = array( + 'orderby' => "host_name:a,service_description:a", + 'brevity' => 4); + + if (!empty($host)) { + $services = array(); + $backendargs['host_name'] = $host; + $objs = get_xml_service_status($backendargs); + foreach ($objs->servicestatus as $o) { + $services[] = strval($o->name); + } + return json_encode($services); + } else { + $hosts = array(); + $objs = get_xml_host_status($backendargs); + foreach ($objs->hoststatus as $o) { + $hosts[] = strval($o->name); + } + return json_encode($hosts); + } + } +} + +/** + * @param null $host + * @param null $service + * @param null $ds + * + * @return array + */ +if(!function_exists('get_datasources')) { + function get_datasources($host = null, $service = null, $ds = null) + { + $result = array(); + $backendargs = array(); + + $backendargs["orderby"] = "host_name:a,service_description:a"; + if ($host) + $backendargs["host_name"] = $host; + if ($service) + $backendargs["service_description"] = $service; // service + + $services = get_xml_service_status($backendargs); + $hosts = get_xml_host_status($backendargs); + + foreach ($services->servicestatus as $status) { + $status = (array)$status; + $result[$status['host_name']][$status['name']] = get_gauge_datasource($status, $ds); + if (empty($result[$status['host_name']])) + unset($result[$status['host_name']]); + } + if (empty($service) || $service == '_HOST_') + foreach ($hosts->hoststatus as $status) { + $status = (array)$status; + $result[$status['name']]['_HOST_'] = get_gauge_datasource($status, $ds); + if (empty($result[$status['name']])) + unset($result[$status['name']]); + } + + return $result; + } +} + +/** + * @param $status + * @param $ds_label + * + * @return array + */ +if(!function_exists('get_gauge_datasource')) { + function get_gauge_datasource($status, $ds_label) + { + $ds = array(); + + if (empty($status['performance_data'])) { + return ''; + } + + $perfdata_datasources = str_getcsv($status['performance_data'], " ", "'"); + foreach ($perfdata_datasources as $perfdata_datasource) { + + $perfdata_s = explode('=', $perfdata_datasource); + $perfdata_name = trim(str_replace("apos;", "", $perfdata_s[0])); + + // Strip bad char from key name and label (REMOVED for pnp convert function -JO) + //$perfdata_name = str_replace('\\', '', $perfdata_name); + //$perfdata_name = str_replace(' ', '_', $perfdata_name); + $perfdata_name = pnp_convert_object_name($perfdata_name); + if ($ds_label && $perfdata_name != $ds_label && $perfdata_name != pnp_convert_object_name($ds_label)) + continue; + if (!isset($perfdata_s[1])) + continue; + + //test=13; "test helo"=3; + + $perfdata = explode(';', $perfdata_s[1]); + $current = preg_replace("/[^0-9.]/", "", grab_array_var($perfdata, 0, 0)); + + $ds[$perfdata_name]['label'] = $perfdata_name; + $ds[$perfdata_name]['current'] = round(floatval($current), 3); + $ds[$perfdata_name]['uom'] = str_replace($current, '', $perfdata[0]); + $ds[$perfdata_name]['warn'] = grab_array_var($perfdata, 1, 0); + $ds[$perfdata_name]['crit'] = grab_array_var($perfdata, 2, 0); + $ds[$perfdata_name]['min'] = floatval(grab_array_var($perfdata, 3, "0")); + $ds[$perfdata_name]['max'] = floatval(grab_array_var($perfdata, 4, "0")); + + // Do some guessing if max is not set + if ($ds[$perfdata_name]['max'] == 0) { + if ($ds[$perfdata_name]['crit'] != 0 && $ds[$perfdata_name]['crit'] > 0) { + $ds[$perfdata_name]['max'] = $ds[$perfdata_name]['crit'] * 1.1; + } else if ($ds[$perfdata_name]['uom'] == '%') { + $ds[$perfdata_name]['max'] = 100; + } + } + + // Do some rounding + $ds[$perfdata_name]['max'] = round($ds[$perfdata_name]['max'], 1); + + // Remove the item if we were not able to determine the max + if ($ds[$perfdata_name]['max'] == 0) { + $ds[$perfdata_name]['max'] = 100; + } + + // add yellowZones & redZones + if (!empty($ds[$perfdata_name]['warn'])) { + if (strpos($ds[$perfdata_name]['warn'], ":") !== false) { + // We are doing a range warning threshold + list($end, $start) = explode(":", $ds[$perfdata_name]['warn']); + $ds[$perfdata_name]['yellowZones'] = array( + array( + "from" => floatval($start), + "to" => floatval($end) + ) + ); + } else { + // Standard warning threshold + $ds[$perfdata_name]['yellowZones'] = array( + array( + "from" => floatval($ds[$perfdata_name]['warn']), + "to" => ($ds[$perfdata_name]['crit'] != 0) ? floatval($ds[$perfdata_name]['crit']) : $ds[$perfdata_name]['max'], + ) + ); + } + } + + if (!empty($ds[$perfdata_name]['crit'])) { + if (strpos($ds[$perfdata_name]['crit'], ":") !== false) { + // We are doing a range warning threshold + list($end, $start) = explode(":", $ds[$perfdata_name]['crit']); + $ds[$perfdata_name]['redZones'] = array( + array( + "from" => floatval($start), + "to" => floatval($end) + ) + ); + } else { + // Standard critical threshold + $ds[$perfdata_name]['redZones'] = array( + array( + "from" => floatval($ds[$perfdata_name]['crit']), + "to" => $ds[$perfdata_name]['max'], + ) + ); + } + } + } + + return $ds; + } +} + +if (!function_exists('str_getcsv')) { + + /** + * @param $input + * @param string $delimiter + * @param string $enclosure + * @param null $escape + * @param null $eol + * + * @return array + */ + function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = null, $eol = null) + { + $temp = fopen("php://memory", "rw"); + fwrite($temp, $input); + fseek($temp, 0); + $r = array(); + while (($data = fgetcsv($temp, 4096, $delimiter, $enclosure)) !== false) { + $r[] = $data; + } + fclose($temp); + return $r; + } +} + +?> \ No newline at end of file diff --git a/Linear Gauge Dashlet/linear_gauge/getdata.php b/Linear Gauge Dashlet/linear_gauge/getdata.php new file mode 100644 index 0000000..2ce9373 --- /dev/null +++ b/Linear Gauge Dashlet/linear_gauge/getdata.php @@ -0,0 +1,36 @@ + $name, + DASHLET_VERSION => "1.0.1", + DASHLET_DATE => "1/27/2025", + DASHLET_AUTHOR => "Nagios Enterprises, LLC", + DASHLET_DESCRIPTION => _("Linear Gauge Dashlet."), + DASHLET_COPYRIGHT => "Copyright (c) 2010-2023 Nagios Enterprises, LLC", + DASHLET_LICENSE => "BSD", + DASHLET_HOMEPAGE => "https://www.nagios.com", + DASHLET_REFRESHRATE => 60, + DASHLET_FUNCTION => "linear_gauge_func", + DASHLET_TITLE => _("Linear Gauge Dashlet"), + DASHLET_OUTBOARD_CLASS=> "linear_gauge_outboardclass", + DASHLET_INBOARD_CLASS => "linear_gauge_inboardclass", + DASHLET_PREVIEW_CLASS => "linear_gauge_previewclass", + DASHLET_JS_FILE => "linear_gauge.js", + DASHLET_WIDTH => "300", + DASHLET_HEIGHT => "250", + DASHLET_OPACITY => "1.0" + ); + + register_dashlet($name, $args); +} + + +function linear_gauge_func($mode=DASHLET_MODE_PREVIEW, $id="", $args=null) +{ + $output = ""; + + switch ($mode) { + + case DASHLET_MODE_GETCONFIGHTML: + //input form for dashlet vars + if ($args == null) { + $output = ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + } + break; + + case DASHLET_MODE_OUTBOARD: + case DASHLET_MODE_INBOARD: + + $output = ""; + if (empty($args['ds'])) { + $output .= "ERROR: Missing Arguments"; + break; + } + + // Random dashlet id + $rand = rand(); + + $n = 0; + $ajaxargs = "{"; + foreach ($args as $idx => $val) { + if ($n > 0) + $ajaxargs .= ", "; + $ajaxargs .= "\"$idx\" : \"$val\""; + $n++; + } + $ajaxargs .= "}"; + + $host = grab_array_var($args, "host", ""); + $service = urldecode(grab_array_var($args, "service", "")); + $ds = grab_array_var($args, "ds", ""); + + // HTML output (heredoc string syntax) + ob_start(); + insert_linear_gauge_html($rand); + ?> + + "; + } else if (get_theme() == "neptunelight") { + $output="No Preview Available"; + } else { + $output="No Preview Available"; + } + break; + } + + return $output; +} + +function insert_linear_gauge_html($id) { + ?> +
+
+

Service Name

+

0

+
+
+ + + + + + + +
+
+ Critical + Warning + OK +
+
+
+ + + { + setval(`#dashlet-${id}`, args['current'], args['warn'], args['crit'], args['max'], args['uom']); + }); + resizeObserver.observe(gaugeContainer); + } +} + +function setval(id, num, warn, crit, max, unit) { + console.log("setvalhelper called with:", id, num, warn, crit, max, unit); + + const gaugedashlet = document.querySelector(id); + if (!gaugedashlet) { + console.error(`Gauge dashlet with id "${id}" not found.`); + return; + } + + const gaugeContainer = gaugedashlet.querySelector('.gauge-container'); + const gaugePointer = gaugedashlet.querySelector('.gauge-pointer'); + const gaugeWidth = gaugeContainer.clientWidth; + + // Ensure proper range values for warn and crit + if (parseInt(warn) > parseInt(crit)) { + [warn, crit] = [crit, warn]; // Swap values + } + + // Update text and unit + const valueElement = gaugedashlet.querySelector('.gaugetext p'); + const span = valueElement.querySelector('span'); + if (span) { + span.innerHTML = unit; // Update the unit + } else { + // If span doesn't exist, create it + const newSpan = document.createElement('span'); + newSpan.innerHTML = unit; + valueElement.appendChild(newSpan); + } + + valueElement.innerHTML = `${num}${unit}`; + valueElement.style.fontSize = `${2.5 - 0.25 * Math.max(0, num.toString().length - 4)}em`; + + + // Calculate pointer position + let pointerPosition; + + if (num >= crit) { + // Critical zone (rightmost third of the gauge) + pointerPosition = (0.33 / 2) * gaugeWidth; // Middle of the critical zone + + } else if (num >= warn) { + // Warning zone (middle third of the gauge) + pointerPosition = (0.66 / 2 + 0.33) * gaugeWidth; // Middle of the warning zone + + } else { + // OK zone (leftmost third of the gauge) + pointerPosition = (0.34 / 2 + 0.66) * gaugeWidth; // Middle of the ok zone + } + + console.log(gaugeWidth); + // Ensure the pointer stays within the bounds of the gauge + const pointerWidth = 20; // Width of the pointer + const maxPointerPosition = gaugeWidth - pointerWidth / 2; + const minPointerPosition = pointerWidth / 2; + const clampedPointerPosition = Math.max(minPointerPosition, Math.min(maxPointerPosition, pointerPosition)); + + // Update the pointer position + gaugePointer.style.left = `${clampedPointerPosition}px`; + + // Dim non-active zones + const criticalZone = gaugedashlet.querySelector('.gauge-section.critical'); + const warningZone = gaugedashlet.querySelector('.gauge-section.warning'); + const okZone = gaugedashlet.querySelector('.gauge-section.ok'); + + if (num >= crit) { + // Highlight critical zone, dim others + criticalZone.classList.remove('dimmed'); + warningZone.classList.add('dimmed'); + okZone.classList.add('dimmed'); + } else if (num >= warn) { + // Highlight warning zone, dim others + criticalZone.classList.add('dimmed'); + warningZone.classList.remove('dimmed'); + okZone.classList.add('dimmed'); + } else { + // Highlight OK zone, dim others + criticalZone.classList.add('dimmed'); + warningZone.classList.add('dimmed'); + okZone.classList.remove('dimmed'); + } + + +} diff --git a/Linear Gauge Dashlet/linear_gauge/linear_gauge1.png b/Linear Gauge Dashlet/linear_gauge/linear_gauge1.png new file mode 100644 index 0000000..341c7df Binary files /dev/null and b/Linear Gauge Dashlet/linear_gauge/linear_gauge1.png differ diff --git a/Linear Gauge Dashlet/linear_gauge/linear_gauge_neptune_light_preview1.png b/Linear Gauge Dashlet/linear_gauge/linear_gauge_neptune_light_preview1.png new file mode 100644 index 0000000..b72cddd Binary files /dev/null and b/Linear Gauge Dashlet/linear_gauge/linear_gauge_neptune_light_preview1.png differ diff --git a/Linear Gauge Dashlet/linear_gauge/neptune_preview1.png b/Linear Gauge Dashlet/linear_gauge/neptune_preview1.png new file mode 100644 index 0000000..341c7df Binary files /dev/null and b/Linear Gauge Dashlet/linear_gauge/neptune_preview1.png differ