Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Health page #469

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d5180f6
add spatie health
Boy132 Jul 8, 2024
c5897ca
change slug for health page
Boy132 Jul 8, 2024
0745ec4
add check for panel version
Boy132 Jul 8, 2024
2ae1fe3
only check for debug mode if env isn't local
Boy132 Jul 8, 2024
236a7b6
add check for node versions
Boy132 Jul 8, 2024
2edc954
improve short summary
Boy132 Jul 8, 2024
5fd9698
fix outdated check
Boy132 Jul 8, 2024
8b1e702
run pint
Boy132 Jul 8, 2024
635bd23
fix health checks during tests
Boy132 Jul 8, 2024
9691166
add count to ok message
Boy132 Jul 8, 2024
d5bcb8d
fix typo
Boy132 Jul 8, 2024
e7f5cf3
temp fix for phpstan job
Boy132 Jul 8, 2024
2530d7a
fix pint...
Boy132 Jul 8, 2024
7a94765
improve "outdated" count
Boy132 Jul 8, 2024
f8f0b54
run pint
Boy132 Jul 8, 2024
1f07e13
skip node versions check if no nodes are created
Boy132 Jul 9, 2024
b92a81e
auto run health checks if they didn't run before
Boy132 Jul 9, 2024
8039627
small refactor
Boy132 Jul 10, 2024
21af2c6
update navigation
Boy132 Jul 12, 2024
135d1ed
fix errors if tests didn't run yet
Boy132 Jul 12, 2024
59b3cd5
fix disk usage check
Boy132 Jul 12, 2024
0b48d5b
Merge branch 'pelican-dev:main' into feature/health
Boy132 Jul 16, 2024
87a87cc
remove plugin and use own page
Boy132 Jul 18, 2024
76039c8
use health status indicator from spatie
Boy132 Jul 18, 2024
f211e68
Merge remote-tracking branch 'origin/main' into feature/health
Boy132 Jul 23, 2024
cb00e54
Merge branch 'refs/heads/main' into feature/health
Boy132 Jul 30, 2024
75a26d8
Merge branch 'refs/heads/main' into feature/health
Boy132 Aug 9, 2024
b1331e5
Merge branch 'pelican-dev:main' into feature/health
Boy132 Aug 19, 2024
9756976
Merge branch 'pelican-dev:main' into feature/health
Boy132 Sep 9, 2024
2b9349b
Merge branch 'main' into feature/health
Boy132 Sep 27, 2024
3b506b2
Merge branch 'main' into feature/health
Boy132 Oct 28, 2024
934554a
fix after merge
Boy132 Oct 28, 2024
6cb8bba
Merge branch 'main' into feature/health
Boy132 Nov 8, 2024
9f26697
update icon
Boy132 Nov 8, 2024
99ac970
update color classes
Boy132 Nov 8, 2024
adb79dd
Merge branch 'main' into feature/health
Boy132 Nov 18, 2024
a5aa4d8
fix after merge
Boy132 Nov 18, 2024
9420816
Merge remote-tracking branch 'origin/main' into feature/health
Boy132 Dec 9, 2024
d242220
add back imports
Boy132 Dec 9, 2024
75feef1
wrong import
Boy132 Dec 9, 2024
5cec84f
update spatie/laravel-health to latest
Boy132 Dec 9, 2024
f7f0b12
move Health page to correct namespace
Boy132 Dec 9, 2024
2c7db05
update NodeVersionsCheck
Boy132 Dec 9, 2024
6e15de3
use style instead of tailwind classes
Boy132 Dec 9, 2024
aebfc48
cleanup custom checks
Boy132 Dec 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions app/Checks/NodeVersionsCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App\Checks;

use App\Models\Node;
use App\Services\Helpers\SoftwareVersionService;
use Spatie\Health\Checks\Check;
use Spatie\Health\Checks\Result;
use Spatie\Health\Enums\Status;

