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


Sampler


Наблюдение за изменением состояния в базе данных, мониторинг размера очередей, телеметрия с удаленных серверов, запуск деплой скриптов и получение нотификации по завершению — конфигурируется за минуту простым YAML файлом.


Код доступен на гитхабе. Инструкции по установке — для Linux, macOS и (экспериментально) Windows.


Зачем мне это, когда есть полноценные системы мониторинга?


Сразу оговорюсь, что это ни в коей мере не альтернатива полномасштабным дашбордам и мониторингу. Сравнивать Sampler c Prometheus+Grafana — то же что сравнивать tail и less с Elastic Stack или Splunk.


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


Значит его надо ставить на все сервера?


Нет, Sampler можно запускать локально, но метрики забирать со многих удаленных машин. Каждый компонент на дашборде имеет init секцию, где можно произвести вход по ssh (или сделать любое другое действие для входа в interactive shell — установить соединение с БД, подключиться по JMX, авторизоваться в API, итп)


Виды компонентов и примеры конфигурации


В примерах конфигурации приведены команды для macOS. Многие будут работать без изменений под Linux, но некоторые нужно адаптировать.


Runchart




Конфигурация
runcharts:
  - title: Search engine response time
    rate-ms: 500     # sampling rate, default = 1000
    scale: 2         # number of digits after sample decimal point, default = 1
    legend:
      enabled: true  # enables item labels, default = true
      details: false # enables item statistics: cur/min/max/dlt, default = true
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com
      - label: BING
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.bing.com

Sparkline




Конфигурация
sparklines:
  - title: CPU usage
    rate-ms: 200
    scale: 0
    sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
  - title: Free memory pages
    rate-ms: 200
    scale: 0
    sample: memory_pressure | grep 'Pages free' | awk '{print $3}'

Barchart




Конфигурация
barcharts:
  - title: Local network activity
    rate-ms: 500        # sampling rate, default = 1000
    scale: 0            # number of digits after sample decimal point, default = 1
    items:
      - label: UDP bytes in
        sample: nettop -J bytes_in -l 1 -m udp | awk '{sum += $4} END {print sum}'
      - label: UDP bytes out
        sample: nettop -J bytes_out -l 1 -m udp | awk '{sum += $4} END {print sum}'
      - label: TCP bytes in
        sample: nettop -J bytes_in -l 1 -m tcp | awk '{sum += $4} END {print sum}'
      - label: TCP bytes out
        sample: nettop -J bytes_out -l 1 -m tcp | awk '{sum += $4} END {print sum}'

Gauge




Конфигурация
gauges:
  - title: Minute progress
    rate-ms: 500        # sampling rate, default = 1000
    scale: 2            # number of digits after sample decimal point, default = 1
    percent-only: false # toggle display of the current value, default = false
    color: 178          # 8-bit color number, default one is chosen from a pre-defined palette
    cur:
      sample: date +%S  # sample script for current value
    max:
      sample: echo 60   # sample script for max value
    min:
      sample: echo 0    # sample script for min value
  - title: Year progress
    cur:
      sample: date +%j
    max:
      sample: echo 365
    min:
      sample: echo 0

Textbox




Конфигурация
textboxes:
  - title: Local weather
    rate-ms: 10000      # sampling rate, default = 1000
    sample: curl wttr.in?0ATQF
    border: false       # border around the item, default = true
    color: 178          # 8-bit color number, default is white
  - title: Docker containers stats
    rate-ms: 500
    sample: docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}"

Asciibox




Конфигурация
asciiboxes:
  - title: UTC time
    rate-ms: 500        # sampling rate, default = 1000
    font: 3d            # font type, default = 2d
    border: false       # border around the item, default = true    
    color: 43           # 8-bit color number, default is white
    sample: env TZ=UTC date +%r

Дополнительная функциональность


Триггеры


Триггеры позволяют запустить некоторое дополнительное действие, если замеряемое значение удовлетворяет заданному условию. Как условие, так и реакция — это так же shell команды, в которые подаются переменные $label, $cur и $prev. В первую очередь триггеры задумывались для алертинга (встроены звуковые и визуальные нотификации), но c опцией вашего собственного скрипта для реакции на срабатывание триггера его действие можно кастомизировать как угодно (например отправить нотификацию на телефон с Pushover)


Пример ниже иллюстрирует конфигурацию триггеров. Если latency ответа поисковой системы превысит 0.3 sec — Sampler моргнет стандартным terminal bell, проиграет NASA quindar tone, покажет визуальную нотификацию на графике и запустит скрипт, который в данном случае голосом произносит измеренное значение latency:


