Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #473 from beyondcode/refactor/custom-statistics-dr…
Browse files Browse the repository at this point in the history
…ivers

[2.x] Custom statistics drivers
  • Loading branch information
rennokki authored Aug 18, 2020
2 parents 35cec91 + 8564896 commit a2fc559
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 39 deletions.
19 changes: 14 additions & 5 deletions config/websockets.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,

],

/*
|--------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions docs/debugging/dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
20 changes: 4 additions & 16 deletions src/Console/CleanStatistics.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

namespace BeyondCode\LaravelWebSockets\Console;

use Carbon\Carbon;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;

class CleanStatistics extends Command
{
Expand All @@ -27,25 +26,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.");
}
Expand Down
112 changes: 112 additions & 0 deletions src/Statistics/Drivers/DatabaseDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;

use Carbon\Carbon;

class DatabaseDriver implements StatisticsDriver
{
/**
* The model that controls the database table.
*
* @var \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry|null
*/
protected $record;

/**
* Initialize the driver.
*
* @param \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry|null $record
* @return void
*/
public function __construct($record = null)
{
$this->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();
}
}
67 changes: 67 additions & 0 deletions src/Statistics/Drivers/StatisticsDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;

interface StatisticsDriver
{
/**
* Initialize the driver with a stored record.
*
* @param mixed $record
* @return void
*/
public function __construct($record = null);

/**
* Get the app ID for the stats.
*
* @return mixed
*/
public function getAppId();

/**
* Get the time value. Should be Y-m-d H:i:s.
*
* @return string
*/
public function getTime(): string;

/**
* Get the peak connection count for the time.
*
* @return int
*/
public function getPeakConnectionCount(): int;

/**
* Get the websocket messages count for the time.
*
* @return int
*/
public function getWebsocketMessageCount(): int;

/**
* Get the API message count for the time.
*
* @return int
*/
public function getApiMessageCount(): int;

/**
* Create a new statistic in the store.
*
* @param array $data
* @return \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
*/
public static function create(array $data): StatisticsDriver;

/**
* 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;
}
24 changes: 12 additions & 12 deletions src/Statistics/Events/StatisticsUpdated.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace BeyondCode\LaravelWebSockets\Statistics\Events;

use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger;
use BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry;
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
Expand All @@ -14,21 +14,21 @@ class StatisticsUpdated implements ShouldBroadcast
use SerializesModels;

/**
* The statistic instance that got updated.
* The statistics driver instance.
*
* @var \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry
* @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
*/
protected $webSocketsStatisticsEntry;
protected $driver;

/**
* Initialize the event.
*
* @param \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry $webSocketsStatisticsEntry
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
* @return void
*/
public function __construct(WebSocketsStatisticsEntry $webSocketsStatisticsEntry)
public function __construct(StatisticsDriver $driver)
{
$this->webSocketsStatisticsEntry = $webSocketsStatisticsEntry;
$this->driver = $driver;
}

/**
Expand All @@ -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(),
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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()],
Expand All @@ -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';
}
Expand Down
11 changes: 11 additions & 0 deletions src/WebSocketsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
);
});
}

/**
Expand Down

0 comments on commit a2fc559

Please sign in to comment.