Added conditional notifications

- Absolute values
- Percentage threshold
This commit is contained in:
Henry Whitaker
2020-08-21 22:56:38 +01:00
parent a15d633322
commit 375ecf650c
6 changed files with 401 additions and 1 deletions

View File

@@ -10,6 +10,7 @@ use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use InvalidArgumentException;
use JsonException;
class SpeedtestHelper {
@@ -301,4 +302,77 @@ class SpeedtestHelper {
'msg' => 'There was an error backing up the database. No speedtests have been deleted.'
];
}
/**
* Work out if a test is lower than the threshold for historic tests
*
* @param String $type
* @param Speedtest $test
* @return array
*/
public static function testIsLowerThanThreshold(String $type, Speedtest $test)
{
if($type == 'percentage') {
$avg = Speedtest::select(DB::raw('AVG(ping) as ping, AVG(download) as download, AVG(upload) as upload'))
->where('failed', false)
->get()
->toArray()[0];
$threshold = SettingsHelper::get('threshold_alert_percentage')->value;
if($threshold == '') {
return [];
}
$errors = [];
foreach($avg as $key => $value) {
if($key == 'ping') {
$threshold = (float)$value * (1 + ( $threshold / 100 ));
if($test->$key > $threshold) {
array_push($errors, $key);
}
} else {
$threshold = (float)$value * (1 - ( $threshold / 100 ));
if($test->$key < $threshold) {
array_push($errors, $key);
}
}
}
return $errors;
}
if($type == 'absolute') {
$thresholds = [
'download' => SettingsHelper::get('threshold_alert_absolute_download')->value,
'upload' => SettingsHelper::get('threshold_alert_absolute_upload')->value,
'ping' => SettingsHelper::get('threshold_alert_absolute_ping')->value,
];
$errors = [];
foreach($thresholds as $key => $value) {
if($value == '') {
continue;
}
if($key == 'ping') {
if($test->$key > $value) {
array_push($errors, $key);
}
} else {
if($test->$key < $value) {
array_push($errors, $key);
}
}
}
return $errors;
}
throw new InvalidArgumentException();
}
}

View File

