Skip to content

Commit

Permalink
Added event logging in database (#8)
Browse files Browse the repository at this point in the history
* Added event logging in database

* feedback

* fixed table for magento webhooks

* code review feedback

* bumped phpunit version
  • Loading branch information
fritsjustbetter committed Feb 1, 2024
1 parent e72545f commit 50c4ac8
Show file tree
Hide file tree
Showing 17 changed files with 343 additions and 16 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,35 @@ Publish the configuration of the package.
php artisan vendor:publish --provider="JustBetter\MagentoWebhooks\ServiceProvider" --tag=config
```

Run the migration for the event logs.

```shell
php artisan migrate
```

## Configuration

The `events` array located in your configuration can be used to add events.

By default, **no middleware** is present on the webhook url. This can be changed by adding your own middleware to
the `middleware` array, like authentication.

### Schedule clean up command

In order to keep the database from filling up, schedule the `CleanLogsCommand` in your Kernel.

```php
use JustBetter\MagentoWebhooks\Commands\CleanLogsCommand;

$schedule->command(CleanLogsCommand::class)->daily();
```

This command supports usage of a custom date. You can pass a date as a parameter which will clean logs from before this date. This date defaults to one month prior.

```shell
php artisan magento:webhooks:clean-logs --date="yesterday"
```

## Magento Webhook Configuration

The following configuration can be used in order to successfully work with webhooks.
Expand Down
14 changes: 14 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Upgrade guide

## 1.x to 2.x

2.x introduces the use of a database to log files

### Database usage

A migration has been added to this package to keep historical data of all the event webhooks. This means that using a database has become mandatory.

### Scheduling clean up

In order to keep the logs from bloating up disk usage, we've added a `CleanLogsCommand` which defaults to a month if no parameters have been passed.
Add this to your scheduler.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"nunomaduro/larastan": "^2.5",
"orchestra/testbench": "^8.11",
"phpstan/phpstan-mockery": "^1.1",
"phpunit/phpunit": "^10.0"
"phpunit/phpunit": "^10.5"
},
"autoload": {
"psr-4": {
Expand Down
23 changes: 23 additions & 0 deletions database/migrations/2024_01_24_153000_create_event_log_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

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

return new class extends Migration
{
public function up(): void
{
Schema::create('magento_webhooks_event_logs', function (Blueprint $table): void {
$table->id();
$table->string('event')->index();
$table->json('data')->nullable();
$table->timestamps();
});
}

public function down(): void
{
Schema::dropIfExists('magento_webhooks_event_logs');
}
};
26 changes: 11 additions & 15 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Tests">
<directory>./tests/*</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="Tests">
<directory>./tests/*</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>
22 changes: 22 additions & 0 deletions src/Actions/CleanLogs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace JustBetter\MagentoWebhooks\Actions;

use Illuminate\Support\Carbon;
use JustBetter\MagentoWebhooks\Contracts\CleansLogs;
use JustBetter\MagentoWebhooks\Models\EventLog;

class CleanLogs implements CleansLogs
{
public function clean(Carbon $date): void
{
EventLog::query()
->where('created_at', '<', $date)
->delete();
}

public static function bind(): void
{
app()->singleton(CleansLogs::class, static::class);
}
}
6 changes: 6 additions & 0 deletions src/Actions/DispatchEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Event;
use JustBetter\MagentoWebhooks\Contracts\DispatchesEvents;
use JustBetter\MagentoWebhooks\Models\EventLog;

class DispatchEvents implements DispatchesEvents
{
public function dispatch(string $event, array $data): void
{
EventLog::query()->create([
'event' => $event,
'data' => $data,
]);

$events = config('magento-webhooks.events');

if (! isset($events[$event])) {
Expand Down
28 changes: 28 additions & 0 deletions src/Commands/CleanLogsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace JustBetter\MagentoWebhooks\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use JustBetter\MagentoWebhooks\Jobs\CleanLogsJob;

class CleanLogsCommand extends Command
{
protected $signature = 'magento:webhooks:clean-logs {--date=}';

protected $description = 'Cleans event logs based on date';

public function handle(): int
{
/** @var ?string $date */
$date = $this->option('date');

$date = $date !== null
? Carbon::parse($date)
: now()->subMonth();

CleanLogsJob::dispatch($date);

return static::SUCCESS;
}
}
10 changes: 10 additions & 0 deletions src/Contracts/CleansLogs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace JustBetter\MagentoWebhooks\Contracts;

use Illuminate\Support\Carbon;

interface CleansLogs
{
public function clean(Carbon $date): void;
}
29 changes: 29 additions & 0 deletions src/Jobs/CleanLogsJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace JustBetter\MagentoWebhooks\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Carbon;
use JustBetter\MagentoWebhooks\Contracts\CleansLogs;

class CleanLogsJob implements ShouldBeUnique, ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;

public function __construct(
protected Carbon $date,
) {
$this->onQueue(config('magento-webhooks.queue'));
}

public function handle(CleansLogs $contract): void
{
$contract->clean($this->date);
}
}
24 changes: 24 additions & 0 deletions src/Models/EventLog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace JustBetter\MagentoWebhooks\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

/**
* @property int $id
* @property string $event
* @property ?array $data
* @property ?Carbon $created_at
* @property ?Carbon $updated_at
*/
class EventLog extends Model
{
protected $table = 'magento_webhooks_event_logs';

protected $guarded = [];

protected $casts = [
'data' => 'array',
];
}
23 changes: 23 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
use JustBetter\MagentoWebhooks\Actions\CleanLogs;
use JustBetter\MagentoWebhooks\Actions\DispatchEvents;
use JustBetter\MagentoWebhooks\Commands\CleanLogsCommand;

class ServiceProvider extends BaseServiceProvider
{
Expand All @@ -25,6 +27,7 @@ protected function registerConfig(): static
protected function registerActions(): static
{
DispatchEvents::bind();
CleanLogs::bind();

return $this;
}
Expand All @@ -33,6 +36,8 @@ public function boot(): void
{
$this
->bootConfig()
->bootCommands()
->bootMigrations()
->bootRoutes();
}

Expand All @@ -55,4 +60,22 @@ protected function bootRoutes(): static

return $this;
}

protected function bootMigrations(): static
{
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');

return $this;
}

protected function bootCommands(): static
{
if ($this->app->runningInConsole()) {
$this->commands([
CleanLogsCommand::class,
]);
}

return $this;
}
}
32 changes: 32 additions & 0 deletions tests/Actions/CleanLogsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace JustBetter\MagentoWebhooks\Tests\Actions;

use JustBetter\MagentoWebhooks\Actions\CleanLogs;
use JustBetter\MagentoWebhooks\Models\EventLog;
use JustBetter\MagentoWebhooks\Tests\TestCase;

class CleanLogsTest extends TestCase
{
/** @test */
public function it_cleans_logs(): void
{
EventLog::query()->create([
'event' => 'some-event',
'data' => ['some' => 'value'],
'created_at' => now()->subMonths(2),
]);

EventLog::query()->create([
'event' => 'some-event',
'data' => ['some' => 'value'],
'created_at' => now(),
]);

/** @var CleanLogs $action */
$action = app(CleanLogs::class);
$action->clean(now()->subMonth());

$this->assertEquals(1, EventLog::query()->count());
}
}
25 changes: 25 additions & 0 deletions tests/Actions/DispatchEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Support\Facades\Event;
use JustBetter\MagentoWebhooks\Actions\DispatchEvents;
use JustBetter\MagentoWebhooks\Models\EventLog;
use JustBetter\MagentoWebhooks\Tests\Fakes\Events\FakeEvent;
use JustBetter\MagentoWebhooks\Tests\TestCase;

Expand Down Expand Up @@ -85,4 +86,28 @@ public function it_can_skip_dispatching_events(): void

Event::assertNotDispatched(FakeEvent::class);
}

/** @test */
public function it_logs_events_in_database(): void
{
Event::fake();

config()->set('magento-webhooks.events', [
'test-event' => [
FakeEvent::class,
],
]);

/** @var DispatchEvents $dispatchEvents */
$dispatchEvents = app(DispatchEvents::class);
$dispatchEvents->dispatch('test-event', ['some' => 'value']);

$log = EventLog::query()
->where('event', '=', 'test-event')
->firstOrFail();

$this->assertEquals([
'some' => 'value',
], $log->data);
}
}
Loading

0 comments on commit 50c4ac8

Please sign in to comment.