fix: (active triggers) add additional error message when zabbix server is unreachable, add error logging to console
All checks were successful
Build and Push Docker Images / build (push) Successful in 1m18s

Signed-off-by: UdoChudo <stream@udochudo.ru>
This commit is contained in:
Udo Chudo 2025-06-25 16:05:54 +05:00
parent a1c36de342
commit 2b65d11622
2 changed files with 50 additions and 25 deletions

View File

@ -1,3 +1,4 @@
from telebot import logger
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
from app.bot.keyboards.groups import create_groups_keyboard from app.bot.keyboards.groups import create_groups_keyboard
@ -12,10 +13,14 @@ from app.bot.utils.zabbix_alt import (
def process_region_selection(bot, chat_id, region_id): def process_region_selection(bot, chat_id, region_id):
try: try:
groups = get_region_groups(region_id) groups = get_region_groups(region_id)
if groups is None:
return bot.send_message(chat_id, "❌ Сервер Zabbix временно недоступен. Попробуйте позже.", reply_markup=get_main_menu())
if not groups: if not groups:
return bot.send_message(chat_id, "Нет групп хостов для этого региона.") return bot.send_message(chat_id, "Нет групп хостов для этого региона.", reply_markup=get_main_menu())
markup = create_groups_keyboard(groups, region_id) markup = create_groups_keyboard(groups, region_id)
bot.send_message(chat_id, "Выберите группу хостов:", reply_markup=markup) bot.send_message(chat_id, "Выберите группу хостов:", reply_markup=markup)
except Exception as e: except Exception as e:
bot.send_message(chat_id, f"Ошибка при получении групп: {str(e)}", reply_markup=get_main_menu()) bot.send_message(chat_id, f"Ошибка при получении групп: {str(e)}", reply_markup=get_main_menu())
@ -23,40 +28,61 @@ def process_region_selection(bot, chat_id, region_id):
def process_group_selection(bot, chat_id, group_id): def process_group_selection(bot, chat_id, group_id):
try: try:
triggers = fetch_triggers_data(group_id) triggers = fetch_triggers_data(group_id)
if triggers is None:
return bot.send_message(chat_id, "❌ Сервер Zabbix временно недоступен. Попробуйте позже.")
if not triggers: if not triggers:
bot.send_message(chat_id, "Нет активных событий.") return bot.send_message(chat_id, "Нет активных событий.")
return
for trigger in triggers: for trigger in triggers:
try:
text, url = format_trigger_for_tg(trigger) text, url = format_trigger_for_tg(trigger)
markup = InlineKeyboardMarkup() markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton(text="Открыть график", url=url)) markup.add(InlineKeyboardButton(text="Открыть график", url=url))
bot.send_message(chat_id, text, reply_markup=markup, parse_mode="HTML") bot.send_message(chat_id, text, reply_markup=markup, parse_mode="HTML")
except Exception as e:
logger.error(f"[Bot] Ошибка при отправке сообщения о триггере: {e}")
continue
except Exception as e: except Exception as e:
bot.send_message(chat_id, f"Ошибка при получении событий: {str(e)}") bot.send_message(chat_id, f"Ошибка при получении событий: {str(e)}")
def process_all_groups_request(bot, chat_id, region_id): def process_all_groups_request(bot, chat_id, region_id):
try: try:
all_triggers = [] all_triggers = []
groups = get_all_groups_for_region(region_id) groups = get_all_groups_for_region(region_id)
zabbix_error = False
for group in groups: for group in groups:
try: try:
triggers = fetch_triggers_data(group['groupid']) triggers = fetch_triggers_data(group['groupid'])
if triggers is None:
zabbix_error = True
continue
if triggers: if triggers:
all_triggers.extend(triggers) all_triggers.extend(triggers)
except Exception: except Exception as e:
logger.error(f"[Bot] Ошибка при обработке группы {group['name']}: {e}")
continue continue
if zabbix_error and not all_triggers:
return bot.send_message(chat_id, "❌ Сервер Zabbix временно недоступен. Попробуйте позже.")
if not all_triggers: if not all_triggers:
bot.send_message(chat_id, "Нет активных событий.") return bot.send_message(chat_id, "Нет активных событий.")
return
for trigger in all_triggers: for trigger in all_triggers:
try:
text, url = format_trigger_for_tg(trigger) text, url = format_trigger_for_tg(trigger)
markup = InlineKeyboardMarkup() markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton(text="Открыть график", url=url)) markup.add(InlineKeyboardButton(text="Открыть график", url=url))
bot.send_message(chat_id, text, reply_markup=markup, parse_mode="HTML") bot.send_message(chat_id, text, reply_markup=markup, parse_mode="HTML")
except Exception as e:
logger.error(f"[Bot] Ошибка при отправке события: {e}")
continue
except Exception as e: except Exception as e:
bot.send_message(chat_id, f"Ошибка при получении данных: {str(e)}") bot.send_message(chat_id, f"Ошибка при получении данных: {str(e)}")