@@ -3,8 +3,11 @@
namespace App\Listeners;
use App\Helpers\SettingsHelper;
use App\Helpers\SpeedtestHelper;
use App\Notifications\SpeedtestAbsoluteThresholdNotificationSlack;
use App\Notifications\SpeedtestCompleteSlack;
use App\Notifications\SpeedtestCompleteTelegram;
use App\Notifications\SpeedtestPercentageThresholdNotificationSlack;
use Exception;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
@@ -32,9 +35,40 @@ class SpeedtestCompleteListener
*/
public function handle($event)
{
Log::info('handling event');
Log::info(SettingsHelper::get('threshold_alert_percentage_notifications')->value);
if((bool)SettingsHelper::get('threshold_alert_percentage_notifications')->value == true) {
$data = $event->speedtest;
$errors = SpeedtestHelper::testIsLowerThanThreshold('percentage', $data);
if(sizeof($errors) > 0) {
try {
Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
->notify(new SpeedtestPercentageThresholdNotificationSlack($errors));
} catch(Exception $e) {
//
}
}
}
if((bool)SettingsHelper::get('threshold_alert_absolute_notifications')->value == true) {
$data = $event->speedtest;
Log::info('absolute nots enabled');
Log::info($data);
$errors = SpeedtestHelper::testIsLowerThanThreshold('absolute', $data);
Log::info($errors);
if(sizeof($errors) > 0) {
try {
Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
->notify(new SpeedtestAbsoluteThresholdNotificationSlack($errors));
} catch(Exception $e) {
//
}
}
}
if(SettingsHelper::get('speedtest_notifications')->value == true) {
$data = $event->speedtest;
if(SettingsHelper::get('slack_webhook')) {
if(SettingsHelper::get('slack_webhook')->value) {
try {
Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
->notify(new SpeedtestCompleteSlack($data));

View File

@@ -0,0 +1,86 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
class SpeedtestAbsoluteThresholdNotificationSlack extends Notification
{
use Queueable;
protected $errors;
/**
* Create a new notification instance.
*
* @param array $errors
* @return void
*/
public function __construct(array $errors)
{
$this->errors = $errors;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['slack'];
}
/**
* Format slack notification
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)
->warning()
->attachment(function ($attachment) {
$attachment->title('Speedtest absolute threshold error')
->content($this->formatMessage());
});
}
/**
* Parse $this->errors and format message
*
* @return String
*/
public function formatMessage()
{
$msg = 'For the latest speedtest, the ';
for($i = 0; $i < sizeof($this->errors); $i++) {
$key = $this->errors[$i];
$msg = $msg . $key;
if(sizeof($this->errors) > 1 && $i < (sizeof($this->errors) - 1)) {
$msg = $msg . ', ';
}
}
if($msg[-1] != '') {
$msg = $msg . ' ';
}
if(sizeof($this->errors) > 1) {
$msg = $msg . 'values ';
} else {
$msg = $msg . 'value ';
}
$msg = $msg . 'exceeded the absolute threshold';
return $msg;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
class SpeedtestPercentageThresholdNotificationSlack extends Notification
{
use Queueable;
protected $errors;
/**
* Create a new notification instance.
*
* @param array $errors
* @return void
*/
public function __construct(array $errors)
{
$this->errors = $errors;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['slack'];
}
/**
* Format slack notification
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)
->warning()
->attachment(function ($attachment) {
$attachment->title('Speedtest percentage threshold error')
->content($this->formatMessage());
});
}
/**
* Parse $this->errors and format message
*
* @return String
*/
public function formatMessage()
{
$msg = 'For the latest speedtest, the ';
for($i = 0; $i < sizeof($this->errors); $i++) {
$key = $this->errors[$i];
$msg = $msg . $key;
if(sizeof($this->errors) > 1 && $i < (sizeof($this->errors) - 1)) {
$msg = $msg . ', ';
}
}
if($msg[-1] != '') {
$msg = $msg . ' ';
}
if(sizeof($this->errors) > 1) {
$msg = $msg . 'values ';
} else {
$msg = $msg . 'value ';
}
$msg = $msg . 'exceeded the percentage threshold';
return $msg;
}
}

View File

@@ -0,0 +1,83 @@
<?php
use App\Helpers\SettingsHelper;
use App\Setting;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddConditionalNotificationsSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if(!SettingsHelper::get('threshold_alert_percentage_notifications')) {
Setting::create([
'name' => 'threshold_alert_percentage_notifications',
'value' => false,
'description' => 'Enable/disable theshold percentage notifications'
]);
}
if(!SettingsHelper::get('threshold_alert_percentage')) {
Setting::create([
'name' => 'threshold_alert_percentage',
'value' => 15,
'description' => 'When any value of a speedtest is x percent lower than the average, a notification will be sent.'
]);
}
if(!SettingsHelper::get('threshold_alert_absolute_notifications')) {
Setting::create([
'name' => 'threshold_alert_absolute_notifications',
'value' => false,
'description' => 'Enable/disable absolute theshold notifications'
]);
}
if(!SettingsHelper::get('threshold_alert_absolute_download')) {
Setting::create([
'name' => 'threshold_alert_absolute_download',
'value' => '',
'description' => 'When the download is lower than this value, a notification will be sent. Leave blank to disable'
]);
}
if(!SettingsHelper::get('threshold_alert_absolute_upload')) {
Setting::create([
'name' => 'threshold_alert_absolute_upload',
'value' => '',
'description' => 'When the upload is lower than this value, a notification will be sent. Leave blank to disable'
]);
}
if(!SettingsHelper::get('threshold_alert_absolute_ping')) {
Setting::create([
'name' => 'threshold_alert_absolute_ping',
'value' => '',
'description' => 'When the ping is higher than this value, a notification will be sent. Leave blank to disable'
]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Setting::whereIn('name', [
'threshold_alert_percentage',
'threshold_alert_absolute_download',
'threshold_alert_absolute_upload',
'threshold_alert_absolute_ping',
'threshold_alert_percentage_notifications',
'threshold_alert_absolute_notifications'
])->delete();
}
}

View File

@@ -158,6 +158,43 @@ export default class Settings extends Component {
type: 'number',
min: 0,
max: 23
},
{
obj: {
id: (Math.floor(Math.random() * 10000) + 1),
name: "Conditional Notifications",
description: ""
},
type: 'group',
children: [
]
},
{
obj: e.threshold_alert_percentage_notifications,
type: 'checkbox',
},
{
obj: e.threshold_alert_percentage,
type: 'number',
min: 0,
max: 100
},
{
obj: e.threshold_alert_absolute_notifications,
type: 'checkbox',
},
{
obj: e.threshold_alert_absolute_download,
type: 'number',
},
{
obj: e.threshold_alert_absolute_upload,
type: 'number',
},
{
obj: e.threshold_alert_absolute_ping,
type: 'number',
}
]} />
</Col>