2016-12-16 82 views
1

我开发了一个Web监控工具。它应该检查网站的状态代码,并决定它的启动或关闭。如果响应代码是200,它会很好,它会保存在数据库中,否则会保存。如果状态码发生变化,应该发送通知,即从上到下或反之亦然(它使用保存在数据库中的最后一个状态码检查新的resCode(响应代码)))。但是如果网站总是上线,请不要发送通知。但是如果网站关闭,请检查警报频率并发送通知。 sendNotification函数对此负责,但出于某种原因并且收到通知的垃圾邮件。它只是继续发送通知而不检查警报频率和状态更改。任何人都可以查看我的代码。提前tnx。Web监控工具:不断发送通知,而不应该发送通知

<?php 
namespace App\Http\Controllers; 

use \GuzzleHttp\Client; 
use App\Utilities\Reporter; 
use GuzzleHttp\Exception\ClientException; 
use App\Notification; 
use App\Status; 
use App\Setting; 
use Carbon; 
class GuzzleController extends Controller 
{ 
    private $default_check_frequency; 

    protected $client; 

    protected $reporter; 

    public function __construct() 
    { 
     $this->client = new Client(); 

     $this->reporter = new Reporter; 

     $this->default_check_frequency = Setting::defaultCheckFrequency(); 


    } 

    private function addStatusToNotification(Notification $notification, Status $status, $resCode) 
    { 
     $notification->statuses()->attach($status, [ 
      'values' => $resCode === 200 
      ? 'up' 
      : 'down' 
      ]); 
    } 

    private function report(Notification $notification, $resCode) 
    { 
     if(empty($resCode)){ 
      $resCode = "no response found"; 
     } 
     if($resCode <> 200){ 
       $this->reporter->slack($notification->website_url . ':' . ' is down' . ' this is the status code!' . ' @- ' .$resCode, 
         $notification->slack_channel); 

       $this->reporter->mail($notification->email,$notification->website_url.' is down '. ' this is the status Code: '. $resCode); 

     }else{ 
       $this->reporter->slack($notification->website_url . ':' . ' is up' . ' this is the status code!' . ' @- ' .$resCode, 
         $notification->slack_channel); 
     } 
    } 

    private function sendNotification(Notification $notification, Status $status, $status_health, $frequency, $resCode) 
    { 
     $elapsed_time = \Carbon\Carbon::parse($status_health['timestamp'])->diffInMinutes(); 

     if ($elapsed_time >= $frequency) { 

      $this->addStatusToNotification($notification, $status, $resCode); 
     } 
     if ($resCode === 200){ 

      if($resCode <> $status_health['value']){ 
       var_dump($status_health['value']); 
       die(); 
       $this->report($notification, $resCode); 

      } 
     }else{ 
      if($resCode === $status_health['value'] && $elapsed_time >= $notification->alert_frequency){ 
       $this->report($notification, $resCode); 

      } 
     } 
    } 


    public function status() 
    { 
     $notifications = Notification::where('active', 1)->get(); 

     $status = Status::where('name', 'health')->first(); 

     foreach ($notifications as $notification) { 
      $this->updateStatus($notification, $status); 
     } 
    } 

    private function updateStatus(Notification $notification, Status $status) 
    { 
     $resCode = $this->getStatusCode($notification->website_url); 

     $this->sendNotification(
      $notification, 
      $status, 
      $notification->status('health'), 
      $this->getFrequency($notification,$resCode), 
      $resCode 
      ); 
    } 

    private function getFrequency(Notification $notification) 
    {   

      return isset($notification->check_frequency) 
      ? intval($notification->check_frequency) 
      : $this->default_check_frequency;     
    } 

    private function getStatusCode($url) 
    { 
     try { 
      $response = $this->client->get($url, [ 
       'http_errors' => false 
       ]); 
      return $response->getStatusCode(); 
     } catch (\GuzzleHttp\Exception\ConnectException $e) { 

     } 
    } 
} 

这实际上是IAM获得status_health,模型,无论是向上还是黎明从数据库

<?php 

namespace App; 
use App\Status; 
use App\Notification; 

use Illuminate\Database\Eloquent\Model; 

class Notification extends Model 
{ 
    protected $fillable = ['id','website_url','email','slack_channel','check_frequency','alert_frequency','speed_frequency','active']; 

    public function statuses(){ 
     return $this->belongsToMany('App\Status')->withPivot('values')->withTimestamps(); 
    } 

    public function status($s_type) 
    { 
     if (!in_array($s_type, ['speed', 'health'])){ 
      return false; 
     } 

     $o_status = Status::where('name', strval($s_type))->first(); 
     $o_response = $this->statuses()->where('status_id', $o_status->id) 
     ->select('values', 'created_at')->orderBy('created_at','DESC')->first(); 

     if($o_response === null){ 
      return false; 
     } 

     return [ 
      'value' => $o_response->values, 
      'timestamp' => $o_response->created_at 
     ]; 
    } 

    public function history($s_type) 
    { 
     if (!in_array($s_type, ['speed', 'health'])){ 
      return false; 
     } 

     $o_status = Status::where('name', strval($s_type))->first(); 
     $o_response = $this->statuses()->where('status_id', $o_status->id) 
     ->select('values', 'created_at')->orderBy('created_at','DESC')->get(); 

     if($o_response === null || $o_response->count() === 0){ 
      return false; 
     } 


     $a_ret = []; 
     $last = null; 

     foreach ($o_response as $o_status) { 
      if($last != $o_status->values) { 
       $a_ret[] = [ 
       'value' => $o_status->values, 
       'timestamp' => $o_status->created_at 
       ]; 
       $last = $o_status->values; 
      } 
     } 
     return $a_ret; 
    } 
} 
+0

显然,代码检查RESP代码改变不能按预期的那样工作确保'$ status_health'包含你期望得到的结果 –

回答

0

您可以在状态保存到数据库中,如果状态,你从了最后检查是否与保存到数据库的状态不同,您可以发送通知并更新数据库中的状态。

使用此方法,只会在状态发生变化时发送通知,而不是每次检查状态时都会发送通知。

如果您使用您保存在数据库中的最新检查来检查status_code,则可以比较并考虑发送通知。

当您调用将发送新状态的函数时,您可以检查status_code!= old_status_code

希望这个作品!

+0

是的,但是如果支票每分钟运行一次,他每分钟都会收到通知......因此,他应该使用他得到的状态从以前的检查 –

+0

我不认为有需要额外的表,因为在模型中的数据s tatus代码仅提取最新的代码。并用新的状态码进行检查。 –

+0

@abrahamfoto这是真的,他可以检查保存到数据库的最后一次检查,并将其与新状态进行比较。 –

0

我在大量调试后得到了答案。问题不在于代码本身。来自http请求的响应代码是一串数字exmaple 200,404等,然后将其作为字符串值保存为“上”或“下”。当我使用比较resCode(响应代码)和status_health ['值'](我从数据库获得的值是一个字符串“向上”或“向下”。在resCode串,我的问题是固定的。在sendNotification的功能代码得到改善。TNX所有谁试图帮助@Robin德克森。这里是新的代码。

<?php 
namespace App\Http\Controllers; 

use \GuzzleHttp\Client; 
use App\Utilities\Reporter; 
use GuzzleHttp\Exception\ClientException; 
use App\Notification; 
use App\Status; 
use App\Setting; 
use Carbon; 
class GuzzleController extends Controller 
{ 
    private $default_check_frequency; 

    protected $client; 

    protected $reporter; 

    public function __construct() 
    { 
     $this->client = new Client(); 

     $this->reporter = new Reporter; 

     $this->default_check_frequency = Setting::defaultCheckFrequency(); 


    } 

    private function addStatusToNotification(Notification $notification, Status $status, $resCode) 
    { 
     $notification->statuses()->attach($status, [ 
      'values' => $resCode === 200 
      ? 'up' 
      : 'down' 
      ]); 
    } 

    private function report(Notification $notification, $resCode) 
    { 
     if(empty($resCode)){ 
      $resCode = "no response found"; 
     } 
     if($resCode <> 200){ 
       $this->reporter->slack($notification->website_url . ':' . ' is down' . ' this is the status code!' . ' @- ' .$resCode, 
         $notification->slack_channel); 

       $this->reporter->mail($notification->email,$notification->website_url.' is down '. ' this is the status Code: '. $resCode); 

     }else{ 
       $this->reporter->slack($notification->website_url . ':' . ' is up' . ' this is the status code!' . ' @- ' .$resCode, 
         $notification->slack_channel); 
     } 
    } 

    private function sendNotification(Notification $notification, Status $status, $status_health, $frequency, $resCode) 
    { 
     $elapsed_time = \Carbon\Carbon::parse($status_health['timestamp'])->diffInMinutes(); 

     if ($elapsed_time >= $frequency) { 

      $this->addStatusToNotification($notification, $status, $resCode); 
     } 

     if ($resCode === 200){ 
      $resCode ='up'; 
      if($resCode <> $status_health['value']){    
       $this->report($notification, $resCode);    
      } 
     }else{ 
      $resCode ='down'; 
      if($resCode <> $status_health['value']){ 
       $this->report($notification, $resCode); 
      }else{ 
       if($elapsed_time >= $notification->alert_frequency){ 
        $this->report($notification, $resCode); 
       } 
      } 

       /*if($elapsed_time >= $notification->alert_frequency){*/ 

       /* }*/    

     } 
    } 


    public function status() 
    { 
     $notifications = Notification::where('active', 1)->get(); 

     $status = Status::where('name', 'health')->first(); 

     foreach ($notifications as $notification) { 
      $this->updateStatus($notification, $status); 
     } 
    } 

    private function updateStatus(Notification $notification, Status $status) 
    { 
     $resCode = $this->getStatusCode($notification->website_url); 

     $this->sendNotification(
      $notification, 
      $status, 
      $notification->status('health'), 
      $this->getFrequency($notification,$resCode), 
      $resCode 
      ); 
    } 

    private function getFrequency(Notification $notification) 
    {   

      return isset($notification->check_frequency) 
      ? intval($notification->check_frequency) 
      : $this->default_check_frequency;     
    } 

    private function getStatusCode($url) 
    { 
     try { 
      $response = $this->client->get($url, [ 
       'http_errors' => false 
       ]); 
      return $response->getStatusCode(); 
     } catch (\GuzzleHttp\Exception\ConnectException $e) { 

     } 
    } 
}