четверг, 25 мая 2017 г.

Мониторинг GPU (и не только) с отправкой статистики в Telegram.

В один прекрасный день, отчасти познакомившись с различными статьями в интернете, например вот этой - Raspberry и Telegram: предпосылки создания умного дома и этой - Отправка состояния сервера через Telegram, а также благодаря просьбам нескольких знакомых, занимающихся майнингом на видеокартах, я задумался о реализации возможности отправки статистики состояния GPU (теоретически, это не обязательно именно статистика с GPU, а статистика чего угодно) в Telegram, в рамках периодического мониторинга. На тот момент, когда я заинтересовался этой проблемой общая задача стояла так, есть некий ПК с 6-ю видеокартами на борту. Необходимо периодически в какой-то удобной форме отправлять / отображать с него статистику по температурам и скорости вращения вентиляторов каждого из GPU в процентах. Конечно всегда можно пойти и другим путем, например, настроив на этом ПК тот же Open Hardware Monitor. В нем помимо всего есть также встроенный web-сервер со статистикой (т.е. ни Apache, ни другой web-сервер для отображения статистики через web поднимать не нужно, достаточно настроить Remote Web Server в Open Hardware Monitor), отображение информации при обращении к которому выглядит примерно так:


Или, например, считать ту же самую информацию с помощью WMI (Open Hardware Monitor представляет Data Interface, доступный через WMI, ознакомиться с API которого можно здесь), отправляя ее потом на сервер статистики / по email / в SMS, вообщем как угодно просто в текстовой форме. Однако, в данном случае задача может осложниться тем, что примеров чтения информации о датчиках через WMI из Open Hardware Monitor очень мало (с наиболее удачным из них можно познакомиться здесь - How to reboot a rig if it stops mining?). Вот пример готового PowerShell скрипта, который читает информации о температурах всех GPU AMD установленных в системе:

$GPUTemps = Get-WmiObject -namespace root\openhardwaremonitor -class sensor | Where-Object {$_.SensorType -Match "temp" -and $_.Identifier -like "*gpu*"} 
$GPUNumber = 0
$GPUTempString = ""
ForEach($GPU In $GPUTemps)  {
 $GPUNumber++
 $GPUTempValue = $GPU.value
 $GPUTempString = $GPUTempString + $GPU.value + ";"
        #Write-Host "[" $GPUNumber "]" $GPUTempValue    
}
Write-Host $GPUTempString

Однако при попытке выполнить данный скрипт у вас может возникнуть ошибка:


Связанная с ExecutionPolicy. Почитать про ExecutionPolicy для PowerShell скриптов можно тут - Set-ExecutionPolicy и тут - 15 способов обхода PowerShell Execution Policy, и выполнив в консоли тот же самый скрипт как powershell -ExecutionPolicy RemoteSigned ./getinfo.ps1 мы получаем результат:


Т.е. строку с температурами всех GPU в системе - 63;63;63;63;62;63; Полученные данные вполне можно уже отправлять как обычный текст любым доступным для вас способом или даже настроить Zabbix Agent'ы для мониторинга.

Но как же быть с отправкой этих данных в Telegram, спросите вы? Сейчас расскажу ... но пока хотелось бы обратить внимание на другой момент. Как вы понимаете, получать данные в о текущем состоянии температур в текстовом виде - хорошо, но неплохо бы добавить и графиков. Здесь есть два пути - первый, это отправка полученных данных на некий сервер статистики и построение графиков с помощью того же Google Chart Tools API. Способ этот хорош, но для реализации требует наличия самого сервиса и некоторых навыков программирования, поэтому его реализацию мы оставим на потом. А пока обратимся к уже существующим средствам визуализации. Думаю многим из тех кто читает эту статью знакома утилита MSI Afterburner в которой вывод всех необходимых графиков с сенсоров уже реализован (см. скриншот).