runcharts:
  - title: SEARCH ENGINE RESPONSE TIME (sec)
    rate-ms: 200
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com     
    triggers:
      - title: Latency threshold exceeded
        condition: echo "$prev < 0.3 && $cur > 0.3" |bc -l  # ожидает "1" как TRUE
        actions:
          terminal-bell: true  # default = false
          sound: true   # NASA quindar tone, default = false
          visual: true  # default = false
          script: 'say alert: ${label} latency exceeded ${cur} second'

Interactive shell


Если до начала семплирования необходимо произвести вход в interactive shell (для единовременного подключения к БД, входа по SSH, подключения к JMX, итп) — можно указать init script, который исполнится один раз при старте. Пример подключения и опроса mongoDB:


textboxes:
  - title: MongoDB polling
    rate-ms: 500
    init: mongo --quiet --host=localhost test # выполнится один раз
    sample: Date.now(); # сработает в рамках mongo shell
    transform: echo result = $sample # выполнится в рамках локальной сессии для преобразования значения

Кроме того, есть поддержка PTY режима и multistep-init скриптов.


Переменные


Если в конфигурации присутствуют часто используемые части, которые не хочется повторять — их можно вынести в переменные и использовать в любом месте YML файла.


На практике


Как бекенд-программисту, мне часто приходится отлаживать, прототипировать и измерять. Отсюда и регулярная необходимость визуализации и мониторинга на скорую руку. Писать каждый раз что-то кастомное — неоправданно долго, но если процесс кастомизации был бы быстрым и (более-менее) удобным, такая визуализация вполне могла бы экономить время и решать задачи. Ничего подобного мне найти не удалось, поэтому было решено писать такой инструмент самому, и сделать его как можно более универсально конфигурабельным.


В самый первый раз по назначению я начал его использовать для отладки механизма группировки и аккумуляции данных, который быстро меняет статусы "событий" в памяти. Чтение состояния системы из логов или опрос отдельных счетчиков по каждому из статусов никак не помогает быстро сориентироваться и понять что к чему, а один взгляд на Sampler вполне решает эту задачу —




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


  • Соединения с базами данных: MySQL, PostgreSQL, MongoDB, Neo4J
  • Kafka
  • Docker
  • SSH
  • JMX

Этот список будет дополняться (и ваш вклад очень приветствуются), а тем временем в issues люди начали делиться своими конфигурациями для дашбордов Kubernetes, Github, и прочим.


Это все, хабр. Буду рад, если кому-то окажется полезным.

