Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ npm i -g yarn
- [Billing](/billing) - Allows users to purchase servers via Stripe - **Proof of Concept - Do absolutely NOT use in production!**
- [Generic OIDC Providers](/generic-oidc-providers) - Create generic OIDC providers for authentication
- [Legal Pages](/legal-pages) - Adds legal pages (Imprint, Privacy Policy, ToS) to the panel
- [McLogCleaner](/mclogcleaner) - Delete old logs with ease
- [MCLogs Uploader](/mclogs-uploader) - Upload console logs to mclo.gs
- [Minecraft Modrinth](/minecraft-modrinth) - Download Minecraft mods & plugins from Modrinth
- [PasteFox Share](/pastefox-share) - Share console logs via pastefox.com
Expand Down
15 changes: 15 additions & 0 deletions mclogcleaner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# McLogCleaner (by JuggleGaming)

McLogCleaner automatically deletes all `.log.gz` files from the server’s `logs` folder.

> **Note:** `latest.log` will always remain intact and is never deleted.

## Setup
To use this plugin, add `mclogcleaner` as a _feature_ to the egg you want to run it with.

## Log Deletion Options
When you click **Delete logs**, a dropdown menu appears where you can choose the **minimum age (in days)** of log files to delete:
- Logs older than 7 days
- Logs older than 30 days
- All logs (regardless of age)
- A custom age in days
15 changes: 15 additions & 0 deletions mclogcleaner/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": "mclogcleaner",
"name": "McLogCleaner",
"author": "JuggleGaming",
"version": "1.1.1",
"description": "Clean your Minecraft-logs with ease",
"category": "plugin",
"url": "https://github.com/pelican-dev/plugins/tree/main/mclogcleaner",
"update_url": null,
"namespace": "JuggleGaming\\McLogCleaner",
"class": "McLogCleanerPlugin",
"panels": null,
"panel_version": null,
"composer_packages": null
}
151 changes: 151 additions & 0 deletions mclogcleaner/src/Filament/Components/Actions/McLogCleanAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

namespace JuggleGaming\McLogCleaner\Filament\Components\Actions;

use App\Models\Server;
use Carbon\Carbon;
use Exception;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Support\Enums\Size;
use Illuminate\Support\Facades\Http;

class McLogCleanAction extends Action
{
public static function getDefaultName(): ?string
{
return 'clean_logs';
}

protected function setUp(): void
{
parent::setUp();
$this->hidden(function () {
/** @var Server|null $server */
$server = Filament::getTenant();
if (!$server) {
return true;
}
$server->loadMissing('egg');
$features = $server->egg->features ?? [];

return !in_array('mclogcleaner', $features, true);
});

$this->label('Delete logs');
$this->icon('tabler-trash');
$this->color('danger');
$this->size(Size::ExtraLarge);
$this->requiresConfirmation()
->modalHeading('Delete logs')
->modalDescription('Choose which logs should be deleted.')
->modalSubmitActionLabel('Delete logs')
->form([
Select::make('mode')
->label('Delete logs')
->options([
7 => 'Older than 7 days',
30 => 'Older than 30 days',
-1 => 'Delete all logs',
'custom' => 'Custom (days)',
])
->default(7)
->required()
->reactive(),
TextInput::make('custom_days')
->label('Delete logs older than (days)')
->numeric()
->minValue(1)
->maxValue(365)
->placeholder('e.g. 14')
->required(fn ($get) => $get('mode') === 'custom')
->visible(fn ($get) => $get('mode') === 'custom'),
]);

$this->action(function (array $data) {
/** @var Server|null $server */
$server = Filament::getTenant();
$mode = $data['mode'];
if ($mode !== 'custom') {
$mode = (int) $mode;
}
if ($mode === 'custom') {
$days = max(1, (int) $data['custom_days']);
} elseif ($mode === -1) {
$days = 0;
} else {
$days = $mode;
}
try {
$files = Http::daemon($server->node)
->get("/api/servers/{$server->uuid}/files/list-directory", [
'directory' => 'logs',
])
->throw()
->json();
if (!is_array($files)) {
throw new Exception('Invalid log directory response.');
}
$threshold = now()->subDays($days)->startOfDay();
$logsToDelete = collect($files)
->filter(fn ($file) => str_ends_with($file['name'], '.log.gz'))
->filter(function ($file) use ($days, $threshold) {
if ($days === 0) {
return true;
}
$logDate = $this->extractLogDate($file['name']);
if (!$logDate) {
return false;
}

return $logDate->lessThan($threshold);
})
->pluck('name')
->map(fn ($name) => 'logs/' . $name)
->values()
->all();
if (empty($logsToDelete)) {
Notification::make()
->title('McLogCleaner')
->body('No logs matching your selection were found.')
->success()
->send();

return;
}
Http::daemon($server->node)
->post("/api/servers/{$server->uuid}/files/delete", [
'root' => '/',
'files' => $logsToDelete,
])
->throw();
Notification::make()
->title('Logfolder cleaned')
->body(count($logsToDelete) . ' files were deleted.')
->success()
->send();
} catch (\Throwable $e) {
report($e);
Notification::make()
->title('Cleanup failed.')
->body('An error occurred while deleting log files. Please try again later.')
->danger()
->send();
}
});
}

private function extractLogDate(string $filename): ?Carbon
{
if (preg_match('/(\d{4}-\d{2}-\d{2})/', $filename, $matches)) {
$date = Carbon::createFromFormat('Y-m-d', $matches[1]);

return $date ? $date->startOfDay() : null;
}

return null;
}
}
24 changes: 24 additions & 0 deletions mclogcleaner/src/McLogCleanerPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace JuggleGaming\McLogCleaner;

use Filament\Contracts\Plugin;
use Filament\Panel;

class McLogCleanerPlugin implements Plugin
{
public function getId(): string
{
return 'mclogcleaner';
}

public function register(Panel $panel): void
{
//
}

public function boot(Panel $panel): void
{
//
}
}
21 changes: 21 additions & 0 deletions mclogcleaner/src/Providers/McLogCleanerPluginProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace JuggleGaming\McLogCleaner\Providers;

use App\Enums\HeaderActionPosition;
use App\Filament\Server\Pages\Console;
use Illuminate\Support\ServiceProvider;
use JuggleGaming\McLogCleaner\Filament\Components\Actions\McLogCleanAction;

class McLogCleanerPluginProvider extends ServiceProvider
{
public function register(): void
{
Console::registerCustomHeaderActions(HeaderActionPosition::Before, McLogCleanAction::make());
}

public function boot(): void
{
//
}
}