class NodeVersionsCheck extends Check
{
public function run(): Result
{
$all = Node::query()->count();

if ($all === 0) {
$result = Result::make()->notificationMessage('No Nodes created')->shortSummary('No Nodes');
$result->status = Status::skipped();

return $result;
}

$latestVersion = app(SoftwareVersionService::class)->getDaemon();

$outdated = Node::query()->get()
->filter(fn (Node $node) => !isset($node->systemInformation()['exception']) && $node->systemInformation()['version'] !== $latestVersion)
->count();

$result = Result::make()
->meta([
'all' => $all,
'outdated' => $outdated,
])
->shortSummary($outdated === 0 ? 'All up-to-date' : "{$outdated}/{$all} outdated");

return $outdated === 0
? $result->ok('All Nodes are up-to-date')
: $result->failed("`{$outdated}`/`{$all}` Nodes are outdated");
Boy132 marked this conversation as resolved.
Show resolved Hide resolved
}
}
32 changes: 32 additions & 0 deletions app/Checks/PanelVersionCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Checks;

use App\Services\Helpers\SoftwareVersionService;
use Spatie\Health\Checks\Check;
use Spatie\Health\Checks\Result;

class PanelVersionCheck extends Check
{
public function run(): Result
{
/** @var SoftwareVersionService $versionService */
$versionService = app(SoftwareVersionService::class);

$isLatest = $versionService->isLatestPanel();
$currentVersion = $versionService->versionData()['version'];
$latestVersion = $versionService->getPanel();

$result = Result::make()
->meta([
'isLatest' => $isLatest,
'currentVersion' => $currentVersion,
'latestVersion' => $latestVersion,
])
->shortSummary($isLatest ? 'up-to-date' : 'outdated');

return $isLatest
? $result->ok('Panel is up-to-date')
: $result->failed("Installed version is `{$currentVersion}` but latest is `{$latestVersion}`");
Boy132 marked this conversation as resolved.
Show resolved Hide resolved
}
}
16 changes: 16 additions & 0 deletions app/Checks/UsedDiskSpaceCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Checks;

use Spatie\Health\Checks\Checks\UsedDiskSpaceCheck as BaseCheck;

class UsedDiskSpaceCheck extends BaseCheck
{
protected function getDiskUsagePercentage(): int
{
$freeSpace = disk_free_space($this->filesystemName ?? '/');
$totalSpace = disk_total_space($this->filesystemName ?? '/');

return 100 - ($freeSpace * 100 / $totalSpace);
}
}
5 changes: 5 additions & 0 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use App\Console\Commands\Maintenance\PruneOrphanedBackupsCommand;
use App\Console\Commands\Maintenance\CleanServiceBackupFilesCommand;
use App\Console\Commands\Maintenance\PruneImagesCommand;
use Spatie\Health\Commands\RunHealthChecksCommand;
use Spatie\Health\Commands\ScheduleCheckHeartbeatCommand;

class Kernel extends ConsoleKernel
{
Expand Down Expand Up @@ -46,5 +48,8 @@ protected function schedule(Schedule $schedule): void
if (config('activity.prune_days')) {
$schedule->command(PruneCommand::class, ['--model' => [ActivityLog::class]])->daily();
}

$schedule->command(ScheduleCheckHeartbeatCommand::class)->everyMinute();
$schedule->command(RunHealthChecksCommand::class)->everyFiveMinutes();
}
}
114 changes: 114 additions & 0 deletions app/Filament/Pages/Health.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

namespace App\Filament\Pages;

use Carbon\Carbon;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Artisan;
use Spatie\Health\Commands\RunHealthChecksCommand;
use Spatie\Health\ResultStores\ResultStore;