Комментарии (51)


  1. RafaelRS
    19.08.2019 07:17

    Годнота! Респект за работу.


  1. sshikov
    19.08.2019 08:15

    А как вы работаете с JMX? У вас же go, как я вижу.


    1. pixelcube
      19.08.2019 14:09

      jmxterm


  1. D_E_S
    19.08.2019 08:59

    Попробовал. Прикольная вещь, только возникла проблемам с кодировкой символов. (отписал в Issues)


  1. VioletGiraffe
    19.08.2019 10:29

    Очень красивый интерфейс! Местами и не скажешь, что терминальный.


  1. ivanz85
    19.08.2019 12:23

    Красота! Grafana, которой не нужно куча ресурсов на отрисовку.


  1. razielvamp
    19.08.2019 14:43
    +1

    Еще бы демона небольшого прикрутить, чтобы алерты слал, и я бы променял эту штуку на zabbix.


    1. sqshq Автор
      20.08.2019 02:33

      Триггеры срабатывают при выполнении условия (например превышение некоторого значения) и могут выполнять произвольный скрипт — например слать алерты по email или pushover


      1. razielvamp
        20.08.2019 04:37

        Да, про триггеры я прочитал, но вот про демона и как его запускать, вродебы, совсем не упомянуто.


        Поэтому не совсем понятно — толи в бекграунде в баше запускать, чтобы отлогинится можно было, толи есть готовый сервис (что-то init.d или systemd подобное).


        1. DeeZ
          20.08.2019 06:20

          Запускайте в screen


          1. razielvamp
            20.08.2019 07:25

            Это конечно мое субъективное мнение, но если бы при мне в проде (даже маленьком) кто-нибудь таким занимался, я бы по рукам надавал. Это определенно уровень "костыли". С таким же успехом можно в баше & на конце запустить.


            Мало того, что это не интуитивный подход, так еще и нельзя гарантировать длительное выполнение процесса. Что если второй админ залезет и перезагрузит скрин? Или сервер банально перезагрузится?


            В таких случаях простецкий bash демон на systemd гораздо более правильное и легко контролируемое решение. И, на мой взгляд, необходимое из коробки, при наличии функционала нотификаций.


    1. mkll
      20.08.2019 19:00

      Простите, но все-таки вы бы променяли zabbix на эту штуку.


  1. vitaliykiev
    19.08.2019 14:49
    +1

    Спасибо, утянул к себе.


  1. SH42913
    19.08.2019 14:49
    +2

    Выглядит супер красиво! Как такое рисовать?
    Даже жаль, что при разработке на Unity такое почти не нужно :(


    1. sqshq Автор
      19.08.2019 15:37
      +1

      Для go существует немало библиотек для отрисовки в терминале. Я выбрал termui — обертку над более низкоуровневой termbox-go. В какой-то момент стало понятно, что заиспользовать готовые компоненты оттуда мне не подходит — чтобы сделать хорошо и красиво, все графики и компоненты для семплера пришлось реализовывать самому, используя тот же низкоуровневый API (рисуй из этой точки в эту, таким-то цветом). Так что я уже некоторое время думаю над тем чтобы отказаться от обертки и использовать просто termbox-go, или например gocui


      1. babylon
        20.08.2019 04:19

        Вопрос риторический. Как работать мышкой в утилите?


        1. sqshq Автор
          20.08.2019 04:24

          Почему риторический? Клик мышкой выделяет компонент, далее для изменения размеров или перемещения — стрелками. Можно обрабатывать еще больше кликов (выделение пунктов меню, перетаскивание элементов). Но мне показалось это не слишком полезно для консольной утилиты, клавишами все равно привычнее и удобнее


    1. GavriKos
      19.08.2019 16:51

      При разработке такое в принципе мало нужно ИМХО, не важно на чем.
      Разве что подцепить к сборочной машине и к тестам (и то и то можно использовать в Unity).
      А вот в продакшне как раз кейсов тьма. Начиная от классического мониторинга серверов (если игра хоть как то с бекендом), и заканчивая забиранием данных из аналитических систем для красивого вывода на стенку )


    1. engine9
      20.08.2019 00:08

      Если привлекает эстетика, гляньте в сторону conky.


      1. SH42913
        20.08.2019 06:34

        Мне нравится конкретно ASCII-эстетика, Conky, если я правильно понимаю, такого не предлагает


  1. VivAmigo
    19.08.2019 14:50

    А всё же есть в мире ребята, способные приятно удивить. Работу принял, забираю на всю жизнь.


  1. RollerBob
    19.08.2019 14:50
    +1

    Сервер погоды упал :)


  1. 20ivs
    19.08.2019 14:50
    +1

    Шикарно! Спасибо!


  1. amarao
    19.08.2019 15:55

    Недавно обнаружил, что monin непоправимо улучшили и в пол-пинка его на сервере больше не поднять. Оказалось, что у нас большая дыра в мониторинге — если есть маленький standalone сервер, то трудно получить там self-sustained мониторинг задёшево. Остался только старичок atop. Возможно, эта штука станет решением.


    1. blind_oracle
      19.08.2019 17:11

      monin
      Продукт любви Monit и Munin? :)


      1. amarao
        19.08.2019 17:21

        munin. Я как посмотрел на его в новой редакции, так и забыл про его существование навсегда.


    1. lorc
      19.08.2019 17:32

      смотрели на collectd?

      К нему правда UI надо сбоку прикручивать. Но их есть несколько разных. Как web-based так и standalone.


      1. amarao
        19.08.2019 18:06

        Вся проблема как раз в том, что все новые системы мониторинга/производительности — чертовски модульные.


        А хочется — херак, и для localhost можно метрики смотреть. С разумными настройками ротации, готовыми view и т.д. Я понимаю, что универсальность это важно для сложных систем, но для скромного localhost'а, там, вдалеке...


        1. lorc
          19.08.2019 18:24

          Ну collectd почти такой — отдельно демон, который искаропки собирает метрики. А потом можно поставить какой-нить Kcollectd или любую смотрелку rrd файлов.

          Во всяком случае, ничего лучше для одного хоста я не знаю. Zabbix — он же страшный и огромный. Всякие Grafana — туда же.


  1. Fi1osof
    19.08.2019 16:40

    Просто за три секунды добавил мониторинг своего сайта и положил его за минуту (интервал 500 мсек). Спасибо! Отличная штука!


  1. Elfet
    19.08.2019 17:01
    -1

    Скажите, а много получается на донате заработать? :)


  1. Arseniy_K
    19.08.2019 17:23
    +1

    Ждём ебилдов.


  1. AlexAV1000
    19.08.2019 19:32

    Блин, я подумал это псевдографика.


  1. osmanpasha
    19.08.2019 20:10

    Очень красиво выглядит программа! Но есть один вопрос: правильно ли я понимаю, что в файле конфигурации описания должны быть скопированы по типу визуализации: сначала все линии, потом все столбики и т.д? Если так, то это довольно неудобно, так как обычно конфигурацию хочется писать в логическом порядке: сначала все про загрузку процессора, потом про базу данных и т.д. Намучался с такой системой в Home assistant, в котором тоже нужно группировать объекты по типам


  1. slovak
    19.08.2019 20:28

    Подскажите, есть ли планы добавить организацию бордов в табы?
    Благодарю!


    1. sqshq Автор
      20.08.2019 01:26

      Если речь только о группировке разных компонентов в одну рамку под некоторым заголовком — это можно сделать сейчас


      image


      Если же речь о табах как в tmux, то пока не планировалось. Двигать компоненты можно прямо из UI, их размеры и положение относительны размеру окна.


  1. RNZ
    19.08.2019 21:02
    -1

    Годно! Однако, есть вот такая штука — https://github.com/netdata/netdata, к которой было-бы логично прикрутить консольный фейс.


  1. Pyhesty
    19.08.2019 23:17

    Ностальджи по ascii графике =) Спасибо!


    1. GavriKos
      20.08.2019 10:47
      +1

      ASCII графика, вставленная картинкой? ))


  1. grundic
    19.08.2019 23:32

    До этого использовал github.com/tenox7/ttyplot. Как раз нужно было на локальных инстансах мониторить некоторые вещи. С этим проектом, думаю, будет в разы удобнее. Отличная работа!

    А вдруг кто-то знает, вдруг есть нечто подобное но web-oriented? Бывает запускашь локальный билд и хочется расшарить метрики с коллегами. Для себя терминал это хорошо, но было бы удобно, если была бы возможность в вебе такое делать (но без поднятия полномасштабного мониторинга). Спасибо.


  1. khazhinov
    20.08.2019 01:17
    +1

    Просто вау
    Разместить такое вместо фона в безрамочном терминале и получится рабочий стол по круче любого хакера из сериала)
    Сразу вопрос. Есть ли пробная конфигурация для сбора метрик с локальной машины (CPU, ОЗУ и т.д.) под Windows?


    1. sqshq Автор
      20.08.2019 01:19

      Спасибо. Пока такой конфигурации нет, но если сделаете сами — не стесняйтесь отписаться на гитхабе (issue, или PR в README)


      1. androidovshchik
        20.08.2019 07:05

        А через cygwin нельзя?


        1. iandarken
          20.08.2019 12:41

          А через LSW нельзя?)


  1. Kellis
    20.08.2019 15:35

    чего может не хватать для ubuntu под wsl, если рисуется вот так?


    1. sqshq Автор
      20.08.2019 15:58

      Под WSL не работает механизм font-fallback, а ваш дефолтный шрифт не поддерживает используемые символы. У майкрософта есть issue на этот счет. Пока что можно попробовать поменять шрифт на Courier New, как предлагают пользователи


      1. Kellis
        20.08.2019 16:13

        Courier New не помог, а вот использование нового терминала — вполне, спасибо.
        Проблема изначально была в стандартном cmd.


  1. bod
    20.08.2019 18:51

    А как сделать такое:
    Используя

    curl http://host.ru:8888/actuator/health
    

    который возвращает в случае успеха
    {"status":"UP"}
    

    нарисовать зелёненьким UP
    и в любом другом случае
    красненьким DOWN?


  1. edo1h
    20.08.2019 22:55

    интересно, почему именно текстовый интерфейс?


  1. bodqhrohro
    20.08.2019 23:37

    Вау, наконец-то нашлась штука, которая позволит заменить мне вертикальную xfce4-panel с кучей genmon'ов с разным интервалом обновления на терминал! Но надо будет допилить чутка, ибо даже с border: false большие отступы остаются, и лишние элементы (заголовки/статусбар), похоже, не выключаются.


    P.S. Статусбар не из-за сообщения об активации лишний ;-) (оно и не влезет даже), а просто лишний.


  1. Urn
    23.08.2019 12:28

    А есть возможность запускать как oneliner, типа github.com/holman/spark?

    $ echo 1 2 3 1 | spark
    ?--?