Skip to content

Commit

Permalink
Merge pull request #1551 from AndyTWF/plugin-logging
Browse files Browse the repository at this point in the history
feat: endpoint to capture logs from plugin
  • Loading branch information
AndyTWF authored Apr 14, 2024
2 parents 4d0a048 + 454113b commit 449b86c
Show file tree
Hide file tree
Showing 19 changed files with 433 additions and 5 deletions.
69 changes: 69 additions & 0 deletions app/Filament/Resources/PluginLogResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace App\Filament\Resources;

use App\Filament\Resources\PluginLogResource\Pages;
use App\Models\Plugin\PluginLog;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Resources\Form;
use Filament\Tables\Columns\TextColumn;

class PluginLogResource extends Resource
{
use TranslatesStrings;

protected static ?string $model = PluginLog::class;

protected static ?string $navigationIcon = 'heroicon-o-rss';
protected static ?string $navigationGroup = 'Administration';

public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('id')
->label(self::translateFormPath('id.label'))
->required(),
TextInput::make('type')
->label(self::translateFormPath('type.label'))
->required(),
TextInput::make('message')
->label(self::translateFormPath('message.label'))
->required(),
Textarea::make('metadata')
->columnSpan('full')
->formatStateUsing(fn (array|null $state) => json_encode($state, JSON_PRETTY_PRINT))
->label(self::translateFormPath('metadata.label'))
->required(),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('id')
->label(self::translateTablePath('columns.id')),
TextColumn::make('type')
->label(self::translateTablePath('columns.type')),
TextColumn::make('created_at')
->label(self::translateTablePath('columns.created_at')),
]);
}

public static function getPages(): array
{
return [
'index' => Pages\ListPluginLogs::route('/'),
'view' => Pages\ViewPluginLog::route('/{record}'),
];
}

protected static function translationPathRoot(): string
{
return 'plugin';
}
}
14 changes: 14 additions & 0 deletions app/Filament/Resources/PluginLogResource/Pages/ListPluginLogs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Filament\Resources\PluginLogResource\Pages;

use App\Filament\Resources\Pages\LimitsTableRecordListingOptions;
use App\Filament\Resources\PluginLogResource;
use Filament\Resources\Pages\ListRecords;

class ListPluginLogs extends ListRecords
{
use LimitsTableRecordListingOptions;

protected static string $resource = PluginLogResource::class;
}
11 changes: 11 additions & 0 deletions app/Filament/Resources/PluginLogResource/Pages/ViewPluginLog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Filament\Resources\PluginLogResource\Pages;

use App\Filament\Resources\PluginLogResource;
use Filament\Resources\Pages\ViewRecord;

class ViewPluginLog extends ViewRecord
{
protected static string $resource = PluginLogResource::class;
}
21 changes: 21 additions & 0 deletions app/Http/Controllers/PluginLogController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Http\Controllers;

use App\Models\Plugin\PluginLog;
use App\Http\Requests\Plugin\PluginLog as PluginLogRequest;
use Illuminate\Http\JsonResponse;

class PluginLogController extends BaseController
{
public function createPluginLogEntry(PluginLogRequest $log): JsonResponse
{
$validated = $log->validated();
if (isset($validated['metadata'])) {
$validated['metadata'] = json_decode($validated['metadata']);
}

$pluginLog = PluginLog::create($validated);
return response()->json(['id' => $pluginLog->id], 201);
}
}
22 changes: 22 additions & 0 deletions app/Http/Requests/Plugin/PluginLog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Http\Requests\Plugin;

use Illuminate\Foundation\Http\FormRequest;

class PluginLog extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'type' => 'required|string|max:255',
'message' => 'required|string|max:255',
'metadata' => 'nullable|json',
];
}
}
25 changes: 25 additions & 0 deletions app/Models/Plugin/PluginLog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Models\Plugin;

use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class PluginLog extends Model
{
use HasFactory;
use HasUuids;

const UPDATED_AT = null;

protected $fillable = [
'type',
'message',
'metadata',
];

protected $casts = [
'metadata' => 'array',
];
}
12 changes: 7 additions & 5 deletions app/Providers/AuthServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use App\Models\IntentionCode\IntentionCode;
use App\Models\Navigation\Navaid;
use App\Models\Notification\Notification;
use App\Models\Plugin\PluginLog;
use App\Models\Runway\Runway;
use App\Models\Sid;
use App\Models\Squawk\AirfieldPairing\AirfieldPairingSquawkRange;
Expand Down Expand Up @@ -66,7 +67,7 @@ class AuthServiceProvider extends ServiceProvider

