Skip to content
Snippets Groups Projects
Commit 55bded05 authored by Tibo's avatar Tibo
Browse files

detect bouncing status and send warning email

parent f2b66f17
No related branches found
No related tags found
No related merge requests found
Pipeline #1879 failed
# Monitoring - Webapp
## Installation
## Contributing
Requires PHP mongodb extension:
To run this tool localy, you will need:
https://docs.mongodb.com/ecosystem/drivers/php/
https://pecl.php.net/package/mongodb
### Mongodb server
```
sudo apt-get install mongodb
```
On Ubuntu 16.04, this will install mongodb version 2.6 by default.
### Mongodb PHP extension
* https://docs.mongodb.com/ecosystem/drivers/php/
* https://pecl.php.net/package/mongodb
With mongodb 2.6, you will need mongodb-1.4.4:
```
sudo pecl install mongodb-1.4.4
```
### PHP
The extension mongodb-1.4.4 is compatible with PHP 7.2 or less (thus NOT with PHP 7.3).
If you try with PHP7.3, you will encounter errors like
```
PHP symbol lookup error: /usr/lib/php/20180731/mongodb.so: undefined symbol: ZEND_HASH_GET_APPLY_COUNT
```
You can find the complete compatibility matrix at https://docs.mongodb.com/ecosystem/drivers/php/
### Installation
```
composer install
touch storage/app/db.sqlite
......@@ -20,9 +46,9 @@ php artisan migrate
php artisan key:generate
```
## Fronted
### Fronted
```
npm install
npm run watch
```
\ No newline at end of file
```
......@@ -12,7 +12,6 @@ use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Mail;
class StatusChangeDetection implements ShouldQueue
{
......@@ -62,18 +61,40 @@ class StatusChangeDetection implements ShouldQueue
$this->sendNotificationIfRequired($change);
}
/**
* Maximum number of notifications sent per day.
*/
const NOTIFICATIONS_PER_DAY = 4;
public function sendNotificationIfRequired(StatusChange $change)
{
$server = $change->server();
$server_id = $server->id;
$notification = new Notification();
$notification->server()->associate($server);
$notification->type = "change";
$notification->change_id = $change->id;
$notification->save();
$onedayago = time() - 24 * 3600;
$sent_notifications_count = Notification::findForServer($server_id, $onedayago)->count();
foreach ($server->organization->users as $user) {
Mail::to($user)->send(new \App\Mail\StatusChanged($change));
if ($sent_notifications_count < self::NOTIFICATIONS_PER_DAY) {
$notification = new Notification();
$notification->server()->associate($server);
$notification->type = "change";
$notification->change_id = $change->id;
$notification->saveAndSend();
return;
}
if ($sent_notifications_count == self::NOTIFICATIONS_PER_DAY) {
$notification = new Notification();
$notification->server()->associate($server);
$notification->type = "bouncing";
$notification->change_id = $change->id;
$notification->saveAndSend();
return;
}
// nothing to do if number of sent notifications > COUNT
}
}
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class StatusBouncing extends Mailable
{
use Queueable, SerializesModels;
private $change;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(\App\StatusChange $change)
{
$this->change = $change;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('emails.server.bouncing')
->with(["change" => $this->change])
->from("monitor@web-d.be")
->subject(
$this->change->server()->organization->name . " / "
. $this->change->server()->name . " : Status bouncing"
);
}
}
......@@ -3,6 +3,7 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Mail;
class Notification extends Model
{
......@@ -15,5 +16,29 @@ class Notification extends Model
return $this->belongsTo('\App\Server');
}
public function saveAndSend()
{
$this->save();
$change = $this->change();
$mail = new \App\Mail\StatusChanged($change);
if ($this->type == "bouncing") {
$mail = new \App\Mail\StatusBouncing($change);
}
foreach ($this->server->organization->users as $user) {
Mail::to($user)->send($mail);
}
}
public function change() : StatusChange
{
return StatusChange::find($this->change_id);
}
public static function findForServer(int $server_id, int $since = 0)
{
return self::where('server_id', $server_id)
->where('created_at', '>', $since);
}
}
......@@ -83,6 +83,18 @@ class StatusChange
return $changes;
}
public static function find(string $id) : StatusChange
{
$collection = \Mongo::get()->monitoring->statuschanges;
$result = $collection->findOne(
['_id' => new \MongoDB\BSON\ObjectId($id)]);
$status = new StatusChange();
$status->parse($result);
$status->id = $id;
return $status;
}
public static function getLastChangeForServer(int $server_id) : StatusChange
{
$collection = \Mongo::get()->monitoring->statuschanges;
......
......@@ -15,9 +15,9 @@ class CreateNotificationsTable extends Migration
{
Schema::create('notifications', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('created_at');
$table->unsignedInteger('updated_at');
$table->unsignedInteger('server_id');
$table->integer('created_at');
$table->integer('updated_at');
$table->integer('server_id');
$table->string('change_id');
$table->string('type');
});
......
@component('mail::message')
# {{ $change->server()->organization->name }} / {{ $change->server()->name }} : status bouncing
Your server **{{ $change->server()->organization->name }} / {{ $change->server()->name }}**
seems to be bouncing between different states.
This is our last email for today...
{{ action("ServerController@show", ["server" => $change->server()]) }}
{{ config('app.name') }}
@endcomponent
......@@ -3,6 +3,7 @@
namespace Tests\Unit;
use App\User;
use App\Notification;
use App\Organization;
use App\Sensor\Disks;
use App\Sensor\Ifconfig;
......@@ -191,5 +192,21 @@ class ExampleTest extends TestCase
$server->status(),
$last_change->status
);
// Check if a notification were inserted
$this->assertTrue(Notification::findForServer($server_id)->count() > 0);
// Insert multiple status changes to simulate bouncing
for ($i = 0; $i < 4; $i++) {
$change = new \App\StatusChange();
$change->status = 155;
$change->server_id = $server_id;
$change->save();
// Run change detection
$change_detection_job = new \App\Jobs\StatusChangeDetection();
$change_detection_job->detectChangeForServer($server);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment