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

namespace App;

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

Thibault Debatty's avatar
Thibault Debatty committed
/**
 * App\Server
 *
 * @property int $id
 * @property int $organization_id
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property string $name
 * @property string $token
 * @property string $read_token
 * @property-read \App\Organization $organization
 * @method static \Illuminate\Database\Eloquent\Builder|Server newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Server newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Server query()
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereOrganizationId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereReadToken($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereToken($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Server whereUpdatedAt($value)
 * @mixin \Eloquent
 */
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 $info = 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\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");
    }
    
    public function records()
    {
        return $this->hasMany(Record::class);
    }
Tibo's avatar
Tibo committed

    public function lastRecord() : ?Record
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        if ($this->last_record == null) {
            $this->last_record = $this->records()->orderBy("time", "desc")->first();
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
     */
Tibo's avatar
Tibo committed
    public function lastRecords1Day() : Collection
        if ($this->records_1day == null) {
            $start = time() - 24 * 3600;
Tibo's avatar
Tibo committed
            $this->records_1day = $this->records()
                    ->where("time", ">", $start)
                    ->orderBy("time")
                    ->get();
Tibo's avatar
Tibo committed
        return $this->records_1day;
    public function hasData() : bool
    {
        return $this->lastRecord() != null;
    }

Tibo's avatar
Tibo committed
    public function info() : ServerInfo
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        if (is_null($this->info)) {
            $this->info = new ServerInfo($this->lastRecord());
        }
Tibo's avatar
Tibo committed
        return $this->info;
Tibo's avatar
Tibo committed
    }
Tibo's avatar
Tibo committed

Tibo's avatar
Tibo committed
    /**
Tibo's avatar
Tibo committed
     */
Tibo's avatar
Tibo committed
    public function status() : Status
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        return Status::max($this->reports());
Tibo's avatar
Tibo committed
    }

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

Tibo's avatar
Tibo committed
    public function reports()
Tibo's avatar
Tibo committed
    {
Tibo's avatar
Tibo committed
        if (is_null($this->reports)) {
            $records = $this->lastRecords1Day();
            $serverinfo = $this->info();

            $this->reports = [];
            foreach (self::$sensors as $sensor) {
                try {
                     $report = (new $sensor)->analyze($records, $serverinfo);
                     $this->reports[] = $report;
                } catch (\Throwable $ex) {
Tibo's avatar
Tibo committed
                    Log::error('Sensor failed : ' . $ex->getTraceAsString());
                    $report = new Report($sensor, Status::unknown());
                    $report->setHTML("<p>Agent crashed...</p>");
                    $this->reports[] = $report;
                }
            }
Tibo's avatar
Tibo committed
        
        return $this->reports;
Tibo's avatar
Tibo committed
    {
        return $this->hasMany(StatusChange::class);
Tibo's avatar
Tibo committed
    }
    public function lastChanges($count = 10)
    {
        return $this->changes()->orderBy("time", "desc")->limit($count)->get();
    }
    
    public function lastChange() : ?StatusChange
Tibo's avatar
Tibo committed
    {
        return $this->changes()->latest("time")->first();
Tibo's avatar
Tibo committed
    }
Tibo's avatar
Tibo committed
}