class Health extends Page
{
protected static ?string $navigationIcon = 'tabler-heart';
protected static ?string $navigationGroup = 'Advanced';

protected static string $view = 'filament.pages.health';

protected $listeners = [
'refresh-component' => '$refresh',
];

protected function getActions(): array
{
return [
Action::make('refresh')
->button()
->action('refresh'),
];
}

protected function getViewData(): array
{
$checkResults = app(ResultStore::class)->latestResults();

if ($checkResults === null) {
Artisan::call(RunHealthChecksCommand::class);

$this->dispatch('refresh-component');
}

return [
'lastRanAt' => new Carbon($checkResults?->finishedAt),
'checkResults' => $checkResults,
];
}

public function refresh(): void
{
Artisan::call(RunHealthChecksCommand::class);

$this->dispatch('refresh-component');

Notification::make()
->title('Health check results refreshed')
->success()
->send();
}

public static function getNavigationBadge(): ?string
{
$results = app(ResultStore::class)->latestResults();

if ($results === null) {
return null;
}

$results = json_decode($results->toJson(), true);

$failed = array_reduce($results['checkResults'], function ($numFailed, $result) {
return $numFailed + ($result['status'] === 'failed' ? 1 : 0);
}, 0);

return $failed === 0 ? null : (string) $failed;
}

public static function getNavigationBadgeColor(): string
{
return self::getNavigationBadge() > null ? 'danger' : '';
}

public static function getNavigationBadgeTooltip(): ?string
{
$results = app(ResultStore::class)->latestResults();

if ($results === null) {
return null;
}

$results = json_decode($results->toJson(), true);

$failedNames = array_reduce($results['checkResults'], function ($carry, $result) {
if ($result['status'] === 'failed') {
$carry[] = $result['name'];
}

return $carry;
}, []);

return 'Failed: ' . implode(', ', $failedNames);
}

public static function getNavigationIcon(): string
{
$results = app(ResultStore::class)->latestResults();

if ($results === null) {
return 'tabler-heart-question';
}

return $results->containsFailingCheck() ? 'tabler-heart-exclamation' : 'tabler-heart-check';
}
}
23 changes: 23 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace App\Providers;

use App\Checks\NodeVersionsCheck;
Boy132 marked this conversation as resolved.
Show resolved Hide resolved
use App\Checks\PanelVersionCheck;
use App\Checks\UsedDiskSpaceCheck;
use App\Extensions\Themes\Theme;
use App\Models;
use App\Models\ApiKey;
Expand All @@ -24,6 +27,12 @@
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Laravel\Sanctum\Sanctum;
use Spatie\Health\Checks\Checks\CacheCheck;
use Spatie\Health\Checks\Checks\DatabaseCheck;
use Spatie\Health\Checks\Checks\DebugModeCheck;
use Spatie\Health\Checks\Checks\EnvironmentCheck;
use Spatie\Health\Checks\Checks\ScheduleCheck;
use Spatie\Health\Facades\Health;

class AppServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -93,6 +102,20 @@ public function boot(): void
'warning' => Color::Amber,
]);

// Don't run any health checks during tests
if (!app()->runningUnitTests()) {
Health::checks([
DebugModeCheck::new()->if(app()->isProduction()),
EnvironmentCheck::new(),
CacheCheck::new(),
DatabaseCheck::new(),
ScheduleCheck::new(),
UsedDiskSpaceCheck::new(),
Boy132 marked this conversation as resolved.
Show resolved Hide resolved
PanelVersionCheck::new(),
NodeVersionsCheck::new(),
]);
}

Gate::before(function (User $user, $ability) {
return $user->isRootAdmin() ? true : null;
});
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"s1lentium/iptools": "~1.2.0",
"socialiteproviders/discord": "^4.2",
"spatie/laravel-fractal": "^6.2",
"spatie/laravel-health": "^1.29",
"spatie/laravel-permission": "^6.9",
"spatie/laravel-query-builder": "^5.8.1",
"spatie/temporary-directory": "^2.2",
Expand Down
Loading
Loading