📜 ⬆️ ⬇️

Monitoring Trassir Servers

It so happened that there is a need to administer a large number (over 50 and will be multiply more) of the Trassir servers (video surveillance server) located in different cities of the CIS. In general, the equipment is not bad, but there are problems with centralized management due to the peculiarities of the system architecture, each server (NVR) lives its own life. Some opportunities to steer at once with a bunch of devices are given by the “native” cloud, but it is absolutely unconfigurable and you can use it only as it is.

The morning of each working day begins with checking each server for operability, which takes a lot of time.

DSSL has an SDK, a full description is available here .
')
Spent a couple of evenings and wrote a class in php, which allows the web server to check the status of Trassir servers and display on the page. To access Trassir servers via the web, they need to be configured. First, in the server settings, enable “Allow access to Trassir from the browser”, secondly, “Trassir SDK” (and set the SDK password). In addition, I recommend creating a user with truncated permissions to authorize the script (in my case, the Monitoring user, password 123, SDK password 12345).

image

In general, the SDK provides great opportunities, you can familiarize yourself with the link that I gave above.

The class code itself:

<?php class TrassirServer { /* 1.   . $serv = new TrassirServer('10.18.242.33', 'Monitoring', '123', '12345'); 2.           ! $serv->check_connection(); 3.   $serv->get_sid(); 4.      $objects = $serv->get_objects();   SDK 5.   $serv->get_health();      3 (get_sid()) */ public $status = array(); //public $objects = array(); private $ip_address, $user, $sid, $sdk_sid; public function __construct($ip_address, $user, $password, $sdk_password) { //. $this->ip_address = $ip_address; $this->status['ip_address']= NULL; $this->user = $user; $this->password = $password; $this->sdk_password = $sdk_password; } public function check_connection (){ //  . $url = 'http://'.trim($this->ip_address).':80/'; $curlInit = curl_init($url); curl_setopt($curlInit,CURLOPT_CONNECTTIMEOUT,2); //  -       curl_setopt($curlInit,CURLOPT_HEADER,true); curl_setopt($curlInit,CURLOPT_NOBODY,true); curl_setopt($curlInit,CURLOPT_RETURNTRANSFER,true); $response = curl_exec($curlInit); curl_close($curlInit); if ($response){ $this->status['online'] = true; } else { $this->status['online'] = false; } return $this->status['online']; } /* { "success" : "0", "error_code" : "invalid username or password" } /* Username and Password should match to one of the server users. */ public function get_sid(){ //  if ($this->status['online']){ $url = 'https://' . trim($this->ip_address) . ':8080/login?username=' . $this->user . '&password='.$this->password; //     $responseJson_str = file_get_contents ($url); $server_auth = json_decode ($responseJson_str, true); // JSON   if($server_auth['success']==1){ $this->status['sid'] = $server_auth['sid']; // sid  } else{ $this->status['sid'] = false; } } return $this->status['sid']; } public function get_objects(){//   if ($this->status['online']){ $url = 'https://' . trim($this->ip_address) . ':8080/objects/?password='.$this->sdk_password; $responseJson_str = file_get_contents ($url); //     $comment_position = strripos ($responseJson_str, '/*'); //      $responseJson_str = substr ($responseJson_str, 0, $comment_position); $objects = json_decode ($responseJson_str, true); return $objects; } return false; } /*    { "disks": "1", "database": "1", "channels_total": "10", "channels_online": "5", "uptime": "12902", "cpu_load": "22.50", "network": "1", "automation": "1", "disks_stat_main_days": "56.15", "disks_stat_priv_days": "35.03", "disks_stat_subs_days": "40.20" } */ public function get_health() { if ($this->status['online'] && $this->status['sid']){ $url = 'https://' . trim($this->ip_address) . ':8080/health?sid='.$this->status['sid']; $responseJson_str = file_get_contents ($url); //     $comment_position = strripos ($responseJson_str, '/*'); //      $responseJson_str = substr ($responseJson_str, 0, $comment_position); $server_health = json_decode ($responseJson_str, true); // JSON   } return $server_health; } } ?> 

The usage example implies the presence of three files, index.php, view.css (the style sheet is optional, but everything will be sad without it), list_of_servers.txt (a text file that shows the IP addresses of all servers to check, each with a new line) .

view.css:

 .error{ background-color: cc3f5b; #border: 1px dotted red; #width: 99%; padding-left: 5px; } .trassir_server{ #border-bottom: 1px solid black; width: 250px; height: 240px; background-color: #4682B4; color: white; margin-top: 15px; margin-left: 5px; display: inline-block; vertical-align: top; } .OK{ background-color: #4169E0; border-bottom: 1px solid black; padding-left: 5px; } .trassir_server_name{ font-size: 20px; text-align: center; height: 30px; } body{ background-color: #DCDCDC; } 

index.php

 <?php header('Content-Type: text/html; charset=utf-8'); ini_set('max_execution_time', 60); error_reporting(E_ALL); require ('classes/TrassirServer.php'); ?> <html> <head> <link rel='stylesheet' href='./css/view.css'> </head> <body> <?php $user = 'Monitoring'; $password = '123'; $sdk_password = '12345'; function trassir_server_monitor($ip, $user, $password, $sdk_password){ $serv = new TrassirServer($ip, $user, $password, $sdk_password); echo '<div class = "trassir_server">'; if ($serv->check_connection()) { if ($serv->get_sid()) { $objects = $serv->get_objects(); if($objects){ foreach ($objects as $obj) //      { if ($obj['class'] == 'Server') { $serv->status['name']= $obj['name']; } } } echo '<div class = "trassir_server_name">'; //   echo $serv->status['name']; echo '</div>'; echo '<div class = "trassir_server_status">'; //  $health = $serv->get_health(); foreach ($health as $key => $value){ if (($key == 'disks' || $key == 'database' || $key == 'network' || $key == 'automation')&& $value=='1') { echo '<div class = "OK">'; echo $key . ': '; echo 'OK'; echo '</div>'; } else if ($key == 'cpu_load' && $value <= 75) { echo '<div class = "OK">'; echo ' : '; echo $value . '%'; echo '</div>'; } else if ($key == 'uptime' && $value > 3600) { echo '<div class = "OK">'; echo ': '; $day = floor($value/86400); $value1 = $value - $day*86400; $hour = floor(($value - $day*86400)/3600); echo $day.' days '.$hour . ' hours'; echo '</div>'; } else if ($key == 'uptime' && $value <= 3600) { echo '<div class = "error">'; echo $key . ' less than hour : '; echo $value . ' seconds'; echo '</div>'; } else if ($key == 'channels_total') { echo '<div class = "OK">'; echo ' : '; echo $value; $ch_total = $value; echo '</div>'; } else if ($key == 'channels_online' && $value == $ch_total) { echo '<div class = "OK">'; echo ' : '; echo $value; $ch_total = $value; echo '</div>'; } else if (($key == 'disks_stat_main_days' || $key == 'disks_stat_subs_days')&& $value > 45) { echo '<div class = "OK">'; echo $key . ': '; echo $value; echo '</div>'; } else if ( $key == 'disks_stat_priv_days') { echo '<div class = "OK">'; echo $key . ': '; echo $value; echo '</div>'; } else { echo '<div class = "error">'; echo $key . ': '; echo $value; echo '</div>'; } } echo '</div>'; } } if (!$serv->status['online'] || !$serv->status['sid'] || !$objects){ //   ,          . echo '<div class = "error">'; echo 'server ' . $ip . '</br>'; echo 'connection error'; echo '</div>'; } echo '</div>'; } $list_of_servers = fopen("conf/list_of_servers.txt", "r"); if ($list_of_servers) { while (($buffer = fgets($list_of_servers)) !== false) { trassir_server_monitor($buffer, $user, $password, $sdk_password); } } fclose($list_of_servers); echo '<br/>'; ?> </body> </html> 

The result in my case (for the testing period only 4 servers):

image

In the plans:

  1. Automatic regular launch of the script (a couple of times a day) and saving statistics on the status of servers in the database.
  2. Perhaps the centralized management of UZ users if it is relevant to the time when I can implement the first.

If there are still “happy” administrators of this system, I will be happy to help with the desire to jointly refine the functionality. Also, if someone is interested in the final result, but is not ready to engage in development - write to denis.glushakov@bk.ru, I will try not to forget about you.

Tips on optimizing the code with pleasure I will accept in the comments.

UPD from 06/22/2018. Since there was some interest in the material, I will make a small update: I rewrote all this horror in a more or less decent lib available on packagist (look for the word Trassir) and did a different implementation with full functionality on the symphony (saving states in the database, displaying statistics, etc.). To whom it is relevant - write to the post office, there is no time to find it to publish yet, and it’s not yet complete until the end.

Source: https://habr.com/ru/post/344488/


All Articles