29 Дек

Настройка автоматического запуска puma при перезагрузке сервера

Для своих Rails-приложений я в последнее время использую связку puma+nginx. И достаточно продолжительное время я ленился настроить функционал автоматического старта приложений при ребуте сервера. Ну, типа, раз в месяц если он перезапустится, то и фиг с ним, вручную стартану. Благо, что особо критичных к простою проектов у меня нет (на самом деле есть, но там очень быстро мне сообщают о проблеме и я её очень быстро решал). Но надо что-то менять и я решил, что пришло то самое время.

Читать далее
07 Май

Статистика по переходам в меню IVR

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

Итого, на руках имеем Freeswitch с реализованными на нем разными IVR-менюшками и всё.
В итоге решил сделать так: подключаем mod_curl, и в каждом пункте меню делаем сначала вот такой запрос

<entry action="menu-exec-app" digits="1" param="curl http://my.backend/add?anumber=${caller_id_number}&bnumber=${destination_number}&key_pressed=1" />

Это, соответственно, для единицы. Для других пунктов в нужных местах меняем цифру на необходимую.

В итоге у нас перед выполнением какого-то действия, которое запланировано при нажатии на кнопку, выполняется сначала запрос на заранее созданный бэкенд, а там уже это всё добавляется в БД. Ну и дальше мы уже с этими данными можем делать что хотим.
Да, при большом количестве меню это становится довольно муторным делом, но в целом это все занимает не так уж и много времени и всё-таки основная работа уходит на обработку статистики, а не на ее сбор.
Из нюансов могу отметить, что тут не отмечаются абоненты, которые не нажали вообще ничего. Но нам же нужна статистика по нажатиям, а не по «ненажатиям» :)

10 Фев

Восстановление FusionPBX при удалении самого первого домена.

Спиздил статью вот отсюда на всякий случай.

При удалении самого первого домена может случиться с ним несчастье, — перестанет пускать админа (  обычно это admin или superadmin ) на веб-консоль для управления!

Но Вам это поможет только в том случае, если Вы не удалили _все_ домены из FusionPBX перед этим. Если-же удалили все то лучше просто снести папку fusionpbx из /var/www, и обязательно удалить базу !!! После чего запустить наш инсталяционный скрит опять.

В принципе всегда можно все снести папки /usr/local/freeswitch и /var/www/fusionpbx , снести базы и начать все с нуля, но я решил разобраться, смогу-ли я восстановить только пользователя, не пересоздавая все.
Читать далее

25 Авг

Формат даты OLE

В БД одной из программ, с которой мне довелось столкнуться, дата записывалась числом в следующем формате 42004.9492447917.
Сначала я немного не понял, потом поискал в интернете и всё понял.
В общем, это запись даты в формате OLE (так называемый OLE Automation Date или дата с плавающей точкой).

Логика переформатирования в обычную дату следующая:
число до запятой — количество дней, прошедших с полуночи 30 декабря 1899 года
число после запятой  — часть дня, которая прошла с его начала. То есть если в сутках у нас 86400 секунд, то полдень будет выражен числом 0.5, как-то так.

То есть, если нам нужно перекодировать число 42004.9492447917 в обычную дату, считаем, то получаем следующее:
42004 — это 42004-й день с 30 декабря 1899 года, то есть 01 января 2015 года
0.9492447917 — это количество секунд, которое прошло с 00:00 этого же дня, разделенное на общее количество секунд в сутках, то есть 0.9492447917*86400 = 82014 секунды, то есть 22 часа 46 минут 54 секунды.
В итоге получаем дату: 01.01.2015 22:46:54

Написал пару небольших функций на RUby для конвертирования дат из одного формата в другой.
Для начала, конечно же, запросим require 'time'

Из OLE в стандартный формат:

def convert_time(t)
 puts Time.at((time.to_f - 25569) * 86400).utc
end

utc в конце необходим для того, чтобы вам выдалось время без поправки на вашу таймзону.
time.to_f — конвертируем входные данные в float
(time.to_f - 25569) — делаем началом отсчета 1 января 1970 года
((time.to_f - 25569) * 86400) — конвертируем дату в Unix time

Из стандартной даты в OLE:

def to_ole(t)
 Time.parse(t).to_f/86400 + 25569
end

Здесь изначально дата должна быть в любом подходящем формате и обязательно с указанием UTC, иначе скрипт будет прибавлять или отнимать к нужному времени количество часов для подгонки под локальное время.
Собственно всё.

05 Мар

Ruby-скрипт в cron

Для работы понадобилось как-то написать небольшой скриптик по парсингу XML-ки и поставить его на выполнение в крон каждый вечер. Сам скрипт написать не проблема. «Да и в крон поставить нефиг делать», — подумал я. Но не совсем.

Поставил в крон. Проверяю в назначенное время — не работает.

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

Не работает.

Смотрю логи — теперь не может загрузить Nokogiri. Мудился-мудился, искал варианты, витоге всё-таки нашел, в чем магия. Оказывается нужно было в крон прописать всякие системные переменные для рубей. Либо вручную, либо при помощи команды rvm cron setup.
Попробовал — наконец-то заработало!
Такие дела.

21 Апр

Настройка NRPE в Nagios на примере Debian сервера

Исходные данные:

  • Установлен Nagios
  • Установлен nagios-plugins
  • Установлен NRPE

Чтобы с помощью NRPE мониторить удаленный сервер, надо поставить на том сервере NRPE-демон, который будет запускать команды нагиоса у себя, а также установить плагины для нагиоса.

apt-get install nagios-nrpe-server
apt-get install nagios-plugins

Далее на целевом сервере идем в папку /etc/nagios и правим там файл nrpe.cfg

Выставляем

#адреса, с которых разрешено обращение к демону nrpe
allowed_hosts=<ip-адрес сервера, на котором установлен Nagios>

#опция, которая позволяет присылать аргументы
dont_blame_nrpe=1

А также почти в самом конце прописываем команды, которые будут выполняться. Напрмиер вот такую: Читать далее