mirror of
https://github.com/librenms/librenms.git
synced 2024-09-21 10:28:13 +00:00
Use Measurements for all statistic collection (#13333)
* Use Measurements for all statistic collection * fix space * Use colors cleanup * fix style * manually fix license notice * add return times and new line * add return times and new line * fix mistake in copyright template * fix style
This commit is contained in:
parent
f28802bb2b
commit
8d5bc3fc41
@ -26,6 +26,7 @@
|
|||||||
namespace LibreNMS\Data\Source;
|
namespace LibreNMS\Data\Source;
|
||||||
|
|
||||||
use App\Models\Device;
|
use App\Models\Device;
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use DeviceCache;
|
use DeviceCache;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@ -215,15 +216,6 @@ class SnmpQuery
|
|||||||
return $this->exec('snmptranslate', $this->parseOid($oid));
|
return $this->exec('snmptranslate', $this->parseOid($oid));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function recordStatistic(string $type, float $start_time): void
|
|
||||||
{
|
|
||||||
global $snmp_stats;
|
|
||||||
|
|
||||||
$runtime = microtime(true) - $start_time;
|
|
||||||
$snmp_stats['ops'][$type] = isset($snmp_stats['ops'][$type]) ? $snmp_stats['ops'][$type] + 1 : 0;
|
|
||||||
$snmp_stats['time'][$type] = isset($snmp_stats['time'][$type]) ? $snmp_stats['time'][$type] + $runtime : $runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildCli(string $command, array $oids): array
|
private function buildCli(string $command, array $oids): array
|
||||||
{
|
{
|
||||||
$cmd = $this->initCommand($command);
|
$cmd = $this->initCommand($command);
|
||||||
@ -285,7 +277,7 @@ class SnmpQuery
|
|||||||
|
|
||||||
private function exec(string $command, array $oids): SnmpResponse
|
private function exec(string $command, array $oids): SnmpResponse
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start($command);
|
||||||
|
|
||||||
$proc = new Process($this->buildCli($command, $oids));
|
$proc = new Process($this->buildCli($command, $oids));
|
||||||
$proc->setTimeout(Config::get('snmp.exec_timeout', 1200));
|
$proc->setTimeout(Config::get('snmp.exec_timeout', 1200));
|
||||||
@ -301,7 +293,7 @@ class SnmpQuery
|
|||||||
$this->checkExitCode($exitCode, $stderr);
|
$this->checkExitCode($exitCode, $stderr);
|
||||||
$this->logOutput($output, $stderr);
|
$this->logOutput($output, $stderr);
|
||||||
|
|
||||||
$this->recordStatistic($command, $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
|
|
||||||
return new SnmpResponse($output, $stderr, $exitCode);
|
return new SnmpResponse($output, $stderr, $exitCode);
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
use LibreNMS\Data\Measure\Measurement;
|
use App\Polling\Measure\Measurement;
|
||||||
use LibreNMS\Data\Measure\MeasurementCollection;
|
use App\Polling\Measure\MeasurementCollection;
|
||||||
use LibreNMS\Interfaces\Data\Datastore as DatastoreContract;
|
use LibreNMS\Interfaces\Data\Datastore as DatastoreContract;
|
||||||
|
|
||||||
abstract class BaseDatastore implements DatastoreContract
|
abstract class BaseDatastore implements DatastoreContract
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Interfaces\Data\Datastore as DatastoreContract;
|
use LibreNMS\Interfaces\Data\Datastore as DatastoreContract;
|
||||||
|
|
||||||
@ -151,12 +152,15 @@ class Datastore
|
|||||||
return $this->stores;
|
return $this->stores;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStats()
|
/**
|
||||||
|
* Get the measurements for all datastores, keyed by datastore name
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection<\App\Polling\Measure\MeasurementCollection>
|
||||||
|
*/
|
||||||
|
public function getStats(): Collection
|
||||||
{
|
{
|
||||||
return array_reduce($this->stores, function ($result, DatastoreContract $store) {
|
return collect($this->stores)->mapWithKeys(function (DatastoreContract $store) {
|
||||||
$result[$store->getName()] = $store->getStats();
|
return [$store->getName() => $store->getStats()];
|
||||||
|
});
|
||||||
return $result;
|
|
||||||
}, []);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Data\Measure\Measurement;
|
|
||||||
use Log;
|
use Log;
|
||||||
|
|
||||||
class Graphite extends BaseDatastore
|
class Graphite extends BaseDatastore
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use InfluxDB\Client;
|
use InfluxDB\Client;
|
||||||
use InfluxDB\Driver\UDP;
|
use InfluxDB\Driver\UDP;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Data\Measure\Measurement;
|
|
||||||
use Log;
|
use Log;
|
||||||
|
|
||||||
class InfluxDB extends BaseDatastore
|
class InfluxDB extends BaseDatastore
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Data\Measure\Measurement;
|
|
||||||
use Log;
|
use Log;
|
||||||
|
|
||||||
class OpenTSDB extends BaseDatastore
|
class OpenTSDB extends BaseDatastore
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use GuzzleHttp\Exception\GuzzleException;
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Data\Measure\Measurement;
|
|
||||||
use Log;
|
use Log;
|
||||||
|
|
||||||
class Prometheus extends BaseDatastore
|
class Prometheus extends BaseDatastore
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
namespace LibreNMS\Data\Store;
|
namespace LibreNMS\Data\Store;
|
||||||
|
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Data\Measure\Measurement;
|
|
||||||
use LibreNMS\Exceptions\FileExistsException;
|
use LibreNMS\Exceptions\FileExistsException;
|
||||||
use LibreNMS\Exceptions\RrdGraphException;
|
use LibreNMS\Exceptions\RrdGraphException;
|
||||||
use LibreNMS\Proc;
|
use LibreNMS\Proc;
|
||||||
|
@ -19,11 +19,11 @@
|
|||||||
*
|
*
|
||||||
* @link https://www.librenms.org
|
* @link https://www.librenms.org
|
||||||
*
|
*
|
||||||
* @copyright 2020 Tony Murray
|
* @copyright 2021 Tony Murray
|
||||||
* @author Tony Murray <murraytony@gmail.com>
|
* @author Tony Murray <murraytony@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace LibreNMS\Data\Measure;
|
namespace App\Polling\Measure;
|
||||||
|
|
||||||
class Measurement
|
class Measurement
|
||||||
{
|
{
|
||||||
@ -31,10 +31,21 @@ class Measurement
|
|||||||
private $type;
|
private $type;
|
||||||
private $duration;
|
private $duration;
|
||||||
|
|
||||||
private function __construct(string $type)
|
private function __construct(string $type, float $duration = null)
|
||||||
{
|
{
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->start = microtime(true);
|
$this->start = microtime(true);
|
||||||
|
if ($duration !== null) {
|
||||||
|
$this->duration = $duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a measurement with an existing duration
|
||||||
|
*/
|
||||||
|
public static function make(string $type, float $duration): Measurement
|
||||||
|
{
|
||||||
|
return new static($type, $duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,17 +54,15 @@ class Measurement
|
|||||||
* @param string $type
|
* @param string $type
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function start(string $type)
|
public static function start(string $type): Measurement
|
||||||
{
|
{
|
||||||
return new static($type);
|
return new static($type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End the timer for this operation
|
* End the timer for this operation
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
*/
|
||||||
public function end()
|
public function end(): Measurement
|
||||||
{
|
{
|
||||||
$this->duration = microtime(true) - $this->start;
|
$this->duration = microtime(true) - $this->start;
|
||||||
|
|
||||||
@ -62,21 +71,22 @@ class Measurement
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the duration of the operation
|
* Get the duration of the operation
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
*/
|
||||||
public function getDuration()
|
public function getDuration(): float
|
||||||
{
|
{
|
||||||
return $this->duration;
|
return $this->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of the operation
|
* Get the type of the operation
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getType()
|
public function getType(): string
|
||||||
{
|
{
|
||||||
return $this->type;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function manager(): MeasurementManager
|
||||||
|
{
|
||||||
|
return app(MeasurementManager::class);
|
||||||
|
}
|
||||||
}
|
}
|
@ -19,42 +19,42 @@
|
|||||||
*
|
*
|
||||||
* @link https://www.librenms.org
|
* @link https://www.librenms.org
|
||||||
*
|
*
|
||||||
* @copyright 2020 Tony Murray
|
* @copyright 2021 Tony Murray
|
||||||
* @author Tony Murray <murraytony@gmail.com>
|
* @author Tony Murray <murraytony@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace LibreNMS\Data\Measure;
|
namespace App\Polling\Measure;
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class MeasurementCollection extends Collection
|
class MeasurementCollection extends Collection
|
||||||
{
|
{
|
||||||
public function getTotalCount()
|
public function getTotalCount(): int
|
||||||
{
|
{
|
||||||
return $this->sumStat('getCount');
|
return $this->sumStat('getCount');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTotalDuration()
|
public function getTotalDuration(): float
|
||||||
{
|
{
|
||||||
return $this->sumStat('getDuration');
|
return $this->sumStat('getDuration');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCountDiff()
|
public function getCountDiff(): int
|
||||||
{
|
{
|
||||||
return $this->sumStat('getCountDiff');
|
return $this->sumStat('getCountDiff');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDurationDiff()
|
public function getDurationDiff(): float
|
||||||
{
|
{
|
||||||
return $this->sumStat('getDurationDiff');
|
return $this->sumStat('getDurationDiff');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkpoint()
|
public function checkpoint(): void
|
||||||
{
|
{
|
||||||
$this->each->checkpoint();
|
$this->each->checkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function record(Measurement $measurement)
|
public function record(Measurement $measurement): void
|
||||||
{
|
{
|
||||||
$type = $measurement->getType();
|
$type = $measurement->getType();
|
||||||
|
|
||||||
@ -65,10 +65,19 @@ class MeasurementCollection extends Collection
|
|||||||
$this->get($type)->add($measurement);
|
$this->get($type)->add($measurement);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sumStat($function)
|
public function getSummary(string $type): MeasurementSummary
|
||||||
{
|
{
|
||||||
return $this->reduce(function ($sum, $measurement) use ($function) {
|
return $this->get($type, new MeasurementSummary($type));
|
||||||
$sum += $measurement->$function();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $method method on measurement class to call
|
||||||
|
* @return int|float
|
||||||
|
*/
|
||||||
|
private function sumStat(string $method)
|
||||||
|
{
|
||||||
|
return $this->reduce(function ($sum, $measurement) use ($method) {
|
||||||
|
$sum += $measurement->$method();
|
||||||
|
|
||||||
return $sum;
|
return $sum;
|
||||||
}, 0);
|
}, 0);
|
142
app/Polling/Measure/MeasurementManager.php
Normal file
142
app/Polling/Measure/MeasurementManager.php
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* MeasurementManager.php
|
||||||
|
*
|
||||||
|
* -Description-
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @link https://www.librenms.org
|
||||||
|
*
|
||||||
|
* @copyright 2021 Tony Murray
|
||||||
|
* @author Tony Murray <murraytony@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Polling\Measure;
|
||||||
|
|
||||||
|
use DB;
|
||||||
|
use Illuminate\Database\Events\QueryExecuted;
|
||||||
|
|
||||||
|
class MeasurementManager
|
||||||
|
{
|
||||||
|
const SNMP_COLOR = "\e[0;36m";
|
||||||
|
const DB_COLOR = "\e[1;33m";
|
||||||
|
const DATASTORE_COLOR = "\e[0;32m";
|
||||||
|
const NO_COLOR = "\e[0m";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MeasurementCollection
|
||||||
|
*/
|
||||||
|
private static $snmp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MeasurementCollection
|
||||||
|
*/
|
||||||
|
private static $db;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
if (self::$snmp === null) {
|
||||||
|
self::$snmp = new MeasurementCollection();
|
||||||
|
self::$db = new MeasurementCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register DB listener to record sql query stats
|
||||||
|
*/
|
||||||
|
public function listenDb(): void
|
||||||
|
{
|
||||||
|
DB::listen(function (QueryExecuted $event) {
|
||||||
|
$type = strtolower(substr($event->sql, 0, strpos($event->sql, ' ')));
|
||||||
|
$this->recordDb(Measurement::make($type, $event->time ? $event->time / 100 : 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update statistics for db operations
|
||||||
|
*/
|
||||||
|
public function recordDb(Measurement $measurement): void
|
||||||
|
{
|
||||||
|
self::$db->record($measurement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print out the stats totals since the last checkpoint
|
||||||
|
*/
|
||||||
|
public function printChangedStats(): void
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
'>> %sSNMP%s: [%d/%.2fs] %sMySQL%s: [%d/%.2fs]',
|
||||||
|
self::SNMP_COLOR,
|
||||||
|
self::NO_COLOR,
|
||||||
|
self::$snmp->getCountDiff(),
|
||||||
|
self::$snmp->getDurationDiff(),
|
||||||
|
self::DB_COLOR,
|
||||||
|
self::NO_COLOR,
|
||||||
|
self::$db->getCountDiff(),
|
||||||
|
self::$db->getDurationDiff()
|
||||||
|
);
|
||||||
|
|
||||||
|
app('Datastore')->getStats()->each(function (MeasurementCollection $stats, $datastore) {
|
||||||
|
printf(' %s%s%s: [%d/%.2fs]', self::DATASTORE_COLOR, $datastore, self::NO_COLOR, $stats->getCountDiff(), $stats->getDurationDiff());
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->checkpoint();
|
||||||
|
|
||||||
|
echo PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a new checkpoint so to compare against
|
||||||
|
*/
|
||||||
|
public function checkpoint(): void
|
||||||
|
{
|
||||||
|
self::$snmp->checkpoint();
|
||||||
|
self::$db->checkpoint();
|
||||||
|
app('Datastore')->getStats()->each->checkpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record a measurement for snmp
|
||||||
|
*/
|
||||||
|
public function recordSnmp(Measurement $measurement): void
|
||||||
|
{
|
||||||
|
self::$snmp->record($measurement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print global stat arrays
|
||||||
|
*/
|
||||||
|
public function printStats(): void
|
||||||
|
{
|
||||||
|
$this->printSummary('SNMP', self::$snmp, self::SNMP_COLOR);
|
||||||
|
$this->printSummary('SQL', self::$db, self::DB_COLOR);
|
||||||
|
|
||||||
|
app('Datastore')->getStats()->each(function (MeasurementCollection $stats, string $datastore) {
|
||||||
|
$this->printSummary($datastore, $stats, self::DATASTORE_COLOR);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function printSummary(string $name, MeasurementCollection $collection, string $color = ''): void
|
||||||
|
{
|
||||||
|
printf('%s%s%s [%d/%.2fs]:', $color, $name, $color ? self::NO_COLOR : '', $collection->getTotalCount(), $collection->getTotalDuration());
|
||||||
|
|
||||||
|
$collection->each(function (MeasurementSummary $stat) {
|
||||||
|
printf(' %s[%d/%.2fs]', ucfirst($stat->getType()), $stat->getCount(), $stat->getDuration());
|
||||||
|
});
|
||||||
|
|
||||||
|
echo PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
@ -19,11 +19,11 @@
|
|||||||
*
|
*
|
||||||
* @link https://www.librenms.org
|
* @link https://www.librenms.org
|
||||||
*
|
*
|
||||||
* @copyright 2020 Tony Murray
|
* @copyright 2021 Tony Murray
|
||||||
* @author Tony Murray <murraytony@gmail.com>
|
* @author Tony Murray <murraytony@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace LibreNMS\Data\Measure;
|
namespace App\Polling\Measure;
|
||||||
|
|
||||||
class MeasurementSummary
|
class MeasurementSummary
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@ class MeasurementSummary
|
|||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add(Measurement $measurement)
|
public function add(Measurement $measurement): void
|
||||||
{
|
{
|
||||||
$this->count++;
|
$this->count++;
|
||||||
$this->duration += $measurement->getDuration();
|
$this->duration += $measurement->getDuration();
|
||||||
@ -48,10 +48,8 @@ class MeasurementSummary
|
|||||||
/**
|
/**
|
||||||
* Get the measurement summary
|
* Get the measurement summary
|
||||||
* ['count' => #, 'duration' => s]
|
* ['count' => #, 'duration' => s]
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function get()
|
public function get(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'count' => $this->count,
|
'count' => $this->count,
|
||||||
@ -59,33 +57,36 @@ class MeasurementSummary
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCount()
|
public function getCount(): int
|
||||||
{
|
{
|
||||||
return $this->count;
|
return $this->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getType()
|
public function getType(): string
|
||||||
{
|
{
|
||||||
return $this->type;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDuration()
|
public function getDuration(): float
|
||||||
{
|
{
|
||||||
return $this->duration;
|
return $this->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkpoint()
|
/**
|
||||||
|
* Set a new checkpoint to compare against with diff methods
|
||||||
|
*/
|
||||||
|
public function checkpoint(): void
|
||||||
{
|
{
|
||||||
$this->checkpointCount = $this->count;
|
$this->checkpointCount = $this->count;
|
||||||
$this->checkpointDuration = $this->duration;
|
$this->checkpointDuration = $this->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCountDiff()
|
public function getCountDiff(): int
|
||||||
{
|
{
|
||||||
return $this->count - $this->checkpointCount;
|
return $this->count - $this->checkpointCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDurationDiff()
|
public function getDurationDiff(): float
|
||||||
{
|
{
|
||||||
return $this->duration - $this->checkpointDuration;
|
return $this->duration - $this->checkpointDuration;
|
||||||
}
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\Sensor;
|
use App\Models\Sensor;
|
||||||
|
use App\Polling\Measure\MeasurementManager;
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@ -38,8 +39,9 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot(MeasurementManager $measure)
|
||||||
{
|
{
|
||||||
|
$measure->listenDb();
|
||||||
\Illuminate\Pagination\Paginator::useBootstrap();
|
\Illuminate\Pagination\Paginator::useBootstrap();
|
||||||
|
|
||||||
$this->app->booted('\LibreNMS\DB\Eloquent::initLegacyListeners');
|
$this->app->booted('\LibreNMS\DB\Eloquent::initLegacyListeners');
|
||||||
|
@ -136,7 +136,8 @@ $string = $argv[0] . " $doing " . date(\LibreNMS\Config::get('dateformat.compact
|
|||||||
d_echo("$string\n");
|
d_echo("$string\n");
|
||||||
|
|
||||||
if (! isset($options['q'])) {
|
if (! isset($options['q'])) {
|
||||||
printStats();
|
echo PHP_EOL;
|
||||||
|
app(\App\Polling\Measure\MeasurementManager::class)->printStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
logfile($string);
|
logfile($string);
|
||||||
|
@ -34,5 +34,5 @@ if (Debug::isEnabled()) {
|
|||||||
echo '<br />';
|
echo '<br />';
|
||||||
printf('Runtime %.3fs', microtime(true) - $start);
|
printf('Runtime %.3fs', microtime(true) - $start);
|
||||||
echo '<br />';
|
echo '<br />';
|
||||||
printStats();
|
app(\App\Polling\Measure\MeasurementManager::class)->printStats();
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
use LibreNMS\Config;
|
|
||||||
use LibreNMS\DB\Eloquent;
|
use LibreNMS\DB\Eloquent;
|
||||||
use LibreNMS\Exceptions\DatabaseConnectException;
|
use LibreNMS\Exceptions\DatabaseConnectException;
|
||||||
use LibreNMS\Util\Laravel;
|
use LibreNMS\Util\Laravel;
|
||||||
@ -110,8 +109,6 @@ function dbQuery($sql, $parameters = [])
|
|||||||
*/
|
*/
|
||||||
function dbInsert($data, $table)
|
function dbInsert($data, $table)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
$sql = 'INSERT IGNORE INTO `' . $table . '` (`' . implode('`,`', array_keys($data)) . '`) VALUES (' . implode(',', dbPlaceHolders($data)) . ')';
|
$sql = 'INSERT IGNORE INTO `' . $table . '` (`' . implode('`,`', array_keys($data)) . '`) VALUES (' . implode(',', dbPlaceHolders($data)) . ')';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -120,7 +117,6 @@ function dbInsert($data, $table)
|
|||||||
dbHandleException(new QueryException($sql, $data, $pdoe));
|
dbHandleException(new QueryException($sql, $data, $pdoe));
|
||||||
}
|
}
|
||||||
|
|
||||||
recordDbStatistic('insert', $time_start);
|
|
||||||
if ($result) {
|
if ($result) {
|
||||||
return Eloquent::DB()->getPdo()->lastInsertId();
|
return Eloquent::DB()->getPdo()->lastInsertId();
|
||||||
} else {
|
} else {
|
||||||
@ -139,8 +135,6 @@ function dbInsert($data, $table)
|
|||||||
*/
|
*/
|
||||||
function dbBulkInsert($data, $table)
|
function dbBulkInsert($data, $table)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
// check that data isn't an empty array
|
// check that data isn't an empty array
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
return false;
|
return false;
|
||||||
@ -160,8 +154,6 @@ function dbBulkInsert($data, $table)
|
|||||||
try {
|
try {
|
||||||
$result = Eloquent::DB()->table($table)->insert((array) $data_chunk);
|
$result = Eloquent::DB()->table($table)->insert((array) $data_chunk);
|
||||||
|
|
||||||
recordDbStatistic('insert', $time_start);
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
} catch (PDOException $pdoe) {
|
} catch (PDOException $pdoe) {
|
||||||
// FIXME query?
|
// FIXME query?
|
||||||
@ -184,8 +176,6 @@ function dbBulkInsert($data, $table)
|
|||||||
*/
|
*/
|
||||||
function dbUpdate($data, $table, $where = null, $parameters = [])
|
function dbUpdate($data, $table, $where = null, $parameters = [])
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
// need field name and placeholder value
|
// need field name and placeholder value
|
||||||
// but how merge these field placeholders with actual $parameters array for the WHERE clause
|
// but how merge these field placeholders with actual $parameters array for the WHERE clause
|
||||||
$sql = 'UPDATE `' . $table . '` set ';
|
$sql = 'UPDATE `' . $table . '` set ';
|
||||||
@ -213,8 +203,6 @@ function dbUpdate($data, $table, $where = null, $parameters = [])
|
|||||||
try {
|
try {
|
||||||
$result = Eloquent::DB()->update($sql, (array) $data);
|
$result = Eloquent::DB()->update($sql, (array) $data);
|
||||||
|
|
||||||
recordDbStatistic('update', $time_start);
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
} catch (PDOException $pdoe) {
|
} catch (PDOException $pdoe) {
|
||||||
dbHandleException(new QueryException($sql, $data, $pdoe));
|
dbHandleException(new QueryException($sql, $data, $pdoe));
|
||||||
@ -225,8 +213,6 @@ function dbUpdate($data, $table, $where = null, $parameters = [])
|
|||||||
|
|
||||||
function dbDelete($table, $where = null, $parameters = [])
|
function dbDelete($table, $where = null, $parameters = [])
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
$sql = 'DELETE FROM `' . $table . '`';
|
$sql = 'DELETE FROM `' . $table . '`';
|
||||||
if ($where) {
|
if ($where) {
|
||||||
$sql .= ' WHERE ' . $where;
|
$sql .= ' WHERE ' . $where;
|
||||||
@ -238,8 +224,6 @@ function dbDelete($table, $where = null, $parameters = [])
|
|||||||
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
||||||
}
|
}
|
||||||
|
|
||||||
recordDbStatistic('delete', $time_start);
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}//end dbDelete()
|
}//end dbDelete()
|
||||||
|
|
||||||
@ -253,8 +237,6 @@ function dbDelete($table, $where = null, $parameters = [])
|
|||||||
*/
|
*/
|
||||||
function dbDeleteOrphans($target_table, $parents)
|
function dbDeleteOrphans($target_table, $parents)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
if (empty($parents)) {
|
if (empty($parents)) {
|
||||||
// don't delete all entries if parents is missing
|
// don't delete all entries if parents is missing
|
||||||
return false;
|
return false;
|
||||||
@ -288,8 +270,6 @@ function dbDeleteOrphans($target_table, $parents)
|
|||||||
dbHandleException(new QueryException($query, [], $pdoe));
|
dbHandleException(new QueryException($query, [], $pdoe));
|
||||||
}
|
}
|
||||||
|
|
||||||
recordDbStatistic('delete', $time_start);
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,14 +281,11 @@ function dbDeleteOrphans($target_table, $parents)
|
|||||||
function dbFetchRows($sql, $parameters = [])
|
function dbFetchRows($sql, $parameters = [])
|
||||||
{
|
{
|
||||||
global $PDO_FETCH_ASSOC;
|
global $PDO_FETCH_ASSOC;
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$PDO_FETCH_ASSOC = true;
|
$PDO_FETCH_ASSOC = true;
|
||||||
$rows = Eloquent::DB()->select($sql, (array) $parameters);
|
$rows = Eloquent::DB()->select($sql, (array) $parameters);
|
||||||
|
|
||||||
recordDbStatistic('fetchrows', $time_start);
|
|
||||||
|
|
||||||
return $rows;
|
return $rows;
|
||||||
} catch (PDOException $pdoe) {
|
} catch (PDOException $pdoe) {
|
||||||
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
||||||
@ -347,14 +324,11 @@ function dbFetch($sql, $parameters = [])
|
|||||||
function dbFetchRow($sql = null, $parameters = [])
|
function dbFetchRow($sql = null, $parameters = [])
|
||||||
{
|
{
|
||||||
global $PDO_FETCH_ASSOC;
|
global $PDO_FETCH_ASSOC;
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$PDO_FETCH_ASSOC = true;
|
$PDO_FETCH_ASSOC = true;
|
||||||
$row = Eloquent::DB()->selectOne($sql, (array) $parameters);
|
$row = Eloquent::DB()->selectOne($sql, (array) $parameters);
|
||||||
|
|
||||||
recordDbStatistic('fetchrow', $time_start);
|
|
||||||
|
|
||||||
return $row;
|
return $row;
|
||||||
} catch (PDOException $pdoe) {
|
} catch (PDOException $pdoe) {
|
||||||
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
||||||
@ -372,12 +346,10 @@ function dbFetchRow($sql = null, $parameters = [])
|
|||||||
function dbFetchCell($sql, $parameters = [])
|
function dbFetchCell($sql, $parameters = [])
|
||||||
{
|
{
|
||||||
global $PDO_FETCH_ASSOC;
|
global $PDO_FETCH_ASSOC;
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$PDO_FETCH_ASSOC = true;
|
$PDO_FETCH_ASSOC = true;
|
||||||
$row = Eloquent::DB()->selectOne($sql, (array) $parameters);
|
$row = Eloquent::DB()->selectOne($sql, (array) $parameters);
|
||||||
recordDbStatistic('fetchcell', $time_start);
|
|
||||||
if ($row) {
|
if ($row) {
|
||||||
return reset($row);
|
return reset($row);
|
||||||
// shift first field off first row
|
// shift first field off first row
|
||||||
@ -399,7 +371,6 @@ function dbFetchCell($sql, $parameters = [])
|
|||||||
function dbFetchColumn($sql, $parameters = [])
|
function dbFetchColumn($sql, $parameters = [])
|
||||||
{
|
{
|
||||||
global $PDO_FETCH_ASSOC;
|
global $PDO_FETCH_ASSOC;
|
||||||
$time_start = microtime(true);
|
|
||||||
|
|
||||||
$cells = [];
|
$cells = [];
|
||||||
|
|
||||||
@ -410,8 +381,6 @@ function dbFetchColumn($sql, $parameters = [])
|
|||||||
}
|
}
|
||||||
$PDO_FETCH_ASSOC = false;
|
$PDO_FETCH_ASSOC = false;
|
||||||
|
|
||||||
recordDbStatistic('fetchcolumn', $time_start);
|
|
||||||
|
|
||||||
return $cells;
|
return $cells;
|
||||||
} catch (PDOException $pdoe) {
|
} catch (PDOException $pdoe) {
|
||||||
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
dbHandleException(new QueryException($sql, $parameters, $pdoe));
|
||||||
@ -544,58 +513,6 @@ function dbGenPlaceholders($count)
|
|||||||
return '(' . implode(',', array_fill(0, $count, '?')) . ')';
|
return '(' . implode(',', array_fill(0, $count, '?')) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update statistics for db operations
|
|
||||||
*
|
|
||||||
* @param string $stat fetchcell, fetchrow, fetchrows, fetchcolumn, update, insert, delete
|
|
||||||
* @param float $start_time The time the operation started with 'microtime(true)'
|
|
||||||
* @return float The calculated run time
|
|
||||||
*/
|
|
||||||
function recordDbStatistic($stat, $start_time)
|
|
||||||
{
|
|
||||||
global $db_stats, $db_stats_last;
|
|
||||||
|
|
||||||
if (! isset($db_stats)) {
|
|
||||||
$db_stats = [
|
|
||||||
'ops' => [
|
|
||||||
'insert' => 0,
|
|
||||||
'update' => 0,
|
|
||||||
'delete' => 0,
|
|
||||||
'fetchcell' => 0,
|
|
||||||
'fetchcolumn' => 0,
|
|
||||||
'fetchrow' => 0,
|
|
||||||
'fetchrows' => 0,
|
|
||||||
],
|
|
||||||
'time' => [
|
|
||||||
'insert' => 0.0,
|
|
||||||
'update' => 0.0,
|
|
||||||
'delete' => 0.0,
|
|
||||||
'fetchcell' => 0.0,
|
|
||||||
'fetchcolumn' => 0.0,
|
|
||||||
'fetchrow' => 0.0,
|
|
||||||
'fetchrows' => 0.0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
$db_stats_last = $db_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
$runtime = microtime(true) - $start_time;
|
|
||||||
$db_stats['ops'][$stat]++;
|
|
||||||
$db_stats['time'][$stat] += $runtime;
|
|
||||||
|
|
||||||
//double accounting corrections
|
|
||||||
if ($stat == 'fetchcolumn') {
|
|
||||||
$db_stats['ops']['fetchrows']--;
|
|
||||||
$db_stats['time']['fetchrows'] -= $runtime;
|
|
||||||
}
|
|
||||||
if ($stat == 'fetchcell') {
|
|
||||||
$db_stats['ops']['fetchrow']--;
|
|
||||||
$db_stats['time']['fetchrow'] -= $runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronize a relationship to a list of related ids
|
* Synchronize a relationship to a list of related ids
|
||||||
*
|
*
|
||||||
|
@ -146,6 +146,10 @@ function discover_device(&$device, $force_module = false)
|
|||||||
$discovery_devices = Config::get('discovery_modules', []);
|
$discovery_devices = Config::get('discovery_modules', []);
|
||||||
$discovery_devices = ['core' => true] + $discovery_devices;
|
$discovery_devices = ['core' => true] + $discovery_devices;
|
||||||
|
|
||||||
|
/** @var \App\Polling\Measure\MeasurementManager $measurements */
|
||||||
|
$measurements = app(\App\Polling\Measure\MeasurementManager::class);
|
||||||
|
$measurements->checkpoint(); // don't count previous stats
|
||||||
|
|
||||||
foreach ($discovery_devices as $module => $module_status) {
|
foreach ($discovery_devices as $module => $module_status) {
|
||||||
$os_module_status = Config::getOsSetting($device['os'], "discovery_modules.$module");
|
$os_module_status = Config::getOsSetting($device['os'], "discovery_modules.$module");
|
||||||
d_echo('Modules status: Global' . (isset($module_status) ? ($module_status ? '+ ' : '- ') : ' '));
|
d_echo('Modules status: Global' . (isset($module_status) ? ($module_status ? '+ ' : '- ') : ' '));
|
||||||
@ -173,7 +177,7 @@ function discover_device(&$device, $force_module = false)
|
|||||||
$module_time = substr($module_time, 0, 5);
|
$module_time = substr($module_time, 0, 5);
|
||||||
$module_mem = (memory_get_usage() - $start_memory);
|
$module_mem = (memory_get_usage() - $start_memory);
|
||||||
printf("\n>> Runtime for discovery module '%s': %.4f seconds with %s bytes\n", $module, $module_time, $module_mem);
|
printf("\n>> Runtime for discovery module '%s': %.4f seconds with %s bytes\n", $module, $module_time, $module_mem);
|
||||||
printChangedStats();
|
$measurements->printChangedStats();
|
||||||
echo "#### Unload disco module $module ####\n\n";
|
echo "#### Unload disco module $module ####\n\n";
|
||||||
} elseif (isset($attribs['discover_' . $module]) && $attribs['discover_' . $module] == '0') {
|
} elseif (isset($attribs['discover_' . $module]) && $attribs['discover_' . $module] == '0') {
|
||||||
echo "Module [ $module ] disabled on host.\n\n";
|
echo "Module [ $module ] disabled on host.\n\n";
|
||||||
|
@ -1449,134 +1449,6 @@ function q_bridge_bits2indices($hex_data)
|
|||||||
return $indices;
|
return $indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Intialize global stat arrays
|
|
||||||
*/
|
|
||||||
function initStats()
|
|
||||||
{
|
|
||||||
global $snmp_stats, $snmp_stats_last;
|
|
||||||
|
|
||||||
if (! isset($snmp_stats)) {
|
|
||||||
$snmp_stats = [
|
|
||||||
'ops' => [
|
|
||||||
'snmpget' => 0,
|
|
||||||
'snmpgetnext' => 0,
|
|
||||||
'snmpwalk' => 0,
|
|
||||||
],
|
|
||||||
'time' => [
|
|
||||||
'snmpget' => 0.0,
|
|
||||||
'snmpgetnext' => 0.0,
|
|
||||||
'snmpwalk' => 0.0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
$snmp_stats_last = $snmp_stats;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print out the stats totals since the last time this function was called
|
|
||||||
*
|
|
||||||
* @param bool $update_only Only update the stats checkpoint, don't print them
|
|
||||||
*/
|
|
||||||
function printChangedStats($update_only = false)
|
|
||||||
{
|
|
||||||
global $snmp_stats, $db_stats;
|
|
||||||
global $snmp_stats_last, $db_stats_last;
|
|
||||||
$output = sprintf(
|
|
||||||
'>> SNMP: [%d/%.2fs] MySQL: [%d/%.2fs]',
|
|
||||||
array_sum($snmp_stats['ops'] ?? []) - array_sum($snmp_stats_last['ops'] ?? []),
|
|
||||||
array_sum($snmp_stats['time'] ?? []) - array_sum($snmp_stats_last['time'] ?? []),
|
|
||||||
array_sum($db_stats['ops'] ?? []) - array_sum($db_stats_last['ops'] ?? []),
|
|
||||||
array_sum($db_stats['time'] ?? []) - array_sum($db_stats_last['time'] ?? [])
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach (app('Datastore')->getStats() as $datastore => $stats) {
|
|
||||||
/** @var \LibreNMS\Data\Measure\MeasurementCollection $stats */
|
|
||||||
$output .= sprintf(' %s: [%d/%.2fs]', $datastore, $stats->getCountDiff(), $stats->getDurationDiff());
|
|
||||||
$stats->checkpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $update_only) {
|
|
||||||
echo $output . PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make a new checkpoint
|
|
||||||
$snmp_stats_last = $snmp_stats;
|
|
||||||
$db_stats_last = $db_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print global stat arrays
|
|
||||||
*/
|
|
||||||
function printStats()
|
|
||||||
{
|
|
||||||
global $snmp_stats, $db_stats;
|
|
||||||
|
|
||||||
if ($snmp_stats) {
|
|
||||||
printf(
|
|
||||||
"SNMP [%d/%.2fs]: Get[%d/%.2fs] Getnext[%d/%.2fs] Walk[%d/%.2fs]\n",
|
|
||||||
array_sum($snmp_stats['ops']),
|
|
||||||
array_sum($snmp_stats['time']),
|
|
||||||
$snmp_stats['ops']['snmpget'],
|
|
||||||
$snmp_stats['time']['snmpget'],
|
|
||||||
$snmp_stats['ops']['snmpgetnext'],
|
|
||||||
$snmp_stats['time']['snmpgetnext'],
|
|
||||||
$snmp_stats['ops']['snmpwalk'],
|
|
||||||
$snmp_stats['time']['snmpwalk']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($db_stats) {
|
|
||||||
printf(
|
|
||||||
"MySQL [%d/%.2fs]: Cell[%d/%.2fs] Row[%d/%.2fs] Rows[%d/%.2fs] Column[%d/%.2fs] Update[%d/%.2fs] Insert[%d/%.2fs] Delete[%d/%.2fs]\n",
|
|
||||||
array_sum($db_stats['ops']),
|
|
||||||
array_sum($db_stats['time']),
|
|
||||||
$db_stats['ops']['fetchcell'],
|
|
||||||
$db_stats['time']['fetchcell'],
|
|
||||||
$db_stats['ops']['fetchrow'],
|
|
||||||
$db_stats['time']['fetchrow'],
|
|
||||||
$db_stats['ops']['fetchrows'],
|
|
||||||
$db_stats['time']['fetchrows'],
|
|
||||||
$db_stats['ops']['fetchcolumn'],
|
|
||||||
$db_stats['time']['fetchcolumn'],
|
|
||||||
$db_stats['ops']['update'],
|
|
||||||
$db_stats['time']['update'],
|
|
||||||
$db_stats['ops']['insert'],
|
|
||||||
$db_stats['time']['insert'],
|
|
||||||
$db_stats['ops']['delete'],
|
|
||||||
$db_stats['time']['delete']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (app('Datastore')->getStats() as $datastore => $stats) {
|
|
||||||
/** @var \LibreNMS\Data\Measure\MeasurementCollection $stats */
|
|
||||||
printf('%s [%d/%.2fs]:', $datastore, $stats->getTotalCount(), $stats->getTotalDuration());
|
|
||||||
|
|
||||||
foreach ($stats as $stat) {
|
|
||||||
/** @var \LibreNMS\Data\Measure\MeasurementSummary $stat */
|
|
||||||
printf(' %s[%d/%.2fs]', ucfirst($stat->getType()), $stat->getCount(), $stat->getDuration());
|
|
||||||
}
|
|
||||||
echo PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $stat snmpget, snmpwalk
|
|
||||||
* @param float $start_time The time the operation started with 'microtime(true)'
|
|
||||||
* @return float The calculated run time
|
|
||||||
*/
|
|
||||||
function recordSnmpStatistic($stat, $start_time)
|
|
||||||
{
|
|
||||||
global $snmp_stats;
|
|
||||||
initStats();
|
|
||||||
|
|
||||||
$runtime = microtime(true) - $start_time;
|
|
||||||
$snmp_stats['ops'][$stat]++;
|
|
||||||
$snmp_stats['time'][$stat] += $runtime;
|
|
||||||
|
|
||||||
return $runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_device_logo(&$device)
|
function update_device_logo(&$device)
|
||||||
{
|
{
|
||||||
$icon = getImageName($device, false);
|
$icon = getImageName($device, false);
|
||||||
|
@ -310,7 +310,10 @@ function poll_device($device, $force_module = false)
|
|||||||
$device['status'] = $deviceModel->status;
|
$device['status'] = $deviceModel->status;
|
||||||
$device['status_reason'] = $deviceModel->status_reason;
|
$device['status_reason'] = $deviceModel->status_reason;
|
||||||
|
|
||||||
printChangedStats(true); // don't count previous stats
|
/** @var \App\Polling\Measure\MeasurementManager $measurements */
|
||||||
|
$measurements = app(\App\Polling\Measure\MeasurementManager::class);
|
||||||
|
$measurements->checkpoint(); // don't count previous stats
|
||||||
|
|
||||||
foreach (Config::get('poller_modules') as $module => $module_status) {
|
foreach (Config::get('poller_modules') as $module => $module_status) {
|
||||||
$os_module_status = Config::get("os.{$device['os']}.poller_modules.$module");
|
$os_module_status = Config::get("os.{$device['os']}.poller_modules.$module");
|
||||||
d_echo('Modules status: Global' . (isset($module_status) ? ($module_status ? '+ ' : '- ') : ' '));
|
d_echo('Modules status: Global' . (isset($module_status) ? ($module_status ? '+ ' : '- ') : ' '));
|
||||||
@ -336,7 +339,7 @@ function poll_device($device, $force_module = false)
|
|||||||
$module_time = microtime(true) - $module_start;
|
$module_time = microtime(true) - $module_start;
|
||||||
$module_mem = (memory_get_usage() - $start_memory);
|
$module_mem = (memory_get_usage() - $start_memory);
|
||||||
printf("\n>> Runtime for poller module '%s': %.4f seconds with %s bytes\n", $module, $module_time, $module_mem);
|
printf("\n>> Runtime for poller module '%s': %.4f seconds with %s bytes\n", $module, $module_time, $module_mem);
|
||||||
printChangedStats();
|
$measurements->printChangedStats();
|
||||||
echo "#### Unload poller module $module ####\n\n";
|
echo "#### Unload poller module $module ####\n\n";
|
||||||
|
|
||||||
// save per-module poller stats
|
// save per-module poller stats
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use App\Models\Device;
|
use App\Models\Device;
|
||||||
|
use App\Polling\Measure\Measurement;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Util\Debug;
|
use LibreNMS\Util\Debug;
|
||||||
@ -185,7 +186,7 @@ function gen_snmp_cmd($cmd, $device, $oids, $options = null, $mib = null, $mibdi
|
|||||||
|
|
||||||
function snmp_get_multi($device, $oids, $options = '-OQUs', $mib = null, $mibdir = null, $array = [])
|
function snmp_get_multi($device, $oids, $options = '-OQUs', $mib = null, $mibdir = null, $array = [])
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpget');
|
||||||
|
|
||||||
if (! is_array($oids)) {
|
if (! is_array($oids)) {
|
||||||
$oids = explode(' ', $oids);
|
$oids = explode(' ', $oids);
|
||||||
@ -212,14 +213,14 @@ function snmp_get_multi($device, $oids, $options = '-OQUs', $mib = null, $mibdir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recordSnmpStatistic('snmpget', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
|
|
||||||
return $array;
|
return $array;
|
||||||
}//end snmp_get_multi()
|
}//end snmp_get_multi()
|
||||||
|
|
||||||
function snmp_get_multi_oid($device, $oids, $options = '-OUQn', $mib = null, $mibdir = null)
|
function snmp_get_multi_oid($device, $oids, $options = '-OUQn', $mib = null, $mibdir = null)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpget');
|
||||||
$oid_limit = get_device_oid_limit($device);
|
$oid_limit = get_device_oid_limit($device);
|
||||||
|
|
||||||
if (! is_array($oids)) {
|
if (! is_array($oids)) {
|
||||||
@ -255,7 +256,7 @@ function snmp_get_multi_oid($device, $oids, $options = '-OUQn', $mib = null, $mi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recordSnmpStatistic('snmpget', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
|
|
||||||
return $array;
|
return $array;
|
||||||
}//end snmp_get_multi_oid()
|
}//end snmp_get_multi_oid()
|
||||||
@ -272,7 +273,7 @@ function snmp_get_multi_oid($device, $oids, $options = '-OUQn', $mib = null, $mi
|
|||||||
*/
|
*/
|
||||||
function snmp_get($device, $oid, $options = null, $mib = null, $mibdir = null)
|
function snmp_get($device, $oid, $options = null, $mib = null, $mibdir = null)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpget');
|
||||||
|
|
||||||
if (strstr($oid, ' ')) {
|
if (strstr($oid, ' ')) {
|
||||||
throw new Exception("snmp_get called for multiple OIDs: $oid");
|
throw new Exception("snmp_get called for multiple OIDs: $oid");
|
||||||
@ -282,7 +283,7 @@ function snmp_get($device, $oid, $options = null, $mib = null, $mibdir = null)
|
|||||||
$output = str_replace('Wrong Type (should be OBJECT IDENTIFIER): ', '', $output);
|
$output = str_replace('Wrong Type (should be OBJECT IDENTIFIER): ', '', $output);
|
||||||
$data = trim($output, "\\\" \n\r");
|
$data = trim($output, "\\\" \n\r");
|
||||||
|
|
||||||
recordSnmpStatistic('snmpget', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
if (preg_match('/(No Such Instance|No Such Object|No more variables left|Authentication failure)/i', $data)) {
|
if (preg_match('/(No Such Instance|No Such Object|No more variables left|Authentication failure)/i', $data)) {
|
||||||
return false;
|
return false;
|
||||||
} elseif ($data || $data === '0') {
|
} elseif ($data || $data === '0') {
|
||||||
@ -305,13 +306,13 @@ function snmp_get($device, $oid, $options = null, $mib = null, $mibdir = null)
|
|||||||
*/
|
*/
|
||||||
function snmp_getnext($device, $oid, $options = null, $mib = null, $mibdir = null)
|
function snmp_getnext($device, $oid, $options = null, $mib = null, $mibdir = null)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpgetnext');
|
||||||
|
|
||||||
$snmpcmd = [Config::get('snmpgetnext', 'snmpgetnext')];
|
$snmpcmd = [Config::get('snmpgetnext', 'snmpgetnext')];
|
||||||
$cmd = gen_snmp_cmd($snmpcmd, $device, $oid, $options, $mib, $mibdir);
|
$cmd = gen_snmp_cmd($snmpcmd, $device, $oid, $options, $mib, $mibdir);
|
||||||
$data = trim(external_exec($cmd), "\" \n\r");
|
$data = trim(external_exec($cmd), "\" \n\r");
|
||||||
|
|
||||||
recordSnmpStatistic('snmpgetnext', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
if (preg_match('/(No Such Instance|No Such Object|No more variables left|Authentication failure)/i', $data)) {
|
if (preg_match('/(No Such Instance|No Such Object|No more variables left|Authentication failure)/i', $data)) {
|
||||||
return false;
|
return false;
|
||||||
} elseif ($data || $data === '0') {
|
} elseif ($data || $data === '0') {
|
||||||
@ -334,7 +335,7 @@ function snmp_getnext($device, $oid, $options = null, $mib = null, $mibdir = nul
|
|||||||
*/
|
*/
|
||||||
function snmp_getnext_multi($device, $oids, $options = '-OQUs', $mib = null, $mibdir = null, $array = [])
|
function snmp_getnext_multi($device, $oids, $options = '-OQUs', $mib = null, $mibdir = null, $array = [])
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpgetnext');
|
||||||
if (! is_array($oids)) {
|
if (! is_array($oids)) {
|
||||||
$oids = explode(' ', $oids);
|
$oids = explode(' ', $oids);
|
||||||
}
|
}
|
||||||
@ -355,7 +356,7 @@ function snmp_getnext_multi($device, $oids, $options = '-OQUs', $mib = null, $mi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recordSnmpStatistic('snmpgetnext', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
|
|
||||||
return $array;
|
return $array;
|
||||||
}//end snmp_getnext_multi()
|
}//end snmp_getnext_multi()
|
||||||
@ -366,7 +367,7 @@ function snmp_getnext_multi($device, $oids, $options = '-OQUs', $mib = null, $mi
|
|||||||
*/
|
*/
|
||||||
function snmp_check($device)
|
function snmp_check($device)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpget');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$oid = '.1.3.6.1.2.1.1.2.0';
|
$oid = '.1.3.6.1.2.1.1.2.0';
|
||||||
@ -379,7 +380,7 @@ function snmp_check($device)
|
|||||||
Log::debug("Device didn't respond to snmpget before {$e->getExceededTimeout()}s timeout");
|
Log::debug("Device didn't respond to snmpget before {$e->getExceededTimeout()}s timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
recordSnmpStatistic('snmpget', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
|
|
||||||
if ($code === 0) {
|
if ($code === 0) {
|
||||||
return true;
|
return true;
|
||||||
@ -390,7 +391,7 @@ function snmp_check($device)
|
|||||||
|
|
||||||
function snmp_walk($device, $oid, $options = null, $mib = null, $mibdir = null)
|
function snmp_walk($device, $oid, $options = null, $mib = null, $mibdir = null)
|
||||||
{
|
{
|
||||||
$time_start = microtime(true);
|
$measure = Measurement::start('snmpwalk');
|
||||||
|
|
||||||
$cmd = gen_snmpwalk_cmd($device, $oid, $options, $mib, $mibdir);
|
$cmd = gen_snmpwalk_cmd($device, $oid, $options, $mib, $mibdir);
|
||||||
$data = trim(external_exec($cmd));
|
$data = trim(external_exec($cmd));
|
||||||
@ -410,7 +411,7 @@ function snmp_walk($device, $oid, $options = null, $mib = null, $mibdir = null)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recordSnmpStatistic('snmpwalk', $time_start);
|
$measure->manager()->recordSnmp($measure->end());
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}//end snmp_walk()
|
}//end snmp_walk()
|
||||||
|
@ -159,7 +159,8 @@ $string = $argv[0] . " $doing " . date(Config::get('dateformat.compact')) . " -
|
|||||||
d_echo("$string\n");
|
d_echo("$string\n");
|
||||||
|
|
||||||
if (! isset($options['q'])) {
|
if (! isset($options['q'])) {
|
||||||
printStats();
|
echo PHP_EOL;
|
||||||
|
app(\App\Polling\Measure\MeasurementManager::class)->printStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
logfile($string);
|
logfile($string);
|
||||||
|
Loading…
Reference in New Issue
Block a user