Всем привет. Предположим, мы настроили связку https://github.com/ableev/Zabbix-in-Telegram . Получаем в telegram события с графиками по событиям триггеров, классно. Можно чуть развить идею и самим заставить ботa telegram отправлять нам графики из заббикса.
Схема пусть будет следующая:
Распишем, что у нас уже изначально есть и настроено:
- настроенный zabbix сервер, бд находится на этом же сервере
- настроенный пользователь веб-интерфейса zabbix сервера, которому хватает прав на чтение
- созданный пользователь БД, который имеет права только на чтение из mysql
- созданный бот
Схема работы скрипта следующая:
Мы добавили созданного бота к себе в телеграм. Отправляем ему управляющие команды с целью найти нужный график, делаем по полученным данным запросы в БД zabbix для получения graphid. Формируем url графика на основе graphid. Далее авторизуемся в веб-интерфейсе zabbix и "забираем" нужный график, потом его отправляем пользователю телеграма.
Сам скрипт:
#!/usr/bin/env python # coding: utf-8 import sys import os import time import random import requests import json import re import stat import MySQLdb import telebot bot = telebot.TeleBot("API_KEY_of_theBOT") zbx_server = "https://zabbix.test.ru" zbx_api_user = "zabbix_read" zbx_api_pass = "1234" available_commands = { '/z ARG1 ARG2: ': " отправить команду заббиксу"} available_arguments = { 'ARG1: ': "Имя сервера телефонии, которое указано в Zabbix)", 'ARG2: ': "Какую информацию получить с хоста"} avalaible_data = ['calls', 'cpu', 'memory'] allowed_uid = ['12345678', '23541335', '987654321'] #Функция для получения url нужного графика def get_zabbix_url(host,needed_data): global zbx_img_url db = MySQLdb.connect(host="localhost", user="read", passwd="read", db="zabbix", charset='utf8') cursor = db.cursor() # формируем курсор, с помощью которого можно исполнять SQL-запросыa sql = "select hostid,host from hosts where host = '" + str(host) + "'"; cursor.execute(sql) data = cursor.fetchall() if len(data) == 0: print "Host " + str(host) + " not found in Zabbix database, exit..." zbx_img_url = "" return zbx_img_url hostid= data[0][0] if needed_data == "calls": sql="select itemid,hostid,name from items where hostid=" + str(hostid) + " and name ='Calls count'"; cursor.execute(sql) data = cursor.fetchall() elif needed_data == "cpu": sql="select itemid,hostid,name from items where hostid=" + str(hostid) + " and name ='Processor load (15 min average per core)'"; cursor.execute(sql) data = cursor.fetchall() elif needed_data == "memory": sql="select itemid,hostid,name from items where hostid=" + str(hostid) + " and name ='Available memory'"; cursor.execute(sql) data = cursor.fetchall() else: print "Host " + str(host) + " found in Zabbix database, but itemid not found, may be ARG2 is wrong? " zbx_img_url = "" return zbx_img_url itemid=data[0][0] sql="select * from graphs_items where itemid=" + str(itemid); cursor.execute(sql) data = cursor.fetchall() graphid = data[0][1] zbx_img_url = "https://zabbix.test.ru/chart2.php?fullscreen=0&graphid=" + str(graphid) + "&width=1138&period=43300" return zbx_img_url @bot.message_handler(commands=['help', 'start']) def send_welcome(message): message_zabbix = "" msg = bot.send_message(message.chat.id, 'Привет! Я бот telephone company! Список доступных команд: ') for i in available_commands: message_zabbix = message_zabbix + i + "\t" + available_commands[i] + "\n\n" for i in available_arguments: message_zabbix = message_zabbix + i + "\t" + available_arguments[i] + "\n\n" message_zabbix = message_zabbix + "Список возможных значений аргумента ARG2: " + str(avalaible_data) + "\n\n" bot.send_message(message.chat.id, message_zabbix ) #message.from_user.id - user id #Получаем какой-то текст от пользователя @bot.message_handler(content_types=["text"]) def get_info(message): uid = message.from_user.id if str(uid) in allowed_uid: text = message.text l = message.text.split() if len(l) != 3: bot.send_message(message.chat.id, "Wrong length of arguments" ) exit(1) host = l[1] needed_data = l[2] data_api = {"name": zbx_api_user, "password": zbx_api_pass, "enter": "Sign in"} req_cookie = requests.post(zbx_server + "/", data=data_api) cookie = req_cookie.cookies #делаем запрос для получения графика file_img = "asterisk.png" get_zabbix_url(host,needed_data) if len(zbx_img_url) != 0: #если хост найден в БД заббикса res = requests.get(zbx_img_url,cookies=cookie) res_code = res.status_code else: # в бд не нашли, шлем сообщение bot.send_message(message.chat.id, "Host " + host + " not found in Zabbix database or maybe ARG2 is wrong?" ) exit(1) res_img = res.content with open(file_img, 'wb') as fp: fp.write(res_img) photo = open('asterisk.png', 'rb') #for sending photo to telegram msg = bot.send_photo(message.chat.id, photo, reply_to_message_id=message.message_id) else: bot.send_message(message.chat.id, "You don't allow access to this chat") bot.polling()
Скрипт "наколеночный". В даннном варианте он принимает при отправке команд боту имя хоста и параметры calls, memory, cpu. Имя хоста - это то, как хост называется в базе заббикса (select hostid,host from hosts), параметр calls - соответствует элементу данных заббикса "Calls count" (select itemid,hostid,name from items where hostid=" + str(hostid) + " and name ='Calls count'"). Приведу несколько картинок, чтобы было немного яснее:
Это элемент данных, на основе которого мы будем запрашивать графики.
Приветственное сообщение.
Запросили данные, но нет прав (не прописан uid пользователя телеграма в списке allowed_uid скрипта). Свой uid можно узнать, отправив сообщение боту @MyTelegramID_bot.
Прописали uid в список, перезапустили скрипт, получили в телеграм график.
Для скрипта можно написать systemd service:
cat /etc/systemd/system/telegram_telebot.service [Unit] Description=Run script for receiving and sending messages from/to telegram from zabbix Requires=network.target After=network.target [Service] #Type=oneshot #RemainAfterExit=True ExecStart=/root/scripts/telegram/telegram_telebot.py Restart=always RestartSec=10m [Install] WantedBy=multi-user.targe
Сервера nginx телеграма иногда выдают 500-е ошибки и чтобы наш скрипт не падал из-за них, указываем параметры Restart и RestartSec (назначил интервал 10 мин в виду того, что когда отдаются 500 ошибки, скрипт падает -> systemd сразу его пытается перезапускать, снова падает и т.д, в нашем варианте достаточно не сразу перезапускать, а выждав некоторое время, пока с бОльшей вероятностью все не починится)
systemctl enable telegram_telebot.service systemctl start telegram_telebot.service