Кто мешает нам использовать эти удобные, уже существующие графики и отправлять их непосредственно скриншотом куда-либо? По-сути никто. Весь вопрос состоит лишь в правильной оптимизации процесса. И здесь опять же есть два пути. Постараюсь рассказать о каждом из них "на пальцах". У Telegram есть достаточно неплохой API для ботов, т.е. как один из возможных вариантов решения изначально мне виделся следующий. Собираем на локальном хосте все необходимые данные в виде массива информации, т.е. например текстовые данные о температурах плюс скриншот с графиками. Отправляем все это с помощью GET/POST на сервер с Telegram ботом, который уже по запросу предоставляет всю эту информацию. Однако, подобный вариант опять же требует некоторых усилий, как минимум это поднятие сервера с HTTPS (для запуска бота) и время на написание самого бота. Этот вариант я также решил "отложить на потом", т.к. теоретически есть более простой вариант. К примеру, представьте себе что на машине с которой вы хотите снимать показания удаленно есть обычный Telegram клиент. Для отправки данных остается только каким-либо образом автоматизировать отправку текстового сообщения и полученной картинки (скриншота) нужному контакту. И вот тут как раз нам на помощь приходит проект telegram-cli от Vitaly Valtman'а.

С тем как работает telegram-cli и как можно его применять для отправки статистики вы уже наверняка познакомились в этой статье, однако в ней клиент собирают под Raspberry Pi, а наша задача собрать его именно для использования под Windows. Благо на Git'е есть небольшая инструкция по сборке под Windows с использованием CygWin, ей, с небольшими модификациями мы и будем руководствоваться.

Первым делом установим Cygwin отсюда (в моем случае была x64 система, поэтому я устанавливал качал именно  setup-x86_64 установщик). Установим его так:

 setup-x86_64 -q -P wget,tar,qawk,bzip2,subversion,vim

Чтобы у нас сразу был wget, tar и некоторые другие пакеты. Затем установим apt-cyg, чтобы иметь возможность устанавливать другие пакеты (это уже нужно делать в запущенном cygwin окружении):

 wget rawgit.com/transcode-open/apt-cyg/master/apt-cyg
 install apt-cyg /bin

Далее установим зависимости и соберем libconfig и libjansson:


 apt-cyg install cygwin32-gcc-core cygwin32-gcc-g++ gcc-core gcc-g++ make wget patch diffutils grep tar gzip
 apt-cyg install libevent-devel openssl-devel libreadline-devel lua-devel python3
 apt-cyg install zlib zlib-devel
 apt-cyg install dos2unix

 wget http://www.hyperrealm.com/libconfig/libconfig-1.5.tar.gz
 tar xvf libconfig-1.5.tar.gz && cd libconfig-1.5
 ./configure
 make && make install && cd ..

 wget http://www.digip.org/jansson/releases/jansson-2.7.tar.gz
 tar xvf jansson-2.7.tar.gz && cd jansson-2.7
 ./configure
 make && make install && cd ..
Затем соберем сам telegram-cli, для этого склонируем репозитарий:

 git clone https://github.com/vysheng/tg

И соберем все:

 cd tg
 dos2unix ./configure
 ./configure
  make

Если сборка прошла успешно, то в папке bin мы получим бинарники generate.exe, telegram-cli.exe и tl-parser.exe:


Но скорее всего будут проблемы, которые решаются так:

  1. Если сразу после запуска ./configure будет ошибка, это значит что файл ./configure у вас не в Unix кодировке, т.е. вместо LF (Line Feed) используются и другие символы для перевода строки. Именно поэтому мы делаем dos2unix ./configure, но если по каким-то причинам он отработает некорректно, то можно взять тот же Far Manager, открыть файл в текстовом редакторе в нем, а затем сохранить (Shift+F2), используя в качестве символа переноса LF (Unix Format).
  2. Если у вас возникает ошибка вида "tgl/tl-parser/tl-parser.c:1:0: ошибка: -fPIC ignored for target (all code is position independent) [-Werror]", это также легко исправляется. Открываем Makefile и из строки COMPILE_FLAGS удаляем ключ -fPIC, а из строки LOCAL_LDFLAGS ключ -rdynamic.
  3. Если у вас возникает ошибка после запуска make "event-old.h:10:0: ошибка: «BEV_EVENT_ERROR» переопределён [-Werror]" это значит что configure не определил libevent и некорректно сформировал config.h, тут еще проще, добавляем в конец config.h строчку #define EVENT_V2 1 и перезапускаем make.
После того как мы все собрали, запускам telegram-cli из Cygwin окружения и регистрируем аккаунт, т.е. указываем номер телефона, пароль из SMS и все готово к работе:


С подробным списком команд можно ознакомиться в Wiki - Telegram CLI Commands. Теперь давайте займемся автоматизацией отправки сообщений.