// These policies are used by filament to determine resource and action access.
protected $policies = [
// The defaults
// The defaults
Aircraft::class => OperationsContributorPolicy::class,
Airfield::class => DefaultFilamentPolicy::class,
AirfieldPairingSquawkRange::class => DefaultFilamentPolicy::class,
Expand All @@ -91,21 +92,22 @@ class AuthServiceProvider extends ServiceProvider
UnitDiscreteSquawkRangeGuest::class => DefaultFilamentPolicy::class,
WakeCategory::class => OperationsContributorPolicy::class,

// Things the plugin can assign
// Things the plugin can assign
SquawkAssignment::class => PluginEditableDataPolicy::class,

// Things that can only be updated by external processes
// Things that can only be updated by external processes
SrdNote::class => ReadOnlyPolicy::class,
SrdRoute::class => ReadOnlyPolicy::class,
Dependency::class => ReadOnlyPolicy::class,

// Things that can only be viewed by users with a role
// Things that can only be viewed by users with a role
StandAssignmentsHistory::class => ReadOnlyWithRolePolicy::class,

// Special policies
// Special policies
Activity::class => ActivityLogPolicy::class,
User::class => UserPolicy::class,
Version::class => PluginVersionPolicy::class,
PluginLog::class => ActivityLogPolicy::class,
];

/**
Expand Down
2 changes: 2 additions & 0 deletions config/filament-logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use App\Filament\Resources\ActivityResource;
use App\Filament\Resources\DependencyResource;
use App\Filament\Resources\PluginLogResource;
use App\Filament\Resources\SquawkAssignmentResource;

return [
Expand All @@ -15,6 +16,7 @@
'exclude' => [
SquawkAssignmentResource::class,
DependencyResource::class,
PluginLogResource::class,
],
],

Expand Down
33 changes: 33 additions & 0 deletions database/factories/Plugin/PluginLogFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Database\Factories\Plugin;

use App\Models\Plugin\PluginLog;
use Illuminate\Database\Eloquent\Factories\Factory;

class PluginLogFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = PluginLog::class;

/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'type' => 'FATAL_EXCEPTION',
'message' => $this->faker->sentence(),
'metadata' => [
'foo' => $this->faker->sentence(),
'bar' => $this->faker->sentence(),
],
];
}
}
29 changes: 29 additions & 0 deletions database/migrations/2024_04_14_132135_create_plugin_logs_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('plugin_logs', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('type')->index()->comment('The type of log, for easy searching');
$table->text('message')->comment('The message of the log');
$table->json('metadata')->nullable()->comment('The context of the log');
$table->timestamp('created_at')->comment('The time the log was created');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('plugin_logs');
}
};
3 changes: 3 additions & 0 deletions database/seeds/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class DatabaseSeeder extends Seeder
PluginEventTableSeeder::class => [
'plugin_events',
],
PluginLogTableSeeder::class => [
'plugin_logs',
],
DepartureReleaseTableSeeder::class => [
'departure_release_requests',
],
Expand Down
12 changes: 12 additions & 0 deletions database/seeds/PluginLogTableSeeder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

use App\Models\Plugin\PluginLog;
use Illuminate\Database\Seeder;

class PluginLogTableSeeder extends Seeder
{
public function run()
{
PluginLog::factory()->create();
}
}
1 change: 1 addition & 0 deletions lang/en/form.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'sids' => require_once __DIR__ . '/sids/form.php',
'handoffs' => require_once __DIR__ . '/handoffs/form.php',
'holds' => require_once __DIR__ . '/holds/form.php',
'plugin' => require_once __DIR__ . '/plugin/form.php',
'prenotes' => require_once __DIR__ . '/prenotes/form.php',
'runways' => require_once __DIR__ . '/runways/form.php',
'controllers' => require_once __DIR__ . '/controllers/form.php',
Expand Down
16 changes: 16 additions & 0 deletions lang/en/plugin/form.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

return [
'id' => [
'label' => 'ID',
],
'type' => [
'label' => 'Type',
],
'message' => [
'label' => 'Message',
],
'metadata' => [
'label' => 'Metadata',
],
];
9 changes: 9 additions & 0 deletions lang/en/plugin/table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

return [
'columns' => [
'id' => 'ID',
'type' => 'Type',
'created_at' => 'Timestamp',
],
];
1 change: 1 addition & 0 deletions lang/en/table.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
'sids' => require_once __DIR__ . '/sids/table.php',
'handoffs' => require_once __DIR__ . '/handoffs/table.php',
'holds' => require_once __DIR__ . '/holds/table.php',
'plugin' => require_once __DIR__ . '/plugin/table.php',
'prenotes' => require_once __DIR__ . '/prenotes/table.php',
'controllers' => require_once __DIR__ . '/controllers/table.php',
'navaids' => require_once __DIR__ . '/navaids/table.php',
Expand Down
12 changes: 12 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Http\Controllers\MissedApproachController;
use App\Http\Controllers\PluginLogController;
use App\Http\Controllers\PrenoteMessageController;
use App\Rules\VatsimCallsign;
use Illuminate\Support\Facades\Route;
Expand Down Expand Up @@ -60,6 +61,17 @@ function () {
Route::get('plugin-events/sync', 'PluginEventsController@getLatestPluginEventId');
Route::get('plugin-events/recent', 'PluginEventsController@getRecentPluginEvents');

// Logs
Route::prefix('plugin')->group(
function () {
Route::prefix('logs')->controller(PluginLogController::class)->group(
function () {
Route::post('', 'createPluginLogEntry');
}
);
}
);

// Holds
Route::put('hold/assigned', 'HoldController@assignHold');
Route::delete('hold/assigned/{callsign}', 'HoldController@deleteAssignedHold')
Expand Down
Loading

0 comments on commit 449b86c

Please sign in to comment.