Telezab/zabbix_manager.py
2025-02-09 09:58:02 +05:00

117 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
import asyncio
from pyzabbix import ZabbixAPI
from datetime import datetime
from pytz import timezone
import os
class ZabbixTriggerManager:
def __init__(self):
self.zabbix_url = os.getenv('ZABBIX_URL') # URL Zabbix из переменных окружения
self.api_token = os.getenv('ZABBIX_API_TOKEN') # API токен Zabbix из переменных окружения
self.moskva_tz = timezone('Europe/Moscow') # Часовой пояс
self.priority_map = {'4': 'HIGH', '5': 'DISASTER'} # Отображение приоритетов
self.zapi = None # Клиент Zabbix API
def login(self) -> None:
"""
Авторизация в Zabbix API.
"""
try:
self.zapi = ZabbixAPI(self.zabbix_url)
self.zapi.login(api_token=self.api_token)
logging.info("Successfully logged in to Zabbix API.")
except Exception as e:
logging.error(f"Error logging in to Zabbix API: {e}")
raise
def get_problems_for_group(self, group_id: str) -> list:
"""
Получает проблемы для указанной группы хостов.
"""
try:
logging.info(f"Fetching problems for group {group_id}")
problems = self.zapi.problem.get(
output=["eventid", "name", "severity", "clock"],
groupids=group_id,
recent=1, # Только текущие проблемы
# sortfield=["clock"],
# sortorder="DESC"
)
logging.info(f"Found {len(problems)} problems for group {group_id}")
return problems
except Exception as e:
logging.error(f"Error fetching problems for group {group_id}: {e}")
return []
def get_problems_for_region(self, region_id: str) -> list:
"""
Получает проблемы для всех групп, связанных с регионом.
"""
try:
logging.info(f"Fetching host groups for region {region_id}")
host_groups = self.zapi.hostgroup.get(output=["groupid", "name"], search={"name": region_id})
filtered_groups = [
group for group in host_groups
if 'test' not in group['name'].lower() and f'_{region_id}' in group['name']
]
all_problems = []
for group in filtered_groups:
problems = self.get_problems_for_group(group['groupid'])
all_problems.extend(problems)
return all_problems
except Exception as e:
logging.error(f"Error fetching problems for region {region_id}: {e}")
return []
async def send_problems_to_user(self, chat_id: int, problems: list, bot) -> None:
"""
Отправляет список проблем пользователю в Telegram с учётом задержки для обхода лимита API.
"""
if not problems:
logging.info(f"No problems to send to chat_id {chat_id}.")
bot.send_message(chat_id, "Нет активных проблем.")
return
for problem in problems:
try:
# Форматируем время
event_time = datetime.fromtimestamp(int(problem['clock']), tz=self.moskva_tz)
event_time_formatted = event_time.strftime('%Y-%m-%d %H:%M:%S Мск')
# Определяем критичность
severity = self.priority_map.get(problem['severity'], "Неизвестно")
priority_mark = '⚠️' if severity == 'HIGH' else '⛔️' if severity == 'DISASTER' else ''
# Определяем имя хоста
hosts = self._get_problem_hosts(problem)
host = hosts[0]["name"] if hosts else "Неизвестно"
# Генерируем URL для графика
item_ids = [item["itemid"] for item in problem.get("items", [])]
url = f"{self.zabbix_url}/history.php?action=batchgraph&" + \
"&".join([f"itemids[{item_id}]={item_id}" for item_id in item_ids]) + "&graphtype=0"
# Формируем сообщение
description = self.escape_telegram_chars(problem['name'])
message = (
f"{priority_mark} <b>Host</b>: {host}\n"
f"<b>Описание</b>: {description}\n"
f"<b>Критичность</b>: {severity}\n"
f"<b>Время создания</b>: {event_time_formatted}\n"
f'<b>URL</b>: <a href="{url}">Ссылка на график</a>'
)
# Отправляем сообщение
bot.send_message(chat_id, message, parse_mode="HTML")
# Задержка для соблюдения рейтлимита
await asyncio.sleep(0.04) # 40 мс = максимум 25 сообщений в секунду
except Exception as e:
logging.error(f"Error sending problem to chat_id {chat_id}: {e}")