View File

@ -9,7 +9,9 @@ from config import ZABBIX_URL, ZABBIX_API_TOKEN, ZABBIX_VERIFY_SSL
def get_region_groups(region_id: str): def get_region_groups(region_id: str):
""" """
Получает список групп, имя которых содержит регион region_id, исключая 'test' и группы, не соответствующие шаблону 'имя_число'. Получает список групп, имя которых содержит регион region_id,
исключая 'test' и группы, не соответствующие шаблону 'имя_число'.
Возвращает None при ошибке подключения.
""" """
try: try:
zapi = ZabbixAPI(ZABBIX_URL) zapi = ZabbixAPI(ZABBIX_URL)
@ -17,8 +19,7 @@ def get_region_groups(region_id: str):
zapi.session.verify = ZABBIX_VERIFY_SSL zapi.session.verify = ZABBIX_VERIFY_SSL
host_groups = zapi.hostgroup.get(output=["groupid", "name"], search={"name": region_id}) host_groups = zapi.hostgroup.get(output=["groupid", "name"], search={"name": region_id})
pattern = re.compile(r'.+_\d+$')
pattern = re.compile(r'.+_\d+$') # строка с нижним подчёркиванием перед числом в конце
filtered_groups = [ filtered_groups = [
group for group in host_groups group for group in host_groups
@ -28,7 +29,7 @@ def get_region_groups(region_id: str):
except Exception as e: except Exception as e:
logger.error(f"[Zabbix] Error getting region groups for '{region_id}': {e}") logger.error(f"[Zabbix] Error getting region groups for '{region_id}': {e}")
return [] return None # ← это важно
def get_all_groups_for_region(region_id: str): def get_all_groups_for_region(region_id: str):
""" """
@ -39,16 +40,15 @@ def get_all_groups_for_region(region_id: str):
def fetch_triggers_data(group_id): def fetch_triggers_data(group_id):
""" """
Возвращает список триггеров с необходимыми данными, Возвращает список триггеров или None при ошибке подключения к Zabbix.
без форматирования сообщений.
""" """
pnet_mediatypes = {"Pnet integration JS 2025", "Pnet integration JS 2024", "Pnet integration new2"} pnet_mediatypes = {"Pnet integration JS 2025", "Pnet integration JS 2024", "Pnet integration new2"}
start_time = time.time() start_time = time.time()
try: try:
zapi = ZabbixAPI(ZABBIX_URL) zapi = ZabbixAPI(ZABBIX_URL)
zapi.login(api_token=ZABBIX_API_TOKEN) zapi.login(api_token=ZABBIX_API_TOKEN)
zapi.session.verify = ZABBIX_VERIFY_SSL
# Получаем проблемы с высокой и критической важностью
problems = zapi.problem.get( problems = zapi.problem.get(
severities=[4, 5], severities=[4, 5],
suppressed=0, suppressed=0,
@ -56,7 +56,6 @@ def fetch_triggers_data(group_id):
groupids=group_id groupids=group_id
) )
trigger_ids = [problem["objectid"] for problem in problems] trigger_ids = [problem["objectid"] for problem in problems]
if not trigger_ids: if not trigger_ids:
logger.info(f"No triggers found for group {group_id}") logger.info(f"No triggers found for group {group_id}")
return [] return []
@ -90,14 +89,14 @@ def fetch_triggers_data(group_id):
break break
triggers_sorted = sorted(pnet_triggers, key=lambda t: int(t['lastEvent']['clock'])) triggers_sorted = sorted(pnet_triggers, key=lambda t: int(t['lastEvent']['clock']))
logger.debug(f"Found {len(pnet_triggers)} pnet triggers for group {group_id}")
end_time = time.time() end_time = time.time()
logger.info(f"[Zabbix] Fetched {len(triggers_sorted)} triggers for group {group_id} in {end_time - start_time:.2f} seconds.") logger.info(f"[Zabbix] Fetched {len(triggers_sorted)} triggers for group {group_id} in {end_time - start_time:.2f} seconds.")
return triggers_sorted return triggers_sorted
except ZabbixAPIException as e: except ZabbixAPIException as e:
logger.error(f"[Zabbix] Zabbix API error for group {group_id}: {e}") logger.error(f"[Zabbix] Zabbix API error for group {group_id}: {e}")
return [] return None # ← отличие
except Exception as e: except Exception as e:
logger.error(f"[Zabbix] Unexpected error fetching triggers for group {group_id}: {e}") logger.error(f"[Zabbix] Unexpected error fetching triggers for group {group_id}: {e}")
return [] return None # ← отличие