From 3e521268d43442ade873a4fc910360a75f67c50f Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Tue, 18 Aug 2020 21:22:29 +0300 Subject: [PATCH 1/2] Added customizable driver for the store --- config/websockets.php | 19 ++- docs/debugging/dashboard.md | 8 ++ src/Console/CleanStatistics.php | 19 +-- src/Statistics/Drivers/DatabaseDriver.php | 113 ++++++++++++++++++ src/Statistics/Drivers/StatisticsDriver.php | 67 +++++++++++ src/Statistics/Events/StatisticsUpdated.php | 24 ++-- .../WebSocketStatisticsEntriesController.php | 12 +- src/WebSocketsServiceProvider.php | 11 ++ 8 files changed, 235 insertions(+), 38 deletions(-) create mode 100644 src/Statistics/Drivers/DatabaseDriver.php create mode 100644 src/Statistics/Drivers/StatisticsDriver.php diff --git a/config/websockets.php b/config/websockets.php index b4256118fe..fd1d32ba9a 100644 --- a/config/websockets.php +++ b/config/websockets.php @@ -178,16 +178,25 @@ /* |-------------------------------------------------------------------------- - | Statistics Eloquent Model + | Statistics Driver |-------------------------------------------------------------------------- | - | This model will be used to store the statistics of the WebSocketsServer. - | The only requirement is that the model should extend - | `WebSocketsStatisticsEntry` provided by this package. + | Here you can specify which driver to use to store the statistics to. + | See down below for each driver's setting. + | + | Available: database | */ - 'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class, + 'driver' => 'database', + + 'database' => [ + + 'driver' => \BeyondCode\LaravelWebSockets\Statistics\Drivers\DatabaseDriver::class, + + 'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class, + + ], /* |-------------------------------------------------------------------------- diff --git a/docs/debugging/dashboard.md b/docs/debugging/dashboard.md index a3fbca71a0..b37194d300 100644 --- a/docs/debugging/dashboard.md +++ b/docs/debugging/dashboard.md @@ -92,6 +92,14 @@ However, to disable it entirely and void any incoming statistic, you can uncomme 'logger' => \BeyondCode\LaravelWebSockets\Statistics\Logger\NullStatisticsLogger::class, // use the `NullStatisticsLogger` instead ``` +## Custom Statistics Drivers + +By default, the package comes with a few drivers like the Database driver which stores the data into the database. + +You should add your custom drivers under the `statistics` key in `websockets.php` and create a driver class that implements the `\BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver` interface. + +Take a quick look at the `\BeyondCode\LaravelWebSockets\Statistics\Drivers\DatabaseDriver` driver to see how to perform your integration. + ## Event Creator The dashboard also comes with an easy-to-use event creator, that lets you manually send events to your channels. diff --git a/src/Console/CleanStatistics.php b/src/Console/CleanStatistics.php index 786ff37c24..5fc3c4d0e8 100644 --- a/src/Console/CleanStatistics.php +++ b/src/Console/CleanStatistics.php @@ -2,7 +2,7 @@ namespace BeyondCode\LaravelWebSockets\Console; -use Carbon\Carbon; +use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; use Illuminate\Console\Command; use Illuminate\Database\Eloquent\Builder; @@ -27,25 +27,14 @@ class CleanStatistics extends Command /** * Run the command. * + * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver * @return void */ - public function handle() + public function handle(StatisticsDriver $driver) { $this->comment('Cleaning WebSocket Statistics...'); - $appId = $this->argument('appId'); - - $maxAgeInDays = config('websockets.statistics.delete_statistics_older_than_days'); - - $cutOffDate = Carbon::now()->subDay($maxAgeInDays)->format('Y-m-d H:i:s'); - - $class = config('websockets.statistics.model'); - - $amountDeleted = $class::where('created_at', '<', $cutOffDate) - ->when(! is_null($appId), function (Builder $query) use ($appId) { - $query->where('app_id', $appId); - }) - ->delete(); + $amountDeleted = $driver::delete($this->argument('appId')); $this->info("Deleted {$amountDeleted} record(s) from the WebSocket statistics."); } diff --git a/src/Statistics/Drivers/DatabaseDriver.php b/src/Statistics/Drivers/DatabaseDriver.php new file mode 100644 index 0000000000..0097c4b229 --- /dev/null +++ b/src/Statistics/Drivers/DatabaseDriver.php @@ -0,0 +1,113 @@ +record = $record; + } + + /** + * Get the app ID for the stats. + * + * @return mixed + */ + public function getAppId() + { + return $this->record->app_id; + } + + /** + * Get the time value. Should be Y-m-d H:i:s. + * + * @return string + */ + public function getTime(): string + { + return Carbon::parse($this->record->created_at)->toDateTimeString(); + } + + /** + * Get the peak connection count for the time. + * + * @return int + */ + public function getPeakConnectionCount(): int + { + return $this->record->peak_connection_count ?? 0; + } + + /** + * Get the websocket messages count for the time. + * + * @return int + */ + public function getWebsocketMessageCount(): int + { + return $this->record->websocket_message_count ?? 0; + } + + /** + * Get the API message count for the time. + * + * @return int + */ + public function getApiMessageCount(): int + { + return $this->record->api_message_count ?? 0; + } + + /** + * Create a new statistic in the store. + * + * @param array $data + * @return \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver + */ + public static function create(array $data): StatisticsDriver + { + $class = config('websockets.statistics.database.model'); + + return new static($class::create($data)); + } + + /** + * Delete statistics from the store, + * optionally by app id, returning + * the number of deleted records. + * + * @param mixed $appId + * @return int + */ + public static function delete($appId = null): int + { + $cutOffDate = Carbon::now()->subDay( + config('websockets.statistics.delete_statistics_older_than_days') + )->format('Y-m-d H:i:s'); + + $class = config('websockets.statistics.database.model'); + + return $class::where('created_at', '<', $cutOffDate) + ->when($appId, function ($query) use ($appId) { + return $query->whereAppId($appId); + }) + ->delete(); + } +} diff --git a/src/Statistics/Drivers/StatisticsDriver.php b/src/Statistics/Drivers/StatisticsDriver.php new file mode 100644 index 0000000000..8ed1e5ec02 --- /dev/null +++ b/src/Statistics/Drivers/StatisticsDriver.php @@ -0,0 +1,67 @@ +webSocketsStatisticsEntry = $webSocketsStatisticsEntry; + $this->driver = $driver; } /** @@ -39,11 +39,11 @@ public function __construct(WebSocketsStatisticsEntry $webSocketsStatisticsEntry public function broadcastWith() { return [ - 'time' => (string) $this->webSocketsStatisticsEntry->created_at, - 'app_id' => $this->webSocketsStatisticsEntry->app_id, - 'peak_connection_count' => $this->webSocketsStatisticsEntry->peak_connection_count, - 'websocket_message_count' => $this->webSocketsStatisticsEntry->websocket_message_count, - 'api_message_count' => $this->webSocketsStatisticsEntry->api_message_count, + 'time' => $this->driver->getTime(), + 'app_id' => $this->driver->getAppId(), + 'peak_connection_count' => $this->driver->getPeakConnectionCount(), + 'websocket_message_count' => $this->driver->getWebsocketMessageCount(), + 'api_message_count' => $this->driver->getApiMessageCount(), ]; } diff --git a/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php b/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php index 312230a32d..bf9453bbe3 100644 --- a/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php +++ b/src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php @@ -2,6 +2,7 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Http\Controllers; +use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; use BeyondCode\LaravelWebSockets\Statistics\Events\StatisticsUpdated; use BeyondCode\LaravelWebSockets\Statistics\Rules\AppId; use Illuminate\Http\Request; @@ -12,9 +13,10 @@ class WebSocketStatisticsEntriesController * Store the entry. * * @param \Illuminate\Http\Request $request + * @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver * @return \Illuminate\Http\Response */ - public function store(Request $request) + public function store(Request $request, StatisticsDriver $driver) { $validatedAttributes = $request->validate([ 'app_id' => ['required', new AppId()], @@ -23,11 +25,9 @@ public function store(Request $request) 'api_message_count' => 'required|integer', ]); - $webSocketsStatisticsEntryModelClass = config('websockets.statistics.model'); - - $statisticModel = $webSocketsStatisticsEntryModelClass::create($validatedAttributes); - - broadcast(new StatisticsUpdated($statisticModel)); + broadcast(new StatisticsUpdated( + $driver::create($validatedAttributes) + )); return 'ok'; } diff --git a/src/WebSocketsServiceProvider.php b/src/WebSocketsServiceProvider.php index 8431724479..297820fab0 100644 --- a/src/WebSocketsServiceProvider.php +++ b/src/WebSocketsServiceProvider.php @@ -10,6 +10,7 @@ use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize as AuthorizeDashboard; use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster; use BeyondCode\LaravelWebSockets\Server\Router; +use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; use BeyondCode\LaravelWebSockets\Statistics\Http\Controllers\WebSocketStatisticsEntriesController; use BeyondCode\LaravelWebSockets\Statistics\Http\Middleware\Authorize as AuthorizeStatistics; use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; @@ -74,6 +75,16 @@ public function register() $this->app->singleton(AppManager::class, function () { return $this->app->make(config('websockets.managers.app')); }); + + $this->app->singleton(StatisticsDriver::class, function () { + $driver = config('websockets.statistics.driver'); + + return $this->app->make( + config('websockets.statistics')[$driver]['driver'] + ?? + \BeyondCode\LaravelWebSockets\Statistics\Drivers\DatabaseDriver::class + ); + }); } /** From 85648964d22daacfc2e65b6b5a03a60a2b2effd6 Mon Sep 17 00:00:00 2001 From: rennokki Date: Tue, 18 Aug 2020 21:22:52 +0300 Subject: [PATCH 2/2] Apply fixes from StyleCI (#472) --- src/Console/CleanStatistics.php | 1 - src/Statistics/Drivers/DatabaseDriver.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Console/CleanStatistics.php b/src/Console/CleanStatistics.php index 5fc3c4d0e8..bc09cf6f36 100644 --- a/src/Console/CleanStatistics.php +++ b/src/Console/CleanStatistics.php @@ -4,7 +4,6 @@ use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver; use Illuminate\Console\Command; -use Illuminate\Database\Eloquent\Builder; class CleanStatistics extends Command { diff --git a/src/Statistics/Drivers/DatabaseDriver.php b/src/Statistics/Drivers/DatabaseDriver.php index 0097c4b229..a8d5175a85 100644 --- a/src/Statistics/Drivers/DatabaseDriver.php +++ b/src/Statistics/Drivers/DatabaseDriver.php @@ -2,7 +2,6 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Drivers; -use BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry; use Carbon\Carbon; class DatabaseDriver implements StatisticsDriver