Всем привет. Предположим, мы настроили связку 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