Телеметрия локального сервера BananaPI на Bananian Linux

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Ответить
kos
Сообщения: 5
Зарегистрирован: Вт июл 14, 2015 2:49 pm
Откуда: Пенза
Благодарил (а): 3 раза
Поблагодарили: 4 раза

Телеметрия локального сервера BananaPI на Bananian Linux

Сообщение kos » Пт июл 17, 2015 7:09 pm

Честно поизучал Азбуку, Библиотеку, Форум - нашел мониторинг системы с помощью OpenHardwareMonitor, но мне не захотелось еще один веб сервер.
Пришлось сваять своё решение.

Коротко: Заносим в свойства Объекта: "ThisComputer" данные, затем выводим их на Домашнюю страницу.

Поехали:
Создать скрипт temp-daemon.sh в scripts
следующего содержания:Показать

Код: Выделить всё

#!/bin/bash
#
# SoC/HDD temperature daemon. Writes the current temperatures to
# /run/soc-temp and /run/hdd-temp (since we're experiencing always
# timeouts under heavy load when trying to get the temperatures
# directly from within RPi-Monitor.


Main() {
        # SoCTempAdjustment is needed because the A20 SoC delivers uncalibrated temp values
        SoCTempAdjustment=1447

        # ensure module sunxi-dbgreg.ko is loaded
        grep -q sunxi_dbgreg </proc/modules || ( modprobe sunxi-dbgreg ; sleep 0.1 )

        # prepare registers
        echo 'f1c25000:27003f' > /sys/devices/virtual/misc/sunxi-dbgreg/rw/write;
        echo 'f1c25010:40000' > /sys/devices/virtual/misc/sunxi-dbgreg/rw/write;
        echo 'f1c25018:10fff' > /sys/devices/virtual/misc/sunxi-dbgreg/rw/write;
        echo 'f1c25004:10' > /sys/devices/virtual/misc/sunxi-dbgreg/rw/write;

        while [ 2 -ge 1 ]; do

                # let the value be written to syslog
                echo 'f1c25020' > /sys/devices/virtual/misc/sunxi-dbgreg/rw/read;

                # wait 0.1 seconds
                sleep 0.1

                # read return value from syslog and transform it into degrees Celsius

                HexVal=$(tail /var/log/syslog | awk -F" 0x" '/ 0x/ {print $2}' | tail -n1 )
                SoCTemp=$(echo $(( 0x${HexVal} - ${SoCTempAdjustment} )) | awk '{printf ("%0.1f",$1/10); }')

                if [ "X${SoCTemp}" != "X" ]; then
                       echo -n ${SoCTemp} >/run/soc-temp
                fi


                # HDD/SSD temp
                DiskTemp=$(hddtemp -n /dev/sda)

                if [ "X${DiskTemp}" != "X" ]; then
                       echo -n ${DiskTemp} >/run/hdd-temp
                fi

                # sleep 30 secs
                sleep 30

       done

} # Main

Main
Дать ему права на выполнение примерно так:

Код: Выделить всё

chmod 770 /var/www/scripts/temp-daemon.sh
добавить в конец /etc/init.d/rc.local
строчки:Показать

Код: Выделить всё

nohup /var/www/scripts/temp-daemon.sh &

chmod 444 /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
Создать новый метод ComputerStatus в Class: Computer, зашел в Объект: ThisComputer - Метод ComputerStatus, ввел
код PHPПоказать

Код: Выделить всё

setGlobal("ThisComputer.OS",file_get_contents('/etc/os-release',NULL,NULL,13,27)); // Версию ОС вырезаем по позициям. С AWK было бы красивее, но не осилил

setGlobal("ThisComputer.Kernel",shell_exec("uname -msr")); // Версия ядра

setGlobal("ThisComputer.Processor",file_get_contents('/proc/cpuinfo',NULL,NULL,12,27)); // Версия процессора
setGlobal("ThisComputer.CPUFreq",file_get_contents('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq')/1000); // Права поправить
setGlobal("ThisComputer.CPUSG",file_get_contents('/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor')); // Режим управления частотой

