import datetime import time import requests from pyzabbix import ZabbixAPI class Zabbix(ZabbixAPI): def __init__(self, url=Zabbix_URL, user=Zabbix_USER, pwd=Zabbix_PWD): super(Zabbix, self).__init__(url=url, user=user, password=pwd) self.hosts = None def get_problem_info(self): now = int(time.time()) last = int((datetime.datetime.now() - datetime.timedelta(days=60)).timestamp()) options = {'output': ['eventid', 'objectid', 'clock', 'ns', 'name', 'severity'], 'suppressed': False, 'source': 0, 'object': 0, 'sortfield': ['eventid'], 'sortorder': 'DESC', 'value': 1, 'acknowledged': False, 'time_from': last, 'time_till': now} problems = self.problem.get(**options) data = {'problems':[],'triggers': []} triggerids = [] if len(problems) > 0: for problem in problems: if problem['objectid'] not in triggerids: triggerids.append(problem['objectid']) if len(triggerids) > 0: trigger_options = {'output': ['priority'], 'selectHosts': ['hostid'], 'triggerids': triggerids, 'monitored': True, 'skipDependent': True} data['triggers'].extend(self.trigger.get(**trigger_options)) triggers = [int(trigger['triggerid']) for trigger in data['triggers']] for problem in problems: if int(problem['objectid']) in triggers: data['problems'].append(problem) tpl = "##### {0:70} {1:10} " tplmsg = "- {0:70} {1:10} " msg = tpl.format("问题", "持续时间") if len(data['problems']) > 0: for problem in data['problems']: diff_time = now - int(problem['clock']) clock_date = "%dd %dh %dm %ds" % (diff_time//86400, (diff_time%86400)//3600, (diff_time%3600)//60,diff_time%60) msg = msg + tplmsg.format(problem['name'], clock_date) print(msg) return msg
看了源码才发现需要调用两个接口才能得到zabbix dashboard信息,也是坑,分页查询逻辑也和一般逻辑不太一样,晕。。。
Zabbix/frontends/php/app/controllers/CControllerWidgetProblemsView.php protected function doAction() { $fields = $this->getForm()->getFieldsData(); $config = select_config(); $data = CScreenProblem::getData([ //这个方法查询数据 'show' => $fields['show'], 'groupids' => getSubGroups($fields['groupids']), 'exclude_groupids' => getSubGroups($fields['exclude_groupids']), 'hostids' => $fields['hostids'], 'name' => $fields['problem'], 'severities' => $fields['severities'], 'evaltype' => $fields['evaltype'], 'tags' => $fields['tags'], 'show_suppressed' => $fields['show_suppressed'], 'unacknowledged' => $fields['unacknowledged'], 'show_latest_values' => $fields['show_latest_values'] ], $config); list($sortfield, $sortorder) = self::getSorting($fields['sort_triggers']); $data = CScreenProblem::sortData($data, $config, $sortfield, $sortorder); if (count($data['problems']) > $fields['show_lines']) { $info = _n('%1$d of %3$d%2$s problem is shown', '%1$d of %3$d%2$s problems are shown', min($fields['show_lines'], count($data['problems'])), (count($data['problems']) > $config['search_limit']) ? '+' : '', min($config['search_limit'], count($data['problems'])) ); } Zabbix/frontends/php/include/classes/screens/CScreenProblem.php $data = [ 'problems' => [], 'triggers' => [] ]; $seen_triggerids = []; $eventid_till = null; do { $options = [ 'groupids' => $filter_groupids, //null 'hostids' => $filter_hostids, //null 'applicationids' => $filter_applicationids, //null 'objectids' => $filter_triggerids, //null 'eventid_till' => $eventid_till, //null 'suppressed' => false, 'limit' => $config['search_limit'] + 1 // search_limit = 1 ]; ... $problems = ($filter['show'] == TRIGGERS_OPTION_ALL) ? self::getDataEvents($options) // zabbix api 接口 event.get : self::getDataProblems($options); // zabbix api 接口 problem.get ... if ($problems) { $eventid_till = end($problems)['eventid'] - 1; // 分页查询 $triggerids = []; .... foreach ($problems as $problem) { if (!array_key_exists($problem['objectid'], $seen_triggerids)) { $triggerids[$problem['objectid']] = true; } } if ($triggerids) { $seen_triggerids += $triggerids; // 保存triggerids ... if ($triggerids) { $seen_triggerids += $triggerids; $options = [ 'output' => ['priority'], 'selectHosts' => ['hostid'], 'triggerids' => array_keys($triggerids), 'monitored' => true, 'skipDependent' => ($filter['show'] == TRIGGERS_OPTION_ALL) ? null : true, 'preservekeys' => true ]; ... $data['triggers'] += API::Trigger()->get($options); // 通过 zabbix api接口(trigger.get())和已有的triggerids 查询dashboard 未恢复问题信息 foreach ($problems as $eventid => $problem) { if (!array_key_exists($problem['objectid'], $data['triggers'])) { unset($problems[$eventid]); // 去重 } } $data['problems'] += $problems; //最后dashboard 问题信息汇总,返回给前端页面 } } while (count($data['problems']) < $config['search_limit'] + 1 && !$end_of_data);
参考:
https://www.zabbix.com/documentation/4.0/zh/manual/api/reference/problem/get
https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/frontends/php/app/controllers/CControllerWidgetProblemsView.php?at=refs%2Fheads%2Frelease%2F4.0#34