Snusmumriken
Потому что если так, то тебе достаточно прост держать счётчик:
-- глобальный, на всяк случ, если данная переменная уже есть то используем её
bad_counter = bad_counter or 0
...
if isGoodRequest then
bad_counter = 0
else
bad_counter = bad_counter + 1
end
if bad_counter == 5 then
sendMail(...)
end
Тогда вообще на каждые пять плохих запросов подряд будет слать, и если много-много плохих запросов подряд — пришлёт только один раз. Если надо в целом на каждые пять плохих — обнуляем счётчик одновременно с sendMail
halt
Вот, уже вырисовывается)
halt
а isGoodRequest откуда береться?
Snusmumriken
Ну как ты проверяешь запрос, плохой он или хороший? Вот и запихни то условие вместо isGoodRequest (но добавь not, или поменяй местами условия if и else)
Snusmumriken
Вот ща типа полностью то как оно должно быть:
badreq = badreq or 0
local status = event:getHeader("State") or ''
local gateway = event:getHeader("Gateway") or ''
if status == "NOREG" and gateway == "mixnet" then
badreq = badreq + 1
else
badreq = 0
end
if badreq == 5 then
sendmail(...)
-- если хотим чтобы отправляло на
-- каждые пять плохих запросов подряд:
-- badreq = 0
end
Snusmumriken
Ну, то есть на самом деле, всё простенько, сам видишь. Но это только если все запросы обрабатывает один инстанс вм, и переменная badreq общая. На нескольких машинах или если на каждый запрос/серию запросов запускается новая вм, придётся шарить переменную через базу.
halt
Вот "плохой" статус это NOREG, но gateway несколько
Snusmumriken
Тогда ставь то условие, которое тебе нужно, панимаищ? : )
halt
ну, я же могу их перечислить OR?
Snusmumriken
Можешь
Denis
А можешь и не or, а таблицей
halt
хотя нет. тогда будет считаться в общем на все гейты
Snusmumriken
А ещё можешь занести их в табличку
isBad = {
NOREG = true,
NOREGISTER = true,
BADREG = true
}
if isBad[status] then ...
Или в такую табличку которую я приводил выше
Snusmumriken
Snusmumriken
Тебе нужна помощь с составлением условий, какой запрос плохой а какой хороший? : )
Snusmumriken
Можешь поменять местами гейты и статусы, тогда можно будет вместо
if enum[status] and enum[status][gateway] then ...
написать
if enum[gateway] and enum[gateway][status] then ...
Это не принципиально, но может быть меньше придётся заполнять, например отсутствие реакции на некоторые гейты в принципе (просто не добавляем их в enum, добавляем туда только то на что реагируем).
halt
Да я вот пока не вкурил. Условие плохое одно, но гейтов несколько. Если я сейчас так запилю, то счетчик же будет срабатывать на все NOREG. Скажем если с каждого гейта придет по одному NOREG, то оповещалка сработает
Snusmumriken
Ага
Snusmumriken
А тебе нужно чтобы на каждый гейт срабатывало по разному?
halt
Нужно чтоб каждый гейт считался
Snusmumriken
Тогда мути более сложный счётчик.
-- можем использовать local,
-- потому что таблички ссылочные,
-- заодно инициализируем, если это первый запрос
-- и её пока не существует
local badReq = badReq or {}
local status = event:getHeader("State") or ''
local gateway = event:getHeader("Gateway") or ''
-- заполняем нулём, если у нас ещё нет инфы по этому гейтвею
badReq[gateway] = badReq[gateway] or 0
if status == "NOREG" then
badReq[gateway] = badReq[gateway] + 1
else
badReq[gateway] = 0
end
if badReq[gateway] == 5 then
sendmail(...)
-- badReq[gateway] = 0
end
Snusmumriken
Теперь у тебя есть восхитительная табличка badReq, которая хранит все плохие статусы подряд для каждого гейтвея. Прекольно, да?
halt
Здорово)
halt
Буду пробовать
halt
Спасибо
Snusmumriken
Лучше подробно изучи луа, таблички — очень мощный инструмент. И довольно простой.
halt
Да вот как раз и пытаюсь осваивать
halt
Но без практики много непонятного. Причем я ни разу не программер
Snusmumriken
Ничо, это всё придёт с практикой. Я тоже не особо программер, хотя работаю им.
Pavel
Pavel
редиска предпочтительнее тем, что можно шарить стейт между пачкой воркеров\машин
Anton
всем привет. подскажите - как передать объект в lua_State - указатель. чтобы его можно было везде достать?
Snusmumriken
https://www.lua.org/pil/28.1.html
void *lua_newuserdata (lua_State *L, size_t size);
static int newarray (lua_State *L) {
int n = luaL_checkint(L, 1);
size_t nbytes = sizeof(NumArray) + (n - 1)*sizeof(double);
NumArray *a = (NumArray *)lua_newuserdata(L, nbytes);
a->size = n;
return 1; /* new userdatum is already on the stack */
}
Snusmumriken
Чтобы потом везде достать — передаёшь его как аргумент луа-функций.
Snusmumriken
Если хочешь чего-то похожего на ООП с луёвой стороны — вешаешь на этот указатель метатаблицу с __index равному табличке с методами объекта. Тогда сам указатель при вызове методов будет передаваться первым аргументом автоматически.
Anton
Snusmumriken
В следующих трёх главах. Стрелка вправо.
Anton
понял, спасибо
Maxim
Нужно чтоб каждый гейт считался
А пробовали prometheus посмотреть для хранения статусов? в grafana можно отображать красивые и яркие графики, а через alertmanager-bot делать рассылку сообщений при наступлении различных событий через необходимые каналы связи (почта, телеграм, slak, e.t.c), это я к тому что бы не тратить время на создание того что уже есть и можно взять коробку за даром - то есть безвозмездно.
Но я мог не верно понять решаемую вами задачу и мой совет заглянуть в доку prometheus вообще не к месту
halt
halt
Тогда мути более сложный счётчик.
-- можем использовать local,
-- потому что таблички ссылочные,
-- заодно инициализируем, если это первый запрос
-- и её пока не существует
local badReq = badReq or {}
local status = event:getHeader("State") or ''
local gateway = event:getHeader("Gateway") or ''
-- заполняем нулём, если у нас ещё нет инфы по этому гейтвею
badReq[gateway] = badReq[gateway] or 0
if status == "NOREG" then
badReq[gateway] = badReq[gateway] + 1
else
badReq[gateway] = 0
end
if badReq[gateway] == 5 then
sendmail(...)
-- badReq[gateway] = 0
end
Привет. Что то пошло не так...
local name = event:getHeader("Event-Name") or ''
local subb = event:getHeader("Event-Subclass") or ''
--freeswitch.consoleLog("INFO", "Получен Event! " .. name)
— Вылавливаем нужный EVENT
if name == "CUSTOM" and subb == "sofia::gateway_state" then
local badReq = badReq or {}
local gateway = event:getHeader("Gateway")
local status = event:getHeader("Ping-Status")
-- заполняем нулём, если у нас ещё нет инфы по этому гейтвею
badReq[gateway] = badReq[gateway] or 0
if status == "UP" then
freeswitch.consoleLog("INFO", "Исходный:".. badReq[gateway] .."\n")
badReq[gateway] = badReq[gateway] + 1
freeswitch.consoleLog("INFO", "Прибавили:".. badReq[gateway] .."\n")
else
badReq[gateway] = 0
freeswitch.consoleLog("INFO", "Статус: DOWN\n")
end
if badReq[gateway] == 2 then
freeswitch.consoleLog("INFO", "Bingo..." ..gateway.. "\n")
-- sendmail(...)
-- badReq[gateway] = 0
end
В итоге получаем
2019-05-30 09:24:35.671710 [INFO] switch_cpp.cpp:1365 Исходный:0
2019-05-30 09:24:35.671710 [INFO] switch_cpp.cpp:1365 Прибавили1
2019-05-30 09:24:36.331678 [INFO] switch_cpp.cpp:1365 Исходный:0
2019-05-30 09:24:36.331678 [INFO] switch_cpp.cpp:1365 Прибавили1
2019-05-30 09:24:43.731713 [INFO] switch_cpp.cpp:1365 Исходный:0
2019-05-30 09:24:43.731713 [INFO] switch_cpp.cpp:1365 Прибавили1
2019-05-30 09:24:44.391710 [INFO] switch_cpp.cpp:1365 Исходный:0
Pavel
https://m.habr.com/ru/company/toshibarus/blog/444502/
Serezha
Maxim
halt
FS стоит на одноплатнике. Не хочется её захламлять
Maxim
Лог нжинкс пишешь в джсон формате тянешь его в прометеус - мониторинг готов :)
Не совсем соглашусь что сборка данных в json формате из nginx prometheus'ом - является готовым мониторингом, скорее это просто сбор и хранение данных с виеменной меткой, для того что бы это стало мониторингом необходим процесс отслеживания событий, что более ближе к мониториргу чем красивые графики на экранах в grafana
halt
Парни, а какое время жизни таблицы в Lua?
badReq = badReq or {};
Записываю в таблицу данные и при следующем запросе их уже нет
Evgeniy
Highly Likely
Highly Likely
Технически пока на них есть ссылка, а после - до итерации GC
halt
Не знаю. Вроде как нет.
Правильно ли я заполняю данными в этом случаее? Я про переменную badReq["".. gateway ..""] Т.к. значений несколько...
badReq = badReq or {};
n = badReq["".. gateway ..""] or 0;
badReq["".. gateway ..""] = badReq["".. gateway ..""] or n;
freeswitch.consoleLog("INFO", "Записано в ': ".. badReq["".. gateway ..""': ".. badReq["".. gateway ..""] .."\n");
n = n + 1;
badReq["".. gateway ..""] = n;
freeswitch.consoleLog("INFO", "После прибавления: ".. badReq["".. gateway ..""] .."\n");
else
badReq["".. gateway ..""] = 0;
freeswitch.consoleLog("INFO", "+1\n");
end;
Highly Likely
Highly Likely
Во что*
halt
Строка. Название гейта
gateway = event:getHeader("Gateway")
status = event:getHeader("Ping-Status")
Highly Likely
Highly Likely
gateway - переменная?
halt
да
Highly Likely
Почему не использовать просто badReq[gateway] или badReq[tostring(gateway)]?
halt
да я уже по всякому пробовал. А если я запилю badReq[gateway] в название строки переменная попадет? Или все же имя строки "gateway"?
halt
В общем проблема ясна. Таблица "умирает". Живет только на 1 запрос
halt
Есть ли возможность продлить ей время жизни?
Serezha
ngx.shared ?
halt
При каждом EVENTE пустые данные. Т.к. это FreeSWITCH деграет этот скрипт при наступлении события
Snusmumriken
Шарь данные через БД.
halt
Я смотрел дебаг в консоле. Данных в таблице при новом запросе нет
Snusmumriken
Вот это вот
Snusmumriken
Ну, то есть на самом деле, всё простенько, сам видишь. Но это только если все запросы обрабатывает один инстанс вм, и переменная badreq общая. На нескольких машинах или если на каждый запрос/серию запросов запускается новая вм, придётся шарить переменную через базу.
halt
Ну что же, буду курить как отправить в Redis из скрипта, и дальше эти данные считывать
halt
)
Snusmumriken
А, кстати, можешь ещё попробовать убрать local перед badReq, на всякий случай
halt
Пробовал
Snusmumriken
Ну тады глобал спейс каждый раз новый : )
Snusmumriken
Как отправить —
local badReqCount = redis:hget("badReq", gateway) or 0
if isBadReq then
badReqCount = badReqCount + 1
else
badReqCount = 0
end
redis:hset("badReq", gateway, badReqCount)
...
Snusmumriken
Highly Likely
Недавно видел учебник по редиске
Highly Likely
Интересно, что там можно понаписать на учебник по Редиске?
Snusmumriken
На самом деле, довольно много всего. Типа "как правильно шардировать, в чём прекол пайплайнов и как их применять чтобы было круто, как оптимизировать память, дёргать удалённые процедуры и писать оптимизированную фигню" и т.п.