В приведенном примере мы запускали telegram-cli из CygWin окружения. Если же оно не установлено, т.е. если мы попытаемся запустить собранный бинарник на машине где нет библиотек CygWin, мы естественно получим ошибку. Поэтому в папку с бинарником кладем еще и следующие используемые им библиотеки по списку:

  • cygcrypto-1.0.0.dll
  • cygevent-2-0-5.dll
  • cygncursesw-10.dll
  • cygreadline7.dll
  • cygwin1.dll
  • cygz.dll
  • cygconfig-9.dll

Плюс необходимо настроить переменные окружения TELEGRAM_CONFIG_DIR и TELEGRAM_HOME для того чтобы telegram-cli находил папку с config'ом. В общем случае пакетный файл для отправки сообщения пользователю @username может выглядеть так:


@echo off 
set TELEGRAM_CONFIG_DIR=.telegram-cli
set TELEGRAM_HOME=%~dp0
(echo dialog_list
timeout /t 3 > nul
echo msg @username Just a test ...
echo.
echo safe_quit
) | telegram-cli.exe --disable-readline 

Т.е. просто копируем это содержимое в .bat (.cmd) файл, например msg.cmd, запускаем его и пользователь @username получает сообщение Just a test. Если нам необходимо отправить картинку, то сделать это можно с помощью команды send_photo в telegram-cli.

Если кому-то тема отправки статистики в Telegram окажется интересной, чуть позже я выложу полный пакет готовый к работе. Т.е. скачал, распаковал, настроил запуск отправки статистике в планировщике и всё. Ну а пока буду рад выслушать ваши предложения и комментарии.

Обновлено 25.05.2017 16:59 (MSK)

Готовая сборка Telegram-Cli под Windows со всеми необходимыми библиотеками, а также примером скрипта для отправки скриншота из MSI Afterburner:

  • Архив: tg-cli-stat.7z 
  • Пароль на архив: decker.su
  • SHA256: 7e97be78699af80e719cf3b4fb4204d14f3c30cae5a569cd485bb02ca308f9a1

Подробная инструкция находится внутри архива в файле readme.txt.

6 комментариев :

  1. вроде все по инструкции но не приходит сообщение от бота. при открытии msg.cmd скриншот появляется в папке но сообщение с ним не приходит

    ОтветитьУдалить
    Ответы
    1. Ну, а сам telegram-cli работает? Запустите register.cmd и попробуйте написать себе сообщение.

      Удалить
  2. у меня такая же проблема, запускал register.cmd и писал сообщение оно туда приходит а вот скрин от него не приходит

    ОтветитьУдалить
    Ответы
    1. Допустим у вас shot.png уже содержит ваш скриншот и лежит в папке с telegram-cli. Если из консоли telegram-cli набрать send_photo @username shot.png, где @username - имя пользователя (username) в Telegram которому вы отправляете сообщение, картинка приходит? Приведите скриншот из telegram-cli.

      Удалить
  3. когда я запускаю telegram-cli. он просто открывается и тут же окно закрывается, но если запустить register.cmd то когда я пишу на этот номер зарегистрированный то в окне сообщения приходят
    а если отправить команду как Вы говорили выходит следующая ошибка:
    Telegram-cli version 1.4.1, Copyright (C) 2013-2015 Vitaly Valtman
    Telegram-cli comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.

    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show_license' for details.
    Telegram-cli uses libtgl version 2.1.0
    Telegram-cli includes software developed by the OpenSSL Project
    for use in the OpenSSL Toolkit. (http://www.openssl.org/)
    I: config dir=[.telegram-cli]
    I: config file=[D:\tg-cli-stat\/.telegram-cli/config]
    [17:37] Мой Теле2 >>> Fghjk
    send_photo @Мой Теле2 shot.png
    FAIL: 88: can not parse arg #1
    User Мой Теле2 offline (was online [2017/06/22 17:38:53])

    ОтветитьУдалить
    Ответы
    1. "@Мой Теле2" - не является валидным username. Все просто. Не путайте имя пользователя так, как оно отображается в списке контактов и @username в Telegram. Откройте меню Settings в Telegram на устройстве пользователя "Мой Tele2", затем на вкладке Info нажмите по графе Username и выберите username для данного пользователя (username состоит из одного слова и пробелов там быть не может). Затем заново запустите register.cmd и повторите команду send_photo @username shot.png.

      Удалить