setGlobal("ThisComputer.uptime",shell_exec('uptime')); // Тут несколько значений сразу

$mem=shell_exec("free -m|grep Mem|awk '{print $2,$3,$4}'"); // Данные об ОЗУ
$mem=explode(" ",$mem);
setGlobal("ThisComputer.memoryUse",$mem[1]);

$Swap=shell_exec("free -m|grep Swap|awk '{print $2,$3,$4}'"); // Данные о SWAP
$Swap=explode(" ",$Swap);
setGlobal("ThisComputer.SwapUse",$Swap[1]);

$disk=shell_exec("df|grep rootfs|awk '{print $2,$3,$5,$6}'"); // p.s. rootfs нужно изменить на свой диск
$disk=explode(" ",$disk);
setGlobal("ThisComputer.driveRootUse",round($disk[1]/1048576, 2)); //Переведем в Гб с округлением до сотых

$disk2=shell_exec("df|grep sda3|awk '{print $2,$3,$5,$6}'"); // p.s. sda3 нужно изменить на свой диск
$disk2=explode(" ",$disk2);
setGlobal("ThisComputer.driveSda3Use",round($disk2[1]/1048576, 2));

setGlobal("ThisComputer.PMUTemp",file_get_contents('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input')/1000);

setGlobal("ThisComputer.CPUTemp",file_get_contents('/run/soc-temp'));

// Электропитание через порт microUSB
setGlobal("ThisComputer.PmuAcVolt",file_get_contents('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/voltage_now')/1000000);
setGlobal("ThisComputer.PmuAcAmp",file_get_contents('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/current_now')/1000000);
setGlobal("ThisComputer.PmuAcWatt",round(gg("ThisComputer.PmuAcVolt")*gg("ThisComputer.PmuAcAmp"), 2)); // Мощность посчитаем и округлим

// Статистика Ethernet
setGlobal("ThisComputer.NetRXM",round(file_get_contents('/sys/class/net/eth0/statistics/rx_bytes')/1048576, 2)); // Читаем данные, переводим в МБ, округляем до сотых
setGlobal("ThisComputer.NetTXM",round(file_get_contents('/sys/class/net/eth0/statistics/tx_bytes')/1048576, 2));
 

(Часть кода (uptime, mem, disk) взял с этого форума. Не помню кто публиковал... PAV или Gagarin - за что им спасибо!
temp-daemon.sh взял с проекта RPi-Monitor)

Добавил в Class: Timer - Объект: ClockChime - Метод onNewMinute строчку:

Код: Выделить всё

callMethod('ThisComputer.ComputerStatus'); 
(Думаю раз в минуту этих сведений достаточно)

Создать сценарий JconhsTemp1d:
СпойлерПоказать

Код: Выделить всё

// Этот сценарий используем только для температуры по тому что удаляем большие значения

// Укажите предельное абсолютное значение температуры, больше которых значения будут затираться предыдущими
$max=140;
// Среднее значение температуры на случай если первое значение отсутствует
$sprev=10;
// Т.к. в highcharts нет возможности вывести диапазон, запрашиваем данные за последний 1 день
$startTime=mktime()-86400*1;

// Получить имя и проверить
 if ( isset($params['name'])  ) { $name = $params['name']; } else { returm; }
 // Разбить на объект и свойство
 $name = explode('.', $name);

 // Получить объект по имени
 $obj=getObject($name[0]); 
 // Получить id свойства
 $prop_id=$obj->getPropertyByName($name[1], $obj->class_id, $obj->id);
 // Получаем VALUE_ID для следующей таблицы
 $pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$obj->id."'");
 // Получаем таблицу
 $arr_s = SQLSelect("SELECT UNIX_TIMESTAMP(ADDED) as ADDED, VALUE FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' and UNIX_TIMESTAMP(ADDED)>=$startTime ORDER BY ADDED");

 // Собрать структуру JSON
 $st = $params['callback'].'([';
 foreach($arr_s as $s) {
  if ($f) $st .=',';
  if ($s['VALUE'] == '' or abs($s['VALUE'])>$max)
   $st .= '['.$s['ADDED'].'000,'.$sprev.']';
   else {
      $st .= '['.$s['ADDED'].'000,'.$s['VALUE'].']';
      $sprev=$s['VALUE'];
   }
   $f=true;
 }
 $st .= ']);';

 // Ответ
 echo ($st); 
