Skip to content
Snippets Groups Projects
Server.php 8.46 KiB
Newer Older
Tibo's avatar
Tibo committed
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
Tibo's avatar
Tibo committed

class Server extends Model
{

    protected $fillable = ["token"];

Tibo's avatar
Tibo committed
    /**
     * Last record from this server (used for caching).
     * @var String
     */
    private $last_record = null;

    private $records_1day = null;

Tibo's avatar
Tibo committed
    private static $sensors = [
        \App\Sensor\LoadAvg::class,
Tibo's avatar
Tibo committed
        \App\Sensor\MemInfo::class,
        \App\Sensor\Ifconfig::class,
        \App\Sensor\Netstat::class,
Tibo's avatar
Tibo committed
        \App\Sensor\ListeningPorts::class,
        \App\Sensor\Reboot::class,
Tibo's avatar
Tibo committed
        \App\Sensor\Updates::class,
Tibo's avatar
Tibo committed
        \App\Sensor\Disks::class,
Tibo's avatar
Tibo committed
        \App\Sensor\Inodes::class,
Tibo's avatar
Tibo committed
        \App\Sensor\Ssacli::class,
Tibo's avatar
Tibo committed
        \App\Sensor\Perccli::class,
        \App\Sensor\Date::class,
Tibo's avatar
Tibo committed
        \App\Sensor\ClientVersion::class,
        \App\Sensor\Heartbeat::class,
        \App\Sensor\DiskEvolution::class,
        \App\Sensor\CPUtemperature::class,
Tibo's avatar
Tibo committed
        \App\Sensor\USBtemperature::class
Tibo's avatar
Tibo committed
    public function __construct(array $attributes = array())
    {
Tibo's avatar
Tibo committed
        $attributes["token"] = str_random(32);
        parent::__construct($attributes);
    }

Tibo's avatar
Tibo committed
    public function organization()
    {
Tibo's avatar
Tibo committed
        return $this->belongsTo("App\Organization");
    }
Tibo's avatar
Tibo committed

Tibo's avatar
Tibo committed
    public function lastRecord()
    {
Tibo's avatar
Tibo committed
        if ($this->last_record == null) {
            $collection = \Mongo::get()->monitoring->records;
            $this->last_record =  $collection->findOne(
Tibo's avatar
Tibo committed
                ["server_id" => $this->id],
                ["sort" => ["_id" => -1]]
            );
Tibo's avatar
Tibo committed
        }

        return $this->last_record;
Tibo's avatar
Tibo committed
    }

Tibo's avatar
Tibo committed
    /**
     * Get the last day of data.
Tibo's avatar
Tibo committed
     * @return type
     */
Tibo's avatar
Tibo committed
    public function lastRecords1Day() : array
        if ($this->records_1day !== null) {
            return $this->records_1day;
        }

        $start = time() - 24 * 3600;
Tibo's avatar
Tibo committed
        $this->records_1day = \Mongo::get()->monitoring->records->find([
                "server_id" => $this->id,
                "time" => ['$gte' => $start]])
                ->toArray();
Tibo's avatar
Tibo committed
        return $this->records_1day;
    public function hasData() : bool
    {
        return $this->lastRecord() != null;
    }

Tibo's avatar
Tibo committed
    /**
     *
Tibo's avatar
Tibo committed
     * @return \Carbon\Carbon
Tibo's avatar
Tibo committed
     */
Tibo's avatar
Tibo committed
    public function lastRecordTime()
    {
        $hearbeat = new \App\Sensor\Heartbeat($this);
        return $hearbeat->lastRecordTime($this->lastRecord());
Tibo's avatar
Tibo committed
    }

Tibo's avatar
Tibo committed
    public function clientVersion(array $records) : string
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        $sensor = new \App\Sensor\ClientVersion($this);
        return $sensor->installedVersion($records);
Tibo's avatar
Tibo committed
    }
    public function lastClientUrl()
    {
Tibo's avatar
Tibo committed
        $client_sensor = new \App\Sensor\ClientVersion($this);
        return $client_sensor->latestUrl();
    }
Tibo's avatar
Tibo committed

Tibo's avatar
Tibo committed
    /**
     * Get integer status of server.
     * @return int
     */
Tibo's avatar
Tibo committed
    public function status(array $records) : int
Tibo's avatar
Tibo committed
    {
        return max($this->statusArray($records));
Tibo's avatar
Tibo committed
    }

    public function statusBadge(array $records)
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        return SensorWrapper::getBadgeForStatus($this->status($records));
Tibo's avatar
Tibo committed
    }

    public function statusArray(array $records)
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        $status_array = [];
Tibo's avatar
Tibo committed
        foreach ($this->getSensors() as $sensor) {
Tibo's avatar
Tibo committed
            $sensor_name = $sensor->id();
                $status_array[$sensor_name] = $sensor->status($records);
            } catch (\Exception $ex) {
                $status_array[$sensor_name] = Sensor::STATUS_UNKNOWN;
                Log::error("Sensor $sensor_name failed : " . $ex->getTraceAsString());
            }
Tibo's avatar
Tibo committed
        }
Tibo's avatar
Tibo committed
        return $status_array;
Tibo's avatar
Tibo committed
    }

    public function getSensorsNOK(array $records)
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        $sensorsNOK = [];
        foreach ($this->getSensors() as $sensor) {
            if ($sensor->status($records) > 0) {
Tibo's avatar
Tibo committed
                $sensorsNOK[] = $sensor;
            }
        }
        return $sensorsNOK;
    }

    public static function getNameForStatus(int $status)
    {
        switch ($status) {
Tibo's avatar
Tibo committed
            case 0:
                return "OK";
            case 10:
                return "WARNING";
            case 20:
                return "ERROR";
            default:
                return "Unknown";
        }
Tibo's avatar
Tibo committed
    }
    public function getBadge(array $records)
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        return SensorWrapper::getBadgeForStatus($this->status($records));
Tibo's avatar
Tibo committed
    public function color(array $records)
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        return SensorWrapper::getColorForStatus($this->status($records));
Tibo's avatar
Tibo committed
    }

Tibo's avatar
Tibo committed
    public function getSensors()
    {

        $sensors = [];
        foreach (self::$sensors as $sensor) {
Tibo's avatar
Tibo committed
            $sensors[] = new SensorWrapper(new $sensor());
        }
        return $sensors;
    }
Tibo's avatar
Tibo committed
    /**
     * Human readable uptime.
     *
     * @return string
     */
    public function uptime() : string
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["upaimte"])) {
            return "unknown";
Tibo's avatar
Tibo committed
        }

Tibo's avatar
Tibo committed
        return $this->parseUptime($record->upaimte);
Tibo's avatar
Tibo committed
    }

Tibo's avatar
Tibo committed
    public function parseUptime(string $string) : string
Tibo's avatar
Tibo committed
    {
        $pieces = explode(' ', $string);
        $uptime = \Carbon\Carbon::now()->subSeconds($pieces[0]);
        return $uptime->diffForHumans(null, true);
    }
Tibo's avatar
Tibo committed

Tibo's avatar
Tibo committed
    public function uuid()
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["system"])) {
Tibo's avatar
Tibo committed
            return "";
        }

        return $this->parseUUID($record->system);
    }

    const UUID = "/\s*UUID: (.*)/m";

    public function parseUUID(string $string) : string
Tibo's avatar
Tibo committed
    {
        $matches = array();
        preg_match(self::UUID, $string, $matches);
        if (! isset($matches[1])) {
            return "unknown";
        }
Tibo's avatar
Tibo committed
        return $matches[1];
    }

Tibo's avatar
Tibo committed

Tibo's avatar
Tibo committed
    public function cpuinfo() : array
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["cpu"])) {
            return ["threads" => 0,
                "cpu" => "unknown"];
Tibo's avatar
Tibo committed
        }

Tibo's avatar
Tibo committed
        return $this->parseCpuinfo($record->cpu);
Tibo's avatar
Tibo committed
    }

    const CPU_INFO = "/^model name	: (.+)$/m";
Tibo's avatar
Tibo committed
    public function parseCpuinfo($string) : array
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        $matches = array();
        preg_match_all(self::CPU_INFO, $string, $matches);

        $result["threads"] = count($matches[0]);
Tibo's avatar
Tibo committed
        $result["cpu"] = $matches[1][0];
Tibo's avatar
Tibo committed
        return $result;
Tibo's avatar
Tibo committed
    public function meminfo()
    {
Tibo's avatar
Tibo committed
        return round($this->memoryTotal() / 1000 / 1000) . " GB";
    }

    /**
     *
     * @return int total memory (in KB)
     */
Tibo's avatar
Tibo committed
    public function memoryTotal()
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["memory"])) {
Tibo's avatar
Tibo committed
            return null;
Tibo's avatar
Tibo committed
        }

Tibo's avatar
Tibo committed
        return $this->parseMeminfo($record->memory);
Tibo's avatar
Tibo committed
    }

    const MEMINFO = "/^MemTotal:\\s+([0-9]+) kB$/m";
Tibo's avatar
Tibo committed
    public function parseMeminfo($string)
    {
Tibo's avatar
Tibo committed
        $matches = array();
        preg_match(self::MEMINFO, $string, $matches);
        $total = $matches[1];
        return $total;
Tibo's avatar
Tibo committed
    public function lsb()
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["lsb"])) {
            return "unknown";
        }

        return $this->parseLsb($record->lsb);
    }

    const LSB = "/^Description:	(.+)$/m";
Tibo's avatar
Tibo committed
    public function parseLsb($string) : string
Tibo's avatar
Tibo committed
    {
        $matches = [];
        preg_match(self::LSB, $string, $matches);
        return $matches[1];


    const REGEX_MANUFACTURER = "/^\s*Manufacturer: (.*)$/m";
    public function parseManufacturer(string $string) : string
Tibo's avatar
Tibo committed
    {
        $matches = [];
        preg_match(self::REGEX_MANUFACTURER, $string, $matches);

        if (!isset($matches[1])) {
            return "unkwnown";
        }
        return $matches[1];
    }

Tibo's avatar
Tibo committed
    public function manufacturer()
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["system"])) {
            return "unknown";
        }

        return $this->parseManufacturer($record->system);
    }

    const REGEX_PRODUCT_NAME = "/^\s*Product Name: (.*)$/m";
    public function parseProductName(string $string) : string
Tibo's avatar
Tibo committed
    {
        $matches = [];
        preg_match(self::REGEX_PRODUCT_NAME, $string, $matches);
        if (!isset($matches[1])) {
            return "unkwnown";
        }
        return $matches[1];
    }

Tibo's avatar
Tibo committed
    public function productName()
    {
Tibo's avatar
Tibo committed
        $record = $this->lastRecord();
        if (! isset($record["system"])) {
            return "unknown";
        return $this->parseProductName($record->system);
Tibo's avatar
Tibo committed

Tibo's avatar
Tibo committed
    public function getChanges($count = 10)
    {
Tibo's avatar
Tibo committed
        return StatusChange::getLastChangesForServer($this->id, $count);
Tibo's avatar
Tibo committed
    }
Tibo's avatar
Tibo committed
    public static function id($id) : Server
    {
Tibo's avatar
Tibo committed
        return self::where("id", $id)->first();
    }
Tibo's avatar
Tibo committed
}