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

Commit a2fc559

Browse files
authored
Merge pull request #473 from beyondcode/refactor/custom-statistics-drivers
[2.x] Custom statistics drivers
2 parents 35cec91 + 8564896 commit a2fc559

File tree

8 files changed

+234
-39
lines changed

8 files changed

+234
-39
lines changed

config/websockets.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,25 @@
178178

179179
/*
180180
|--------------------------------------------------------------------------
181-
| Statistics Eloquent Model
181+
| Statistics Driver
182182
|--------------------------------------------------------------------------
183183
|
184-
| This model will be used to store the statistics of the WebSocketsServer.
185-
| The only requirement is that the model should extend
186-
| `WebSocketsStatisticsEntry` provided by this package.
184+
| Here you can specify which driver to use to store the statistics to.
185+
| See down below for each driver's setting.
186+
|
187+
| Available: database
187188
|
188189
*/
189190

190-
'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class,
191+
'driver' => 'database',
192+
193+
'database' => [
194+
195+
'driver' => \BeyondCode\LaravelWebSockets\Statistics\Drivers\DatabaseDriver::class,
196+
197+
'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class,
198+
199+
],
191200

192201
/*
193202
|--------------------------------------------------------------------------

docs/debugging/dashboard.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ However, to disable it entirely and void any incoming statistic, you can uncomme
9292
'logger' => \BeyondCode\LaravelWebSockets\Statistics\Logger\NullStatisticsLogger::class, // use the `NullStatisticsLogger` instead
9393
```
9494

95+
## Custom Statistics Drivers
96+
97+
By default, the package comes with a few drivers like the Database driver which stores the data into the database.
98+
99+
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.
100+
101+
Take a quick look at the `\BeyondCode\LaravelWebSockets\Statistics\Drivers\DatabaseDriver` driver to see how to perform your integration.
102+
95103
## Event Creator
96104

97105
The dashboard also comes with an easy-to-use event creator, that lets you manually send events to your channels.

src/Console/CleanStatistics.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
namespace BeyondCode\LaravelWebSockets\Console;
44

5-
use Carbon\Carbon;
5+
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
66
use Illuminate\Console\Command;
7-
use Illuminate\Database\Eloquent\Builder;
87

98
class CleanStatistics extends Command
109
{
@@ -27,25 +26,14 @@ class CleanStatistics extends Command
2726
/**
2827
* Run the command.
2928
*
29+
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
3030
* @return void
3131
*/
32-
public function handle()
32+
public function handle(StatisticsDriver $driver)
3333
{
3434
$this->comment('Cleaning WebSocket Statistics...');
3535

36-
$appId = $this->argument('appId');
37-
38-
$maxAgeInDays = config('websockets.statistics.delete_statistics_older_than_days');
39-
40-
$cutOffDate = Carbon::now()->subDay($maxAgeInDays)->format('Y-m-d H:i:s');
41-
42-
$class = config('websockets.statistics.model');
43-
44-
$amountDeleted = $class::where('created_at', '<', $cutOffDate)
45-
->when(! is_null($appId), function (Builder $query) use ($appId) {
46-
$query->where('app_id', $appId);
47-
})
48-
->delete();
36+
$amountDeleted = $driver::delete($this->argument('appId'));
4937

5038
$this->info("Deleted {$amountDeleted} record(s) from the WebSocket statistics.");
5139
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;
4+
5+
use Carbon\Carbon;
6+
7+
class DatabaseDriver implements StatisticsDriver
8+
{
9+
/**
10+
* The model that controls the database table.
11+
*
12+
* @var \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry|null
13+
*/
14+
protected $record;
15+
16+
/**
17+
* Initialize the driver.
18+
*
19+
* @param \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry|null $record
20+
* @return void
21+
*/
22+
public function __construct($record = null)
23+
{
24+
$this->record = $record;
25+
}
26+
27+
/**
28+
* Get the app ID for the stats.
29+
*
30+
* @return mixed
31+
*/
32+
public function getAppId()
33+
{
34+
return $this->record->app_id;
35+
}
36+
37+
/**
38+
* Get the time value. Should be Y-m-d H:i:s.
39+
*
40+
* @return string
41+
*/
42+
public function getTime(): string
43+
{
44+
return Carbon::parse($this->record->created_at)->toDateTimeString();
45+
}
46+
47+
/**
48+
* Get the peak connection count for the time.
49+
*
50+
* @return int
51+
*/
52+
public function getPeakConnectionCount(): int
53+
{
54+
return $this->record->peak_connection_count ?? 0;
55+
}
56+
57+
/**
58+
* Get the websocket messages count for the time.
59+
*
60+
* @return int
61+
*/
62+
public function getWebsocketMessageCount(): int
63+
{
64+
return $this->record->websocket_message_count ?? 0;
65+
}
66+
67+
/**
68+
* Get the API message count for the time.
69+
*
70+
* @return int
71+
*/
72+
public function getApiMessageCount(): int
73+
{
74+
return $this->record->api_message_count ?? 0;
75+
}
76+
77+
/**
78+
* Create a new statistic in the store.
79+
*
80+
* @param array $data
81+
* @return \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
82+
*/
83+
public static function create(array $data): StatisticsDriver
84+
{
85+
$class = config('websockets.statistics.database.model');
86+
87+
return new static($class::create($data));
88+
}
89+
90+
/**
91+
* Delete statistics from the store,
92+
* optionally by app id, returning
93+
* the number of deleted records.
94+
*
95+
* @param mixed $appId
96+
* @return int
97+
*/
98+
public static function delete($appId = null): int
99+
{
100+
$cutOffDate = Carbon::now()->subDay(
101+
config('websockets.statistics.delete_statistics_older_than_days')
102+
)->format('Y-m-d H:i:s');
103+
104+
$class = config('websockets.statistics.database.model');
105+
106+
return $class::where('created_at', '<', $cutOffDate)
107+
->when($appId, function ($query) use ($appId) {
108+
return $query->whereAppId($appId);
109+
})
110+
->delete();
111+
}
112+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\Statistics\Drivers;
4+
5+
interface StatisticsDriver
6+
{
7+
/**
8+
* Initialize the driver with a stored record.
9+
*
10+
* @param mixed $record
11+
* @return void
12+
*/
13+
public function __construct($record = null);
14+
15+
/**
16+
* Get the app ID for the stats.
17+
*
18+
* @return mixed
19+
*/
20+
public function getAppId();
21+
22+
/**
23+
* Get the time value. Should be Y-m-d H:i:s.
24+
*
25+
* @return string
26+
*/
27+
public function getTime(): string;
28+
29+
/**
30+
* Get the peak connection count for the time.
31+
*
32+
* @return int
33+
*/
34+
public function getPeakConnectionCount(): int;
35+
36+
/**
37+
* Get the websocket messages count for the time.
38+
*
39+
* @return int
40+
*/
41+
public function getWebsocketMessageCount(): int;
42+
43+
/**
44+
* Get the API message count for the time.
45+
*
46+
* @return int
47+
*/
48+
public function getApiMessageCount(): int;
49+
50+
/**
51+
* Create a new statistic in the store.
52+
*
53+
* @param array $data
54+
* @return \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
55+
*/
56+
public static function create(array $data): StatisticsDriver;
57+
58+
/**
59+
* Delete statistics from the store,
60+
* optionally by app id, returning
61+
* the number of deleted records.
62+
*
63+
* @param mixed $appId
64+
* @return int
65+
*/
66+
public static function delete($appId = null): int;
67+
}

src/Statistics/Events/StatisticsUpdated.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace BeyondCode\LaravelWebSockets\Statistics\Events;
44

55
use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger;
6-
use BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry;
6+
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
77
use Illuminate\Broadcasting\PrivateChannel;
88
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
99
use Illuminate\Queue\SerializesModels;
@@ -14,21 +14,21 @@ class StatisticsUpdated implements ShouldBroadcast
1414
use SerializesModels;
1515

1616
/**
17-
* The statistic instance that got updated.
17+
* The statistics driver instance.
1818
*
19-
* @var \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry
19+
* @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
2020
*/
21-
protected $webSocketsStatisticsEntry;
21+
protected $driver;
2222

2323
/**
2424
* Initialize the event.
2525
*
26-
* @param \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry $webSocketsStatisticsEntry
26+
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
2727
* @return void
2828
*/
29-
public function __construct(WebSocketsStatisticsEntry $webSocketsStatisticsEntry)
29+
public function __construct(StatisticsDriver $driver)
3030
{
31-
$this->webSocketsStatisticsEntry = $webSocketsStatisticsEntry;
31+
$this->driver = $driver;
3232
}
3333

3434
/**
@@ -39,11 +39,11 @@ public function __construct(WebSocketsStatisticsEntry $webSocketsStatisticsEntry
3939
public function broadcastWith()
4040
{
4141
return [
42-
'time' => (string) $this->webSocketsStatisticsEntry->created_at,
43-
'app_id' => $this->webSocketsStatisticsEntry->app_id,
44-
'peak_connection_count' => $this->webSocketsStatisticsEntry->peak_connection_count,
45-
'websocket_message_count' => $this->webSocketsStatisticsEntry->websocket_message_count,
46-
'api_message_count' => $this->webSocketsStatisticsEntry->api_message_count,
42+
'time' => $this->driver->getTime(),
43+
'app_id' => $this->driver->getAppId(),
44+
'peak_connection_count' => $this->driver->getPeakConnectionCount(),
45+
'websocket_message_count' => $this->driver->getWebsocketMessageCount(),
46+
'api_message_count' => $this->driver->getApiMessageCount(),
4747
];
4848
}
4949

src/Statistics/Http/Controllers/WebSocketStatisticsEntriesController.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace BeyondCode\LaravelWebSockets\Statistics\Http\Controllers;
44

5+
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
56
use BeyondCode\LaravelWebSockets\Statistics\Events\StatisticsUpdated;
67
use BeyondCode\LaravelWebSockets\Statistics\Rules\AppId;
78
use Illuminate\Http\Request;
@@ -12,9 +13,10 @@ class WebSocketStatisticsEntriesController
1213
* Store the entry.
1314
*
1415
* @param \Illuminate\Http\Request $request
16+
* @param \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver $driver
1517
* @return \Illuminate\Http\Response
1618
*/
17-
public function store(Request $request)
19+
public function store(Request $request, StatisticsDriver $driver)
1820
{
1921
$validatedAttributes = $request->validate([
2022
'app_id' => ['required', new AppId()],
@@ -23,11 +25,9 @@ public function store(Request $request)
2325
'api_message_count' => 'required|integer',
2426
]);
2527

26-
$webSocketsStatisticsEntryModelClass = config('websockets.statistics.model');
27-
28-
$statisticModel = $webSocketsStatisticsEntryModelClass::create($validatedAttributes);
29-
30-
broadcast(new StatisticsUpdated($statisticModel));
28+
broadcast(new StatisticsUpdated(
29+
$driver::create($validatedAttributes)
30+
));
3131

3232
return 'ok';
3333
}

src/WebSocketsServiceProvider.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize as AuthorizeDashboard;
1111
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
1212
use BeyondCode\LaravelWebSockets\Server\Router;
13+
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
1314
use BeyondCode\LaravelWebSockets\Statistics\Http\Controllers\WebSocketStatisticsEntriesController;
1415
use BeyondCode\LaravelWebSockets\Statistics\Http\Middleware\Authorize as AuthorizeStatistics;
1516
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
@@ -74,6 +75,16 @@ public function register()
7475
$this->app->singleton(AppManager::class, function () {
7576
return $this->app->make(config('websockets.managers.app'));
7677
});
78+
79+
$this->app->singleton(StatisticsDriver::class, function () {
80+
$driver = config('websockets.statistics.driver');
81+
82+
return $this->app->make(
83+
config('websockets.statistics')[$driver]['driver']
84+
??
85+
\BeyondCode\LaravelWebSockets\Statistics\Drivers\DatabaseDriver::class
86+
);
87+
});
7788
}
7889

7990
/**

0 commit comments

Comments
 (0)