diff --git a/app/Console/Commands/GetMetricsCommand.php b/app/Console/Commands/GetMetricsCommand.php new file mode 100644 index 0000000..6711ffd --- /dev/null +++ b/app/Console/Commands/GetMetricsCommand.php @@ -0,0 +1,31 @@ +whereHas('services', function (Builder $query) { + $query->where('type', 'monitoring') + ->where('name', 'remote-monitor'); + })->chunk(10, function ($servers) use (&$checkedMetrics) { + /** @var Server $server */ + foreach ($servers as $server) { + $info = $server->os()->resourceInfo(); + $server->metrics()->create(array_merge($info, ['server_id' => $server->id])); + $checkedMetrics++; + } + }); + $this->info("Checked $checkedMetrics metrics"); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e4aef7c..1e87277 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -17,6 +17,7 @@ protected function schedule(Schedule $schedule): void $schedule->command('backups:run "0 0 * * 0"')->weekly(); $schedule->command('backups:run "0 0 1 * *"')->monthly(); $schedule->command('metrics:delete-older-metrics')->daily(); + $schedule->command('metrics:get')->everyMinute(); } /** diff --git a/app/SSH/OS/OS.php b/app/SSH/OS/OS.php index 4402901..c9aa1ee 100644 --- a/app/SSH/OS/OS.php +++ b/app/SSH/OS/OS.php @@ -166,4 +166,21 @@ public function cleanup(): void 'cleanup' ); } + + public function resourceInfo(): array + { + $info = $this->server->ssh()->exec( + $this->getScript('resource-info.sh'), + ); + + return [ + 'load' => str($info)->after('load:')->before(PHP_EOL)->toString(), + 'memory_total' => str($info)->after('memory_total:')->before(PHP_EOL)->toString(), + 'memory_used' => str($info)->after('memory_used:')->before(PHP_EOL)->toString(), + 'memory_free' => str($info)->after('memory_free:')->before(PHP_EOL)->toString(), + 'disk_total' => str($info)->after('disk_total:')->before(PHP_EOL)->toString(), + 'disk_used' => str($info)->after('disk_used:')->before(PHP_EOL)->toString(), + 'disk_free' => str($info)->after('disk_free:')->before(PHP_EOL)->toString(), + ]; + } } diff --git a/app/SSH/OS/scripts/resource-info.sh b/app/SSH/OS/scripts/resource-info.sh new file mode 100644 index 0000000..78f1f86 --- /dev/null +++ b/app/SSH/OS/scripts/resource-info.sh @@ -0,0 +1,7 @@ +echo "load:$(uptime | awk -F'load average:' '{print $2}' | awk -F, '{print $1}' | tr -d ' ')" +echo "memory_total:$(free -k | awk 'NR==2{print $2}')" +echo "memory_used:$(free -k | awk 'NR==2{print $3}')" +echo "memory_free:$(free -k | awk 'NR==2{print $7}')" +echo "disk_total:$(df -BM / | awk 'NR==2{print $2}' | sed 's/M//')" +echo "disk_used:$(df -BM / | awk 'NR==2{print $3}' | sed 's/M//')" +echo "disk_free:$(df -BM / | awk 'NR==2{print $4}' | sed 's/M//')" diff --git a/app/SSH/Services/Monitoring/RemoteMonitor/RemoteMonitor.php b/app/SSH/Services/Monitoring/RemoteMonitor/RemoteMonitor.php new file mode 100644 index 0000000..0ea6086 --- /dev/null +++ b/app/SSH/Services/Monitoring/RemoteMonitor/RemoteMonitor.php @@ -0,0 +1,53 @@ + [ + function (string $attribute, mixed $value, Closure $fail) { + $monitoringExists = $this->service->server->monitoring(); + if ($monitoringExists) { + $fail('You already have a monitoring service on the server.'); + } + }, + ], + 'version' => [ + 'required', + Rule::in(['latest']), + ], + ]; + } + + public function creationData(array $input): array + { + return [ + 'data_retention' => 10, + ]; + } + + public function data(): array + { + return [ + 'data_retention' => $this->service->type_data['data_retention'] ?? 10, + ]; + } + + public function install(): void + { + // + } + + public function uninstall(): void + { + Metric::where('server_id', $this->service->server_id)->delete(); + } +} diff --git a/app/SSH/Services/VitoAgent/VitoAgent.php b/app/SSH/Services/Monitoring/VitoAgent/VitoAgent.php similarity index 98% rename from app/SSH/Services/VitoAgent/VitoAgent.php rename to app/SSH/Services/Monitoring/VitoAgent/VitoAgent.php index a8c426e..c0bfbc6 100644 --- a/app/SSH/Services/VitoAgent/VitoAgent.php +++ b/app/SSH/Services/Monitoring/VitoAgent/VitoAgent.php @@ -1,6 +1,6 @@ 'firewall', 'supervisor' => 'process_manager', 'vito-agent' => 'monitoring', + 'remote-monitor' => 'monitoring', ], 'service_handlers' => [ 'nginx' => \App\SSH\Services\Webserver\Nginx::class, @@ -152,7 +153,8 @@ 'php' => \App\SSH\Services\PHP\PHP::class, 'ufw' => \App\SSH\Services\Firewall\Ufw::class, 'supervisor' => \App\SSH\Services\ProcessManager\Supervisor::class, - 'vito-agent' => \App\SSH\Services\VitoAgent\VitoAgent::class, + 'vito-agent' => \App\SSH\Services\Monitoring\VitoAgent\VitoAgent::class, + 'remote-monitor' => \App\SSH\Services\Monitoring\RemoteMonitor\RemoteMonitor::class, ], 'service_units' => [ 'nginx' => [ diff --git a/public/static/images/remote-monitor.svg b/public/static/images/remote-monitor.svg new file mode 100644 index 0000000..0e7d376 --- /dev/null +++ b/public/static/images/remote-monitor.svg @@ -0,0 +1,29 @@ + + + + + + + Miscellaneous + + + health-monitoring + + + Health Monitoring + + + image/svg+xml + + + Amido Limited + + + Richard Slater + + + + + + + \ No newline at end of file diff --git a/resources/views/metrics/partials/data-retention.blade.php b/resources/views/metrics/partials/data-retention.blade.php index abe4c66..fe062ac 100644 --- a/resources/views/metrics/partials/data-retention.blade.php +++ b/resources/views/metrics/partials/data-retention.blade.php @@ -22,7 +22,12 @@ class="p-6" @foreach (config("core.metrics_data_retention") as $item) - + @endforeach @error("data_retention") diff --git a/resources/views/services/partials/actions/remote-monitor.blade.php b/resources/views/services/partials/actions/remote-monitor.blade.php new file mode 100644 index 0000000..7e1c6a0 --- /dev/null +++ b/resources/views/services/partials/actions/remote-monitor.blade.php @@ -0,0 +1,6 @@ +@include("services.partials.unit-actions.restart", ["disabled" => true]) +@include("services.partials.unit-actions.start", ["disabled" => true]) +@include("services.partials.unit-actions.stop", ["disabled" => true]) +@include("services.partials.unit-actions.enable", ["disabled" => true]) +@include("services.partials.unit-actions.disable", ["disabled" => true]) +@include("services.partials.unit-actions.uninstall") diff --git a/resources/views/services/partials/installers/remote-monitor.blade.php b/resources/views/services/partials/installers/remote-monitor.blade.php new file mode 100644 index 0000000..843f189 --- /dev/null +++ b/resources/views/services/partials/installers/remote-monitor.blade.php @@ -0,0 +1,37 @@ + + Install + +@push("modals") + +
$server]) }}" + hx-swap="outerHTML" + hx-select="#install-remote-monitor-form" + class="p-6" + > + @csrf + + + + +

+ {{ __("Install Remote Monitor") }} +

+ + @error("type") + + @enderror + +
+ + {{ __("Cancel") }} + + + + {{ __("Install") }} + +
+ +
+@endpush diff --git a/resources/views/services/partials/installers/vito-agent.blade.php b/resources/views/services/partials/installers/vito-agent.blade.php index 4e9a298..45df258 100644 --- a/resources/views/services/partials/installers/vito-agent.blade.php +++ b/resources/views/services/partials/installers/vito-agent.blade.php @@ -21,7 +21,8 @@ class="p-6"
- Vito Agent is only works if you are running your Vito instance on a cloud not local! + Vito Agent is only works if you are running your Vito instance on a cloud not local! Consider + installing remote-monitor instead.
diff --git a/resources/views/services/partials/unit-actions/disable.blade.php b/resources/views/services/partials/unit-actions/disable.blade.php index 8b71fc6..d3c2f1c 100644 --- a/resources/views/services/partials/unit-actions/disable.blade.php +++ b/resources/views/services/partials/unit-actions/disable.blade.php @@ -1,4 +1,5 @@ diff --git a/tests/Unit/Commands/GetMetricsCommandTest.php b/tests/Unit/Commands/GetMetricsCommandTest.php new file mode 100644 index 0000000..75d6465 --- /dev/null +++ b/tests/Unit/Commands/GetMetricsCommandTest.php @@ -0,0 +1,52 @@ +create([ + 'server_id' => $this->server->id, + 'name' => 'remote-monitor', + 'type' => 'monitoring', + 'type_data' => [ + 'data_retention' => 7, + ], + 'version' => 'latest', + 'status' => ServiceStatus::READY, + ]); + + $this->artisan('metrics:get') + ->expectsOutput('Checked 1 metrics'); + + $this->assertDatabaseHas('metrics', [ + 'server_id' => $this->server->id, + 'load' => 1, + 'memory_total' => 1, + 'memory_used' => 1, + 'memory_free' => 1, + 'disk_total' => 1, + 'disk_used' => 1, + 'disk_free' => 1, + ]); + } +}