(Использовал решение Bagir с небольшими доработками, за что ему спасибо!)

Создал новую домашнюю страницу "Статус системы" с периодом обновления 60 сек, ввел
html кодПоказать

Код: Выделить всё

<h2>Статус системы</h2><br>
ОС: <b>%ThisComputer.OS%</b><br>
Kernel: <b>%ThisComputer.Kernel%</b><br>
Processor: <b>%ThisComputer.Processor%</b><br>
Частота процессора: <b>%ThisComputer.CPUFreq%MHz</b><br>
Режим управления частотой: <b>%ThisComputer.CPUSG%</b><br>
Обновлено:<b>%ThisComputer.uptime%</b><br>
Оперативная память:<b> Всего: 970 Мб, Занято: %ThisComputer.memoryUse% Мб</b><br>
Файл подкачки:<b> Всего: 2047 Мб, Занято:%ThisComputer.SwapUse% Мб</b><br>
Жёсткий диск:<b><br>
/:  Всего: 45 Гб, Занято: %ThisComputer.driveRootUse% Гб<br>
/media/data: Всего: 413 Гб, Занято: %ThisComputer.driveSda3Use% Гб</b><br>
Температура PMU:<b> %ThisComputer.PMUTemp%°C</b><br>
Температура CPU:<b> %ThisComputer.CPUTemp%°C</b><br>
Электропитание: <b>%ThisComputer.PmuAcVolt%V, %ThisComputer.PmuAcAmp%A, %ThisComputer.PmuAcWatt%W</b><br>
Gigabit Ethernet statistic: <b>RX=%ThisComputer.NetRXM% MByte, TX=%ThisComputer.NetTXM% MByte</b><br>
<script type="text/javascript" src="../../highcharts/js/highcharts.js"></script>
<script type="text/javascript">

$(function () {
    var seriesOptions = [],
          obsss = 0,
          seriesCounter = 0,
          timeback = 0,
          names = ['CPU', 'PMU', 'HDD'], 
          sensornames = ['ThisComputer.CPUTemp', 'ThisComputer.PMUTemp', 'ThisComputer.HDDTemp'];

    Highcharts.setOptions({
        lang: {
            shortMonths: ['Янв','Фев','Мар','Апр','Май','Июн','Июл', 
                                     'Авг','Сен','Окт','Ноя','Дек'],
        }
    });

    // create the chart when all data is loaded
    createChart = function () {
        $('#CompTemp').highcharts({
           chart: {
                zoomType: 'x'
            },
            title: { 
                text : 'Температура сервера за 1 день'
            },
            legend: {
                enabled: false
             },
            xAxis: {
                type: 'datetime'
            },
            yAxis: {
                  title: {
                    text: 'Температура (°C)'
                   } 
             },
             series: seriesOptions
           });
    };

    $.each(names, function (i, name) {
        $.getJSON('/objects/?script=JconhsTemp1d&name='+sensornames[i]+'&callback=?', function (data) {

            seriesOptions[i] = {
                name: name,
                data: data,
                type: 'spline'
            };

            // Счетчик окончания загрузки данных
            seriesCounter += 1;
            if (seriesCounter === names.length) {
                createChart();
            }
         });
     });
});
</script>

<div id="CompTemp" style="height: 250px; width: 400px"></div>
Результат:
картинкаПоказать
bananapi3.jpg
bananapi3.jpg (135.41 КБ) 9865 просмотров
Возможно кому-то пригодится.

Аналогично можно нарисовать графики для ОЗУ, файла подкачки, разделов диска, электропитания, загрузки эзернета
За это сообщение автора kos поблагодарили (всего 2):
Ruslan (Пн янв 11, 2016 11:23 pm) • VGorokhov (Ср янв 27, 2016 1:13 am)
Рейтинг: 2.33%
Ruslan
Сообщения: 37
Зарегистрирован: Чт апр 09, 2015 7:11 pm
Благодарил (а): 7 раз
Поблагодарили: 1 раз

Re: Телеметрия локального сервера BananaPI на Bananian Linux

Сообщение Ruslan » Пн янв 11, 2016 11:31 pm

Уважаемый kos

Интересное решение. Спасибо.

Столкнулся с проблемкой.
Не получается изменить права на файл:

Код: Выделить всё

/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
Точнее права изменяются, но после перезагрузки слетают. :(
За это сообщение автора Ruslan поблагодарил:
VGorokhov (Ср янв 27, 2016 1:15 am)
Рейтинг: 1.16%
RaspBerry Pi 2 | MajorDoMo lastUpdate:27/04/2017
kos
Сообщения: 5
Зарегистрирован: Вт июл 14, 2015 2:49 pm
Откуда: Пенза
Благодарил (а): 3 раза
Поблагодарили: 4 раза

Re: Телеметрия локального сервера BananaPI на Bananian Linux

Сообщение kos » Ср фев 10, 2016 10:25 am

Добрый день!
Прошу прощения за долгий ответ. Совсем не было времени заниматься этим проектом.

Ruslan,
Может не совсем красивое решение, но работает:
добавить в конец /etc/init.d/rc.local

Код: Выделить всё

chmod 444 /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
За это сообщение автора kos поблагодарил:
Ruslan (Пт фев 26, 2016 3:46 pm)
Рейтинг: 1.16%
Аватара пользователя
Rage_4er
Сообщения: 16
Зарегистрирован: Вс дек 18, 2016 4:20 pm
Благодарил (а): 11 раз
Поблагодарили: 0

Re: Телеметрия локального сервера BananaPI на Bananian Linux

Сообщение Rage_4er » Пн фев 06, 2017 4:54 pm

Подскажите, у меня Orange Pi PC Plus на Armbian_5.24_Orangepipcplus_Debian_jessie_3.4.113, что-то надо доставлять в систему? В таком виде ничего не получается.. Или код менять надо где-то?
Orange Pi PC Plus

CONNECT
kos
Сообщения: 5
Зарегистрирован: Вт июл 14, 2015 2:49 pm
Откуда: Пенза
Благодарил (а): 3 раза
Поблагодарили: 4 раза

Re: Телеметрия локального сервера BananaPI на Bananian Linux

Сообщение kos » Пн фев 06, 2017 5:39 pm

Решение основано на модуле sunxi_dbgreg, которое читает регистры процессора A20 ARM Cortex-A7™.
Не знаю есть ли возможность читать данные этим модулем из вашего процессора.
Проверьте загружен ли в ядре модуль sunxi_dbgreg. Можно попробовать его туда установить. Есть пример установки на форуме кубика http://www.cubieforums.com/index.php?topic=2493.0
Возможно под ваш проц придется что-то допилить.
Аватара пользователя
Rage_4er
Сообщения: 16
Зарегистрирован: Вс дек 18, 2016 4:20 pm
Благодарил (а): 11 раз
Поблагодарили: 0

Re: Телеметрия локального сервера BananaPI на Bananian Linux

Сообщение Rage_4er » Пн фев 06, 2017 5:55 pm

kos писал(а):Решение основано на модуле sunxi_dbgreg, которое читает регистры процессора A20 ARM Cortex-A7™.
Не знаю есть ли возможность читать данные этим модулем из вашего процессора.
Проверьте загружен ли в ядре модуль sunxi_dbgreg. Можно попробовать его туда установить. Есть пример установки на форуме кубика http://www.cubieforums.com/index.php?topic=2493.0
Возможно под ваш проц придется что-то допилить.
Хорошо. Спасибо. Поизучаю)
Orange Pi PC Plus

CONNECT
Ответить