diff --git a/LibreNMS/Util/Time.php b/LibreNMS/Util/Time.php index f8c524dc43..43d271acf8 100644 --- a/LibreNMS/Util/Time.php +++ b/LibreNMS/Util/Time.php @@ -48,4 +48,35 @@ class Time return isset($conversion[$description]) ? $conversion[$description] : 0; } + + public static function formatInterval($interval, $format = 'long') + { + $result = ''; + $data = [ + 'years' => 31536000, + 'days' => 86400, + 'hours' => 3600, + 'minutes' => 60, + 'seconds' => 1, + ]; + + foreach ($data as $k => $v) { + if ($interval >= $v) { + $diff = floor($interval / $v); + + $result .= " $diff"; + if ($format == 'short') { + $result .= substr($k, 0, 1); + } elseif ($diff > 1) { + $result .= ' ' . $k; + } else { + $result .= substr($k, 0, -1); + } + + $interval -= $v * $diff; + } + } + + return $result; + } } diff --git a/app/Http/Controllers/Table/DeviceController.php b/app/Http/Controllers/Table/DeviceController.php index e4effdae9a..7a108ea535 100644 --- a/app/Http/Controllers/Table/DeviceController.php +++ b/app/Http/Controllers/Table/DeviceController.php @@ -31,6 +31,7 @@ use Illuminate\Database\Eloquent\Builder; use LibreNMS\Config; use LibreNMS\Util\Rewrite; use LibreNMS\Util\Url; +use LibreNMS\Util\Time; class DeviceController extends TableController { @@ -125,7 +126,7 @@ class DeviceController extends TableController 'metrics' => $this->getMetrics($device), 'hardware' => Rewrite::ciscoHardware($device), 'os' => $this->getOsText($device), - 'uptime' => $device->formatUptime(true), + 'uptime' => Time::formatInterval($device->status ? $device->uptime : $device->last_polled->diffInSeconds(), 'short'), 'location' => $this->getLocation($device), 'actions' => $this->getActions($device), ]; diff --git a/app/Models/Device.php b/app/Models/Device.php index e433a8aa63..9fb93647a9 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -13,6 +13,7 @@ use LibreNMS\Util\IP; use LibreNMS\Util\IPv4; use LibreNMS\Util\IPv6; use LibreNMS\Util\Url; +use LibreNMS\Util\Time; class Device extends BaseModel { @@ -21,7 +22,10 @@ class Device extends BaseModel public $timestamps = false; protected $primaryKey = 'device_id'; protected $fillable = ['hostname', 'ip', 'status', 'status_reason']; - protected $casts = ['status' => 'boolean']; + protected $casts = [ + 'last_polled' => 'datetime', + 'status' => 'boolean', + ]; /** * Initialize this class @@ -253,34 +257,7 @@ class Device extends BaseModel public function formatUptime($short = false) { - $result = ''; - $interval = $this->uptime; - $data = [ - 'years' => 31536000, - 'days' => 86400, - 'hours' => 3600, - 'minutes' => 60, - 'seconds' => 1, - ]; - - foreach ($data as $k => $v) { - if ($interval >= $v) { - $diff = floor($interval / $v); - - $result .= " $diff"; - if ($short) { - $result .= substr($k, 0, 1); - } elseif ($diff > 1) { - $result .= $k; - } else { - $result .= substr($k, 0, -1); - } - - $interval -= $v * $diff; - } - } - - return $result; + return Time::formatInterval($this->uptime, $short); } /** diff --git a/html/includes/dev-overview-data.inc.php b/html/includes/dev-overview-data.inc.php index fdcae0615a..91a6e515d8 100644 --- a/html/includes/dev-overview-data.inc.php +++ b/html/includes/dev-overview-data.inc.php @@ -1,9 +1,11 @@
@@ -21,13 +23,8 @@ echo '
'; echo ''; echo ''; -$uptime = formatUptime($device['uptime']); -$uptime_text = 'Uptime'; -if ($device['status'] == 0) { - // Rewrite $uptime to be downtime if device is down - $uptime = formatUptime(time() - strtotime($device['last_polled'])); - $uptime_text = 'Downtime'; -} +$uptime = (Time::formatInterval($device['status'] ? $device['uptime'] : time() - strtotime($device['last_polled']))); +$uptime_text = ($device['status'] ? 'Uptime' : 'Downtime'); if ($device['os'] == 'ios') { formatCiscoHardware($device); diff --git a/html/pages/devices.inc.php b/html/pages/devices.inc.php index c504293384..5ab815f0f8 100644 --- a/html/pages/devices.inc.php +++ b/html/pages/devices.inc.php @@ -291,7 +291,7 @@ if ($format == "graph") { Metrics Platform Operating System - Uptime + Up/Down Time Location Actions @@ -314,6 +314,13 @@ if ($format == "graph") { "device": function (column, row) { return "" + row.hostname + ""; }, + "uptime": function (column, row) { + if (row.status == 'down') { + return "" + row.uptime + ""; + } else { + return "" + row.uptime + ""; + } + }, }, templates: { header: "

" diff --git a/includes/alerts.inc.php b/includes/alerts.inc.php index e794807409..0a38ba04ea 100644 --- a/includes/alerts.inc.php +++ b/includes/alerts.inc.php @@ -30,6 +30,7 @@ use LibreNMS\Authentication\LegacyAuth; use LibreNMS\Alert\AlertUtil; use LibreNMS\Config; use PHPMailer\PHPMailer\PHPMailer; +use LibreNMS\Util\Time; /** * @param $rule @@ -411,8 +412,8 @@ function DescribeAlert($alert) $obj['version'] = $device['version']; $obj['location'] = $device['location']; $obj['uptime'] = $device['uptime']; - $obj['uptime_short'] = formatUptime($device['uptime'], 'short'); - $obj['uptime_long'] = formatUptime($device['uptime']); + $obj['uptime_short'] = Time::formatInterval($device['uptime'], 'short'); + $obj['uptime_long'] = Time::formatInterval($device['uptime']); $obj['description'] = $device['purpose']; $obj['notes'] = $device['notes']; $obj['alert_notes'] = $alert['note']; diff --git a/includes/functions.php b/includes/functions.php index c50f19be06..a8efaa443f 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -26,6 +26,7 @@ use LibreNMS\Util\IPv6; use LibreNMS\Util\MemcacheLock; use Symfony\Component\Process\Process; use PHPMailer\PHPMailer\PHPMailer; +use LibreNMS\Util\Time; if (!function_exists('set_debug')) { /** @@ -617,54 +618,10 @@ function deviceArray($host, $community, $snmpver, $port = 161, $transport = 'udp return $device; } + function formatUptime($diff, $format = "long") { - $yearsDiff = floor($diff/31536000); - $diff -= $yearsDiff*31536000; - $daysDiff = floor($diff/86400); - $diff -= $daysDiff*86400; - $hrsDiff = floor($diff/60/60); - $diff -= $hrsDiff*60*60; - $minsDiff = floor($diff/60); - $diff -= $minsDiff*60; - $secsDiff = $diff; - - $uptime = ""; - - if ($format == "short") { - if ($yearsDiff > '0') { - $uptime .= $yearsDiff . "y "; - } - if ($daysDiff > '0') { - $uptime .= $daysDiff . "d "; - } - if ($hrsDiff > '0') { - $uptime .= $hrsDiff . "h "; - } - if ($minsDiff > '0') { - $uptime .= $minsDiff . "m "; - } - if ($secsDiff > '0') { - $uptime .= $secsDiff . "s "; - } - } else { - if ($yearsDiff > '0') { - $uptime .= $yearsDiff . " years, "; - } - if ($daysDiff > '0') { - $uptime .= $daysDiff . " day" . ($daysDiff != 1 ? 's' : '') . ", "; - } - if ($hrsDiff > '0') { - $uptime .= $hrsDiff . "h "; - } - if ($minsDiff > '0') { - $uptime .= $minsDiff . "m "; - } - if ($secsDiff > '0') { - $uptime .= $secsDiff . "s "; - } - } - return trim($uptime); + return Time::formatInterval($diff, $format); } function isSNMPable($device) diff --git a/includes/polling/core.inc.php b/includes/polling/core.inc.php index 4debe68933..fe9698afc4 100644 --- a/includes/polling/core.inc.php +++ b/includes/polling/core.inc.php @@ -14,6 +14,7 @@ use App\Models\Location; use LibreNMS\Config; use LibreNMS\RRD\RrdDefinition; +use LibreNMS\Util\Time; $snmpdata = snmp_get_multi_oid($device, ['sysUpTime.0', 'sysLocation.0', 'sysContact.0', 'sysName.0', 'sysObjectID.0', 'sysDescr.0'], '-OQnUt', 'SNMPv2-MIB'); @@ -41,7 +42,7 @@ if (!empty($agent_data['uptime'])) { if ($uptime != 0 && $config['os'][$device['os']]['bad_uptime'] !== true) { if ($uptime < $device['uptime']) { - log_event('Device rebooted after ' . formatUptime($device['uptime']) . " -> {$uptime}s", $device, 'reboot', 4, $device['uptime']); + log_event('Device rebooted after ' . Time::formatInterval($device['uptime']) . " -> {$uptime}s", $device, 'reboot', 4, $device['uptime']); } $tags = array( @@ -51,7 +52,7 @@ if ($uptime != 0 && $config['os'][$device['os']]['bad_uptime'] !== true) { $graphs['uptime'] = true; - echo 'Uptime: ' . formatUptime($uptime) . PHP_EOL; + echo 'Uptime: ' . Time::formatInterval($uptime) . PHP_EOL; $update_array['uptime'] = $uptime; $device['uptime'] = $uptime;