From 8211f301edea08b5b2f77b30ee3bff8bae372990 Mon Sep 17 00:00:00 2001 From: Marco Caberletti Date: Tue, 8 Mar 2016 16:15:30 +0100 Subject: [PATCH 1/3] Add .gitignore file. Add log_file and log_level parameters in settings. Edit script to use log file. --- .gitignore | 5 +++++ zbxtg.py | 30 ++++++++++++++++++++++-------- zbxtg_settings.example.py | 3 +++ 3 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ceddb02 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.project +.pydevproject +.settings/ +*.pyc +zbxtg_settings.py diff --git a/zbxtg.py b/zbxtg.py index 278cc2d..db1df16 100755 --- a/zbxtg.py +++ b/zbxtg.py @@ -1,14 +1,17 @@ #!/usr/bin/env python # coding: utf-8 -import sys +import json +import logging import os -import time +from os.path import dirname import random -import requests -import json import re -from os.path import dirname +import sys +import time + +import requests + import zbxtg_settings @@ -62,9 +65,11 @@ def send_message(self, to, message): print_message("Trying to /sendMessage:") print_message(url) print_message("post params: " + str(params)) + logging.info("Sending message %s", params) res = requests.post(url, params=params, proxies=self.proxies) answer = res._content answer_json = json.loads(answer) + logging.info("Receive message %s", answer_json) if not answer_json["ok"]: print_message(answer_json) sys.exit(1) @@ -76,9 +81,11 @@ def send_photo(self, to, message, path): message = "\n".join(message) params = {"chat_id": to, "caption": message} files = {"photo": open(path, 'rb')} + logging.info("Sendig message %s", params) res = requests.post(url, params=params, files=files, proxies=self.proxies) answer = res._content answer_json = json.loads(answer) + logging.info("Receive message %s", answer_json) if not answer_json["ok"]: print_message(answer_json) sys.exit(1) @@ -168,7 +175,7 @@ def api_test(self): def print_message(string): string = str(string) + "\n" filename = sys.argv[0].split("/")[-1] - sys.stderr.write(filename + ": " + string) + logging.debug(filename + ": " + string) def list_cut(elements, symbols_limit): @@ -208,9 +215,12 @@ def main(): rnd = random.randint(0, 999) ts = time.time() - hash_ts = str(ts) + "." + str(rnd) + hash_ts = str(ts) + "." + str(rnd) - log_file = "/dev/null" + log_file = zbxtg_settings.log_file + logging.basicConfig(filename=log_file, + level=logging.getLevelName(zbxtg_settings.log_level), + format='%(asctime)-15s %(name)-5s %(levelname)-8s %(message)s') zbx_to = sys.argv[1] zbx_subject = sys.argv[2] @@ -219,6 +229,8 @@ def main(): tg_contact_type_old = "user" tg = TelegramAPI(key=zbxtg_settings.tg_key) + + logging.debug("Start notify process") if zbxtg_settings.proxy_to_tg: tg.proxies = {"http": "http://{0}/".format(zbxtg_settings.proxy_to_tg)} @@ -373,6 +385,8 @@ def main(): zbxtg_body_text.append(zbxtg_settings.zbx_server) except: pass + + logging.debug("Send message") if not tg_method_image: tg.send_message(uid, zbxtg_body_text) diff --git a/zbxtg_settings.example.py b/zbxtg_settings.example.py index 4a0cc21..5c8f932 100644 --- a/zbxtg_settings.example.py +++ b/zbxtg_settings.example.py @@ -12,5 +12,8 @@ proxy_to_zbx = None proxy_to_tg = None +log_file = "/var/log/zabbixsrv/zbx_telegram.log" +log_level = "DEBUG" + #proxy_to_zbx = "proxy.local:3128" #proxy_to_tg = "proxy.local:3128" From 5f7ce7647e5e7344cf5d4955a1729803ca993791 Mon Sep 17 00:00:00 2001 From: Marco Caberletti Date: Wed, 9 Mar 2016 09:16:54 +0100 Subject: [PATCH 2/3] Add console handler. Modify --debug option behavior. Replace print_message with logger. --- zbxtg.py | 109 ++++++++++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 61 deletions(-) diff --git a/zbxtg.py b/zbxtg.py index db1df16..03abfe7 100755 --- a/zbxtg.py +++ b/zbxtg.py @@ -14,6 +14,7 @@ import zbxtg_settings +log = logging.getLogger('default_logger') class TelegramAPI(): tg_url_bot_general = "https://api.telegram.org/bot" @@ -25,7 +26,6 @@ def http_get(self, url): return answer_json def __init__(self, key): - self.debug = False self.key = key self.proxies = {} self.type = "private" # 'private' for private chats or 'group' for group chats @@ -40,14 +40,12 @@ def get_me(self): def get_updates(self): url = self.tg_url_bot_general + self.key + "/getUpdates" - if self.debug: - print_message(url) + log.debug(url) updates = self.http_get(url) - if self.debug: - print_message("Content of /getUpdates:") - print_message(updates) + log.debug("Content of /getUpdates:") + log.debug(updates) if not updates["ok"]: - print_message(updates) + log.error(updates) sys.exit(1) else: return updates @@ -61,17 +59,16 @@ def send_message(self, to, message): if self.markdown: parse_mode = "Markdown" params["parse_mode"] = parse_mode - if self.debug: - print_message("Trying to /sendMessage:") - print_message(url) - print_message("post params: " + str(params)) - logging.info("Sending message %s", params) + log.debug("Trying to /sendMessage:") + log.debug(url) + log.debug("post params: " + str(params)) + log.info("Sending message %s", params) res = requests.post(url, params=params, proxies=self.proxies) answer = res._content answer_json = json.loads(answer) - logging.info("Receive message %s", answer_json) + log.info("Receive message %s", answer_json) if not answer_json["ok"]: - print_message(answer_json) + log.error(answer_json) sys.exit(1) else: return answer_json @@ -81,21 +78,20 @@ def send_photo(self, to, message, path): message = "\n".join(message) params = {"chat_id": to, "caption": message} files = {"photo": open(path, 'rb')} - logging.info("Sendig message %s", params) + log.info("Sendig message %s", params) res = requests.post(url, params=params, files=files, proxies=self.proxies) answer = res._content answer_json = json.loads(answer) - logging.info("Receive message %s", answer_json) + log.info("Receive message %s", answer_json) if not answer_json["ok"]: - print_message(answer_json) + log.error(answer_json) sys.exit(1) else: return answer_json def get_uid(self, name): uid = 0 - if self.debug: - print_message("Getting uid from /getUpdates...") + log.debug("Getting uid from /getUpdates...") updates = self.get_updates() for m in updates["result"]: chat = m["message"]["chat"] @@ -111,14 +107,13 @@ def get_uid(self, name): def error_need_to_contact(self, to): if self.type == "private": - print_message("User '{0}' needs to send some text bot in private".format(to)) + log.info("User '{0}' needs to send some text bot in private".format(to)) if self.type == "group": - print_message("You need to mention your bot in '{0}' group chat (i.e. type @YourBot)".format(to)) + log.info("You need to mention your bot in '{0}' group chat (i.e. type @YourBot)".format(to)) class ZabbixAPI(): def __init__(self, server, username, password): - self.debug = False self.server = server self.username = username self.password = password @@ -135,10 +130,10 @@ def login(self): req_cookie = requests.post(self.server + "/", data=data_api, proxies=self.proxies, verify=self.verify) cookie = req_cookie.cookies if len(req_cookie.history) > 1 and req_cookie.history[0].status_code == 302: - print_message("probably the server in your config file has not full URL (for example " + log.info("probably the server in your config file has not full URL (for example " "'{0}' instead of '{1}')".format(self.server, self.server + "/zabbix")) if not cookie: - print_message("authorization has failed, url: {0}".format(self.server + "/")) + log.info("authorization has failed, url: {0}".format(self.server + "/")) cookie = None self.cookie = cookie @@ -151,12 +146,11 @@ def graph_get(self, itemid, period, title, width, height, tmp_dir): "&items[0][itemid]={0}&items[0][sortorder]=0" \ "&items[0][drawtype]=5&items[0][color]=00CC00".format(itemid, period, title, width, height) - if self.debug: - print_message(zbx_img_url) + log.debug(zbx_img_url) res = requests.get(zbx_img_url, cookies=self.cookie, proxies=self.proxies, verify=self.verify) res_code = res.status_code if res_code == 404: - print_message("can't get image from '{0}'".format(zbx_img_url)) + log.error("can't get image from '{0}'".format(zbx_img_url)) sys.exit(1) res_img = res._content with open(file_img, 'wb') as fp: @@ -171,13 +165,6 @@ def api_test(self): api = requests.post(api_url, data=api_data, proxies=self.proxies, headers=headers) return api._content - -def print_message(string): - string = str(string) + "\n" - filename = sys.argv[0].split("/")[-1] - logging.debug(filename + ": " + string) - - def list_cut(elements, symbols_limit): symbols_count = symbols_count_now = 0 elements_new = [] @@ -215,13 +202,8 @@ def main(): rnd = random.randint(0, 999) ts = time.time() - hash_ts = str(ts) + "." + str(rnd) - - log_file = zbxtg_settings.log_file - logging.basicConfig(filename=log_file, - level=logging.getLevelName(zbxtg_settings.log_level), - format='%(asctime)-15s %(name)-5s %(levelname)-8s %(message)s') - + hash_ts = str(ts) + "." + str(rnd) + zbx_to = sys.argv[1] zbx_subject = sys.argv[2] zbx_body = sys.argv[3] @@ -230,7 +212,17 @@ def main(): tg = TelegramAPI(key=zbxtg_settings.tg_key) - logging.debug("Start notify process") + log_level = logging.getLevelName(zbxtg_settings.log_level) + log_file = zbxtg_settings.log_file + format = logging.Formatter('%(asctime)-15s [%(name)-5s] [%(levelname)-8s] %(message)s') + + fh = logging.FileHandler(log_file) + fh.setFormatter(format) + + log.setLevel(log_level) + log.addHandler(fh) + + log.debug("Start notify process") if zbxtg_settings.proxy_to_tg: tg.proxies = {"http": "http://{0}/".format(zbxtg_settings.proxy_to_tg)} @@ -302,12 +294,12 @@ def main(): if "--debug" in sys.argv or is_debug: is_debug = True - tg.debug = True - zbx.debug = True - print_message(tg.get_me()) - print_message("Cache file with uids: " + tmp_uids) - log_file = tmp_dir + ".debug." + hash_ts + ".log" - #print_message(log_file) + ch = logging.StreamHandler(sys.stdout) + ch.setFormatter(format) + log.addHandler(ch) + log.debug(tg.get_me()) + log.debug("Cache file with uids: " + tmp_uids) + log.setLevel(logging.DEBUG) if "--markdown" in sys.argv: tg.markdown = True @@ -319,13 +311,11 @@ def main(): tg.type = "channel" if "--disable_web_page_preview" in sys.argv or disable_web_page_preview: - if is_debug: - print_message("'disable_web_page_preview' option has been enabled") + log.debug("'disable_web_page_preview' option has been enabled") tg.disable_web_page_preview = True if not os.path.isdir(tmp_dir): - if is_debug: - print_message("Tmp dir doesn't exist, creating new one...") + log.debug("Tmp dir doesn't exist, creating new one...") try: os.makedirs(tmp_dir) os.chmod(tmp_dir, 0777) @@ -333,8 +323,7 @@ def main(): os.chmod(tmp_uids, 0777) except: tmp_dir = "/tmp" - if is_debug: - print_message("Using {0} as a temporary dir".format(tmp_dir)) + log.debug("Using {0} as a temporary dir".format(tmp_dir)) uid = None @@ -370,13 +359,11 @@ def main(): if tmp_need_update: cache_string = "{0};{1};{2}\n".format(zbx_to, tg.type, str(uid).rstrip()) - if is_debug: - print_message("Add new string to cache file: {0}".format(cache_string)) + log.debug("Add new string to cache file: {0}".format(cache_string)) with open(tmp_uids, "a") as cache_file_uids: cache_file_uids.write(cache_string) - if is_debug: - print_message("Telegram uid of {0} '{1}': {2}".format(tg.type, zbx_to, uid)) + log.debug("Telegram uid of {0} '{1}': {2}".format(tg.type, zbx_to, uid)) # add signature, turned off by default, you can turn it on in config try: @@ -386,21 +373,21 @@ def main(): except: pass - logging.debug("Send message") + log.debug("Send message") if not tg_method_image: tg.send_message(uid, zbxtg_body_text) else: zbx.login() if not zbx.cookie: - print_message("Login to Zabbix web UI has failed, check manually...") + log.info("Login to Zabbix web UI has failed, check manually...") else: zbxtg_file_img = zbx.graph_get(settings["zbxtg_itemid"], settings["zbxtg_image_period"], settings["zbxtg_title"], settings["zbxtg_image_width"], settings["zbxtg_image_height"], tmp_dir) zbxtg_body_text, is_modified = list_cut(zbxtg_body_text, 200) if is_modified: - print_message("probably you will see MEDIA_CAPTION_TOO_LONG error, " + log.info("probably you will see MEDIA_CAPTION_TOO_LONG error, " "the message has been cut to 200 symbols, " "https://github.com/ableev/Zabbix-in-Telegram/issues/9" "#issuecomment-166895044") From 5f0afcabf52822ce57b3c36ddc9d5554096e59b1 Mon Sep 17 00:00:00 2001 From: Marco Caberletti Date: Wed, 16 Mar 2016 13:32:30 +0100 Subject: [PATCH 3/3] Apply formatter. --- zbxtg.py | 78 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/zbxtg.py b/zbxtg.py index 03abfe7..c40f19c 100755 --- a/zbxtg.py +++ b/zbxtg.py @@ -16,6 +16,7 @@ log = logging.getLogger('default_logger') + class TelegramAPI(): tg_url_bot_general = "https://api.telegram.org/bot" @@ -28,7 +29,8 @@ def http_get(self, url): def __init__(self, key): self.key = key self.proxies = {} - self.type = "private" # 'private' for private chats or 'group' for group chats + # 'private' for private chats or 'group' for group chats + self.type = "private" self.markdown = False self.html = False self.disable_web_page_preview = False @@ -42,8 +44,7 @@ def get_updates(self): url = self.tg_url_bot_general + self.key + "/getUpdates" log.debug(url) updates = self.http_get(url) - log.debug("Content of /getUpdates:") - log.debug(updates) + log.debug("Content of /getUpdates: %s", updates) if not updates["ok"]: log.error(updates) sys.exit(1) @@ -53,7 +54,8 @@ def get_updates(self): def send_message(self, to, message): url = self.tg_url_bot_general + self.key + "/sendMessage" message = "\n".join(message) - params = {"chat_id": to, "text": message, "disable_web_page_preview": self.disable_web_page_preview} + params = {"chat_id": to, "text": message, + "disable_web_page_preview": self.disable_web_page_preview} if self.markdown or self.html: parse_mode = "HTML" if self.markdown: @@ -79,7 +81,8 @@ def send_photo(self, to, message, path): params = {"chat_id": to, "caption": message} files = {"photo": open(path, 'rb')} log.info("Sendig message %s", params) - res = requests.post(url, params=params, files=files, proxies=self.proxies) + res = requests.post( + url, params=params, files=files, proxies=self.proxies) answer = res._content answer_json = json.loads(answer) log.info("Receive message %s", answer_json) @@ -107,12 +110,15 @@ def get_uid(self, name): def error_need_to_contact(self, to): if self.type == "private": - log.info("User '{0}' needs to send some text bot in private".format(to)) + log.info( + "User '{0}' needs to send some text bot in private".format(to)) if self.type == "group": - log.info("You need to mention your bot in '{0}' group chat (i.e. type @YourBot)".format(to)) + log.info( + "You need to mention your bot in '{0}' group chat (i.e. type @YourBot)".format(to)) class ZabbixAPI(): + def __init__(self, server, username, password): self.server = server self.username = username @@ -126,14 +132,17 @@ def login(self): if not self.verify: requests.packages.urllib3.disable_warnings() - data_api = {"name": self.username, "password": self.password, "enter": "Sign in"} - req_cookie = requests.post(self.server + "/", data=data_api, proxies=self.proxies, verify=self.verify) + data_api = { + "name": self.username, "password": self.password, "enter": "Sign in"} + req_cookie = requests.post( + self.server + "/", data=data_api, proxies=self.proxies, verify=self.verify) cookie = req_cookie.cookies if len(req_cookie.history) > 1 and req_cookie.history[0].status_code == 302: log.info("probably the server in your config file has not full URL (for example " - "'{0}' instead of '{1}')".format(self.server, self.server + "/zabbix")) + "'{0}' instead of '{1}')".format(self.server, self.server + "/zabbix")) if not cookie: - log.info("authorization has failed, url: {0}".format(self.server + "/")) + log.info( + "authorization has failed, url: {0}".format(self.server + "/")) cookie = None self.cookie = cookie @@ -147,7 +156,8 @@ def graph_get(self, itemid, period, title, width, height, tmp_dir): "&items[0][drawtype]=5&items[0][color]=00CC00".format(itemid, period, title, width, height) log.debug(zbx_img_url) - res = requests.get(zbx_img_url, cookies=self.cookie, proxies=self.proxies, verify=self.verify) + res = requests.get( + zbx_img_url, cookies=self.cookie, proxies=self.proxies, verify=self.verify) res_code = res.status_code if res_code == 404: log.error("can't get image from '{0}'".format(zbx_img_url)) @@ -160,11 +170,13 @@ def graph_get(self, itemid, period, title, width, height, tmp_dir): def api_test(self): headers = {'Content-type': 'application/json'} api_data = json.dumps({"jsonrpc": "2.0", "method": "user.login", "params": - {"user": self.username, "password": self.password}, "id": 1}) + {"user": self.username, "password": self.password}, "id": 1}) api_url = self.server + "/api_jsonrpc.php" - api = requests.post(api_url, data=api_data, proxies=self.proxies, headers=headers) + api = requests.post( + api_url, data=api_data, proxies=self.proxies, headers=headers) return api._content + def list_cut(elements, symbols_limit): symbols_count = symbols_count_now = 0 elements_new = [] @@ -203,7 +215,7 @@ def main(): rnd = random.randint(0, 999) ts = time.time() hash_ts = str(ts) + "." + str(rnd) - + zbx_to = sys.argv[1] zbx_subject = sys.argv[2] zbx_body = sys.argv[3] @@ -211,17 +223,18 @@ def main(): tg_contact_type_old = "user" tg = TelegramAPI(key=zbxtg_settings.tg_key) - + log_level = logging.getLevelName(zbxtg_settings.log_level) log_file = zbxtg_settings.log_file - format = logging.Formatter('%(asctime)-15s [%(name)-5s] [%(levelname)-8s] %(message)s') - + format = logging.Formatter( + '%(asctime)-15s [%(name)-5s] [%(levelname)-8s] %(message)s') + fh = logging.FileHandler(log_file) fh.setFormatter(format) - + log.setLevel(log_level) log.addHandler(fh) - + log.debug("Start notify process") if zbxtg_settings.proxy_to_tg: @@ -231,7 +244,8 @@ def main(): password=zbxtg_settings.zbx_api_pass) if zbxtg_settings.proxy_to_zbx: - zbx.proxies = {"http": "http://{0}/".format(zbxtg_settings.proxy_to_zbx)} + zbx.proxies = { + "http": "http://{0}/".format(zbxtg_settings.proxy_to_zbx)} try: zbx_api_verify = zbxtg_settings.zbx_api_verify @@ -248,7 +262,8 @@ def main(): "zbxtg_image_period": "3600", "zbxtg_image_width": "900", "zbxtg_image_height": "200", - "tg_method_image": False, # if True - default send images, False - send text + # if True - default send images, False - send text + "tg_method_image": False, "tg_chat": False, # send message to chat or in private "is_debug": False, "is_channel": False, @@ -286,7 +301,8 @@ def main(): is_channel = bool(settings["is_channel"]) disable_web_page_preview = bool(settings["disable_web_page_preview"]) - # experimental way to send message to the group https://github.com/ableev/Zabbix-in-Telegram/issues/15 + # experimental way to send message to the group + # https://github.com/ableev/Zabbix-in-Telegram/issues/15 if sys.argv[0].split("/")[-1] == "zbxtg_group.py" or "--group" in sys.argv or tg_chat: tg_chat = True tg.type = "group" @@ -358,7 +374,8 @@ def main(): sys.exit(1) if tmp_need_update: - cache_string = "{0};{1};{2}\n".format(zbx_to, tg.type, str(uid).rstrip()) + cache_string = "{0};{1};{2}\n".format( + zbx_to, tg.type, str(uid).rstrip()) log.debug("Add new string to cache file: {0}".format(cache_string)) with open(tmp_uids, "a") as cache_file_uids: cache_file_uids.write(cache_string) @@ -372,7 +389,7 @@ def main(): zbxtg_body_text.append(zbxtg_settings.zbx_server) except: pass - + log.debug("Send message") if not tg_method_image: @@ -383,17 +400,18 @@ def main(): log.info("Login to Zabbix web UI has failed, check manually...") else: zbxtg_file_img = zbx.graph_get(settings["zbxtg_itemid"], settings["zbxtg_image_period"], settings["zbxtg_title"], - settings["zbxtg_image_width"], settings["zbxtg_image_height"], + settings["zbxtg_image_width"], settings[ + "zbxtg_image_height"], tmp_dir) zbxtg_body_text, is_modified = list_cut(zbxtg_body_text, 200) if is_modified: log.info("probably you will see MEDIA_CAPTION_TOO_LONG error, " - "the message has been cut to 200 symbols, " - "https://github.com/ableev/Zabbix-in-Telegram/issues/9" - "#issuecomment-166895044") + "the message has been cut to 200 symbols, " + "https://github.com/ableev/Zabbix-in-Telegram/issues/9" + "#issuecomment-166895044") if tg.send_photo(uid, zbxtg_body_text, zbxtg_file_img): os.remove(zbxtg_file_img) if __name__ == "__main__": - main() \ No newline at end of file + main()