Найти тему
Битрикс и не только

Сбор и отображение информации о нагрузке сервера Yii2 + Highcharts - Часть первая: сбор данных

Оглавление

Всем привет.

Сегодня я расскажу о том, как с помощью php собирать информацию о состоянии нагрузки сервера и выводить это в виде красивого графика Highcharts.

Данная задача была реализована на Yii2 на сервере с Debian.

Начнем!

Для начала нужно удостовериться, что у пользователя под которым будет выполняться процесс сбора статистики есть доступ на чтение к следующим файлам:

/proc/stat
/proc/meminfo

Информация которую будем собирать и хранить:

Загрузка процессора
Информация об оперативной памяти: объем доступной памяти в ГБ и в процентах

Информация о жестких дисках: доступный объем в ГБ и в процентах. На моем сервере установлен ssd диск и обычный sata. Будем собирать информацию по обоим.

Для хранения информации создадим таблицу в БД

CREATE TABLE `server_stat` (

`id` int(11) NOT NULL,

`date_create` datetime NOT NULL,

`cpu` double NOT NULL,

`memory` double NOT NULL,

`ssd` double NOT NULL,

`sata` double NOT NULL,

`memory_percent` int(11) NOT NULL,

`ssd_percent` int(11) NOT NULL,

`sata_percent` int(11) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `server_stat`

ADD PRIMARY KEY (`id`);

ALTER TABLE `server_stat`

MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

Описание полей таблицы:

id - идентификатор записи
date_create - дата создания
cpu - загрузка процессора
memory - доступная память в ГБ
ssd - доступное место на ssd диске в ГБ
sata - доступное место на sata диске в ГБ
memory_percent - доступная память в %
ssd_percent - доступное место на ssd диске в %
sata_percent - доступное место на sata диске в %

После создания таблицы нужно создать модель ServerStat. Для упрощения этого действия воспользуйтесь Gii.

Далее в контролере, который будет заниматься сбором данных создайте метод actionServerStat

Чтобы не писать весь код к контроллере создадим хелпер StatHelper, который будет выполнять следующие дествия:

Вычисление загрузки процессора
Вычисления свободной оперативной памяти
Вычисление свободного места на дисках

Хелперы я храню в нэймспэйсе app\components\helpers

Код хелпера:

<?php

namespace app\components\helpers;

class StatHelper{

// загрузка процессора

static public function getCpu(){

$file = '/proc/stat';

//проверяем возможность чтения виртуальной директории

if (@is_readable($file)){

//делаем первый замер

$file_first = file($file);

//определяем значения состояний (описаны выше)

$tmp_first = explode(" ",$file_first[0]);

$cpu_user_first = $tmp_first[2];

$cpu_nice_first = $tmp_first[3];

$cpu_sys_first = $tmp_first[4];

$cpu_idle_first = $tmp_first[5];

$cpu_io_first = $tmp_first[6];

sleep(2);//промежуток до второго замера

//делаем второй замер

$file_second = file($file);

$tmp_second = explode(" ",$file_second[0]);

$cpu_user_second= $tmp_second[2];

$cpu_nice_second= $tmp_second[3];

$cpu_sys_second = $tmp_second[4];

$cpu_idle_second= $tmp_second[5];

$cpu_io_second = $tmp_second[6];

//определяем разницу использованного процессорного времени

$diff_used = ($cpu_user_second-$cpu_user_first)+($cpu_nice_second-$cpu_nice_first)+($cpu_sys_second-$cpu_sys_first)+($cpu_io_second-$cpu_io_first);

//определяем разницу общего процессорного времени

$diff_total = ($cpu_user_second-$cpu_user_first)+(

$cpu_nice_second-$cpu_nice_first)+($cpu_sys_second-$cpu_sys_first)+($cpu_io_second-$cpu_io_first)+($cpu_idle_second-$cpu_idle_first);

//определение загрузки cpu

$cpu = round($diff_used/$diff_total, 2);

return $cpu * 100;

}

return null;

}

// статистика памяти

static public function getMemory(){

$memory = [

'full' => 0,

'free' => 0

];

$fh = fopen('/proc/meminfo','r');

if(!$fh)

return null;

while ($line = fgets($fh)) {

$pieces = [];

if (preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $pieces))

$memory['full'] = round($pieces[1]/1024, 2);

if (preg_match('/^MemAvailable:\s+(\d+)\skB$/', $line, $pieces))

$memory['free'] = round($pieces[1]/1024, 2);

if($memory['full'] && $memory['free'])

break;

}

fclose($fh);

return $memory;

}

//статистика дисков

static public function getHdd(){

$sata = [

'full' => 0,

'free' => 0,

];

foreach(['disk1', 'disk300', 'disk50', 'disk500'] as $disk){

$sata['full'] += disk_total_space('/media/'.$disk)/1024/1024/1024;

$sata['free'] += disk_free_space('/media/'.$disk)/1024/1024/1024;

}

return [

'ssd' => [

'full' => round(disk_total_space('/')/1024/1024/1024, 2),

'free' => round(disk_free_space('/')/1024/1024/1024, 2),

],

'sata' => [

'full' => round($sata['full'], 2),

'free' => round($sata['free'], 2)

]

];

}

}

К сожалению данный редактор не поддерживает красивое форматирование кода …

Теперь вкратце расскажу, что делают данные методы

Метод getCpu:

Данный метод берет показания процессорного времени из файл системы /proc/stat

Сначала делается первый замер и после небольшой задержки второй, после чего вычисляется разница общего и использованного процессорного времени. Отсюда вычисляется загрузка, как отношение использованного к общему

Метод getMemory:

Данный метод берет показания из файл системы /proc/meminfo

В нем ищем строки MemTotal и MemAvailable и разбираем их регулярным выражением

Метод getHdd:

В моем случае жесткие диски примонтированы следующим образом:

/ - ssd диск
/media/disk1, /media/disk300, /media/disk50, /media/disk500 - разделы sata диска

Так как я хочу получить общие показания, то будем суммировать собранную информацию по каждому разделу диска

Для вычислений используются php функции disk_total_space и disk_free_space

Теперь применим эти методы. Код контроллера:

use app\models\ServerStat;

….

public function actionServerStat(){

$cpu = StatHelper::getCpu();

$memory = StatHelper::getMemory();

$hdd = StatHelper::getHdd();

$stat = new ServerStat();

$stat->date_create = (new \DateTime)->format('Y-m-d H:i:s');

$stat->cpu = $cpu;

$stat->memory = $memory['free'];

$stat->ssd = $hdd['ssd']['free'];

$stat->sata = $hdd['sata']['free'];

$stat->memory_percent = 100 - intval($memory['free'] * 100 / $memory['full']);

$stat->ssd_percent = 100 - intval($hdd['ssd']['free'] * 100 / $hdd['ssd']['full']);

$stat->sata_percent = 100 - intval($hdd['sata']['free'] * 100 / $hdd['sata']['full']);

$stat->save();

}

Собираем всю информацию, вычисляем процентные значения и записываем в таблицу.

Далее ставим данный скрипт в крон. Если не делали этого на Yii2, воспользуйтесь моим небольшим руководством Yii2 cron задачи

Во второй части опишу процесс вывода собранных данных в виде графика HighCharts.

Есть вопросы, пишите в комментарии.

Спасибо за внимание.