mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 06:56:15 +00:00
#591 - monitoring
This commit is contained in:
@ -7,6 +7,7 @@
|
||||
use Illuminate\Contracts\Database\Query\Expression;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class GetMetrics
|
||||
@ -17,8 +18,13 @@ class GetMetrics
|
||||
*/
|
||||
public function filter(Server $server, array $input): Collection
|
||||
{
|
||||
if (isset($input['from']) && isset($input['to']) && $input['from'] === $input['to']) {
|
||||
Validator::make($input, self::rules($input))->validate();
|
||||
|
||||
if (isset($input['from'])) {
|
||||
$input['from'] = Carbon::parse($input['from'])->format('Y-m-d').' 00:00:00';
|
||||
}
|
||||
|
||||
if (isset($input['to'])) {
|
||||
$input['to'] = Carbon::parse($input['to'])->format('Y-m-d').' 23:59:59';
|
||||
}
|
||||
|
||||
@ -145,8 +151,8 @@ public static function rules(array $input): array
|
||||
];
|
||||
|
||||
if (isset($input['period']) && $input['period'] === 'custom') {
|
||||
$rules['from'] = ['required', 'date', 'before:to'];
|
||||
$rules['to'] = ['required', 'date', 'after:from'];
|
||||
$rules['from'] = ['required', 'date', 'before_or_equal:to'];
|
||||
$rules['to'] = ['required', 'date', 'after_or_equal:from'];
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
@ -5,6 +5,7 @@
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\ServiceInterface;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateMetricSettings
|
||||
{
|
||||
@ -13,6 +14,8 @@ class UpdateMetricSettings
|
||||
*/
|
||||
public function update(Server $server, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules())->validate();
|
||||
|
||||
/** @var Service $service */
|
||||
$service = $server->monitoring();
|
||||
/** @var ServiceInterface $handler */
|
||||
|
95
app/Http/Controllers/MonitoringController.php
Normal file
95
app/Http/Controllers/MonitoringController.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Monitoring\GetMetrics;
|
||||
use App\Actions\Monitoring\UpdateMetricSettings;
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Models\Metric;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Spatie\RouteAttributes\Attributes\Delete;
|
||||
use Spatie\RouteAttributes\Attributes\Get;
|
||||
use Spatie\RouteAttributes\Attributes\Middleware;
|
||||
use Spatie\RouteAttributes\Attributes\Patch;
|
||||
use Spatie\RouteAttributes\Attributes\Prefix;
|
||||
|
||||
#[Prefix('servers/{server}/monitoring')]
|
||||
#[Middleware(['auth', 'has-project'])]
|
||||
class MonitoringController extends Controller
|
||||
{
|
||||
#[Get('/', name: 'monitoring')]
|
||||
public function index(Server $server): Response
|
||||
{
|
||||
$this->authorize('viewAny', [Metric::class, $server]);
|
||||
|
||||
return Inertia::render('monitoring/index', [
|
||||
'lastMetric' => $server->metrics()->latest()->first(),
|
||||
'dataRetention' => $server->monitoring()?->type_data['data_retention'] ?? 30,
|
||||
'hasMonitoringService' => $server->monitoring()?->status === ServiceStatus::READY,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Get('/json', name: 'monitoring.json')]
|
||||
public function json(Request $request, Server $server): JsonResponse
|
||||
{
|
||||
$this->authorize('viewAny', [Metric::class, $server]);
|
||||
|
||||
$metrics = app(GetMetrics::class)->filter($server, $request->input());
|
||||
|
||||
return response()->json($metrics);
|
||||
}
|
||||
|
||||
#[Get('/{metric}', name: 'monitoring.show')]
|
||||
public function show(Server $server, string $metric): Response
|
||||
{
|
||||
if (! in_array($metric, ['load', 'memory', 'disk'])) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$this->authorize('viewAny', [Metric::class, $server]);
|
||||
|
||||
return Inertia::render('monitoring/show', [
|
||||
'metric' => $metric,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Patch('/update', name: 'monitoring.update')]
|
||||
public function update(Request $request, Server $server): RedirectResponse
|
||||
{
|
||||
/** @var ?Service $monitoring */
|
||||
$monitoring = $server->monitoring();
|
||||
|
||||
if (! $monitoring) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$this->authorize('update', $monitoring);
|
||||
|
||||
app(UpdateMetricSettings::class)->update($server, $request->input());
|
||||
|
||||
return back()->with('success', 'Settings updated!');
|
||||
}
|
||||
|
||||
#[Delete('/reset', name: 'monitoring.destroy')]
|
||||
public function destroy(Server $server): RedirectResponse
|
||||
{
|
||||
/** @var ?Service $monitoring */
|
||||
$monitoring = $server->monitoring();
|
||||
|
||||
if (! $monitoring) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$this->authorize('update', $monitoring);
|
||||
|
||||
$server->metrics()->delete();
|
||||
|
||||
return back()->with('success', 'All metrics deleted!');
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Database\Factories\MetricFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@ -29,7 +30,7 @@
|
||||
*/
|
||||
class Metric extends Model
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\MetricFactory> */
|
||||
/** @use HasFactory<MetricFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\ServerLogFactory;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@ -25,7 +26,7 @@
|
||||
*/
|
||||
class ServerLog extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\ServerLogFactory> */
|
||||
/** @use HasFactory<ServerLogFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
@ -103,6 +104,10 @@ public function download(): StreamedResponse
|
||||
return Storage::disk('local')->download($tmpName, str($this->name)->afterLast('/'));
|
||||
}
|
||||
|
||||
if (! Storage::disk($this->disk)->exists($this->name)) {
|
||||
abort(404, "Log file doesn't exist or is empty!");
|
||||
}
|
||||
|
||||
return Storage::disk($this->disk)->download($this->name);
|
||||
}
|
||||
|
||||
@ -114,7 +119,7 @@ public static function getRemote(Builder $query, bool $active = true, ?Site $sit
|
||||
{
|
||||
$query->where('is_remote', $active);
|
||||
|
||||
if ($site instanceof \App\Models\Site) {
|
||||
if ($site instanceof Site) {
|
||||
$query->where('name', 'like', $site->path.'%');
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
||||
use App\SSH\Services\ServiceInterface;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use Database\Factories\ServiceFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
@ -28,7 +29,7 @@
|
||||
*/
|
||||
class Service extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\ServiceFactory> */
|
||||
/** @use HasFactory<ServiceFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -14,7 +14,6 @@ class MetricPolicy
|
||||
public function viewAny(User $user, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->service('monitoring') &&
|
||||
$server->isReady();
|
||||
}
|
||||
|
||||
@ -22,28 +21,24 @@ public function view(User $user, Metric $metric): bool
|
||||
{
|
||||
|
||||
return ($user->isAdmin() || $metric->server->project->users->contains($user)) &&
|
||||
$metric->server->service('monitoring') &&
|
||||
$metric->server->isReady();
|
||||
}
|
||||
|
||||
public function create(User $user, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->service('monitoring') &&
|
||||
$server->isReady();
|
||||
}
|
||||
|
||||
public function update(User $user, Metric $metric): bool
|
||||
{
|
||||
return ($user->isAdmin() || $metric->server->project->users->contains($user)) &&
|
||||
$metric->server->service('monitoring') &&
|
||||
$metric->server->isReady();
|
||||
}
|
||||
|
||||
public function delete(User $user, Metric $metric): bool
|
||||
{
|
||||
return ($user->isAdmin() || $metric->server->project->users->contains($user)) &&
|
||||
$metric->server->service('monitoring') &&
|
||||
$metric->server->isReady();
|
||||
}
|
||||
}
|
||||
|
@ -122,4 +122,13 @@ protected function addUfw(): void
|
||||
'version' => 'latest',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function addMonitoring(): void
|
||||
{
|
||||
$this->server->services()->create([
|
||||
'type' => 'monitoring',
|
||||
'name' => 'remote-monitor',
|
||||
'version' => 'latest',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -39,5 +39,6 @@ public function createServices(array $input): void
|
||||
$this->addSupervisor();
|
||||
$this->addRedis();
|
||||
$this->addUfw();
|
||||
$this->addMonitoring();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user