Zabbix常用SQL操作
前言
线上API项目中, 有部分常用Zabbix操作, 采用直接读库方式。
本文章记录出现在项目中的常用SQL操作(主要以3.x版本为例),主要使用Python语言做演示。
Zabbix一些对应关系及常量
# 历史表对应ID
ZBX_HISTORY_TABLES = ("history", "history_str",
"history_log", "history_uint", "history_text")
# 一些主要的常量
ZBX_MAPPING = {
"EVENT_SOURCE_TRIGGERS": 0,
"EVENT_OBJECT_TRIGGER": 0,
"TRIGGER_VALUE_FALSE": 0,
"SEC_PER_DAY": 86400,
"TRIGGER_VALUE_TRUE": 1,
"TRIGGER_VALUE_TRUE": 0
常用基础操作
获取主机ID
# hostname 主机名
def get_host_id(self, hostname):
sql = """
SELECT hg.hostid from hosts_groups hg,hosts h
WHERE h.hostid=hg.hostid and h.HOST='%s' limit 1;
""" % hostname
获取主机TriggerID
# hostid 主机ID
# triggername 触发器名
def get_trigger_id(self, hostid, triggername):
sql = """
SELECT DISTINCT
t.triggerid
FROM
triggers t,functions f,items i
WHERE
i.hostid='%s'
AND f.triggerid=t.triggerid
AND f.itemid=i.itemid
AND t.description like "%%%s%%"
""" % (hostid, triggername)
获取主机Item ID
# hostid 主机ID
# item item名
def get_item_id(self, hostid, item):
sql = """
SELECT DISTINCT
i.itemid
FROM
items i
WHERE
i.hostid = "%s"
AND i.key_ = "%s"
""" % (hostid, item)
获取ItemID的类型
# itemid itemID
def get_itemid_type(self, itemid):
sql = "SELECT i.value_type FROM items i WHERE i.itemid='%s'" % itemid
获取关闭的Triger(适用于巡检)
def get_close_trigger(self):
sql = """
SELECT
`triggers`.description,
`hosts`.`host`
FROM
`triggers`
INNER JOIN functions ON functions.triggerid = `triggers`.triggerid
INNER JOIN items ON functions.itemid = items.itemid
INNER JOIN `hosts` ON items.hostid = `hosts`.hostid
WHERE
`triggers`.`status` <> 0
"""
获取状态异常的监控项(适用于巡检)
def get_not_supported(self):
sql = """
SELECT
i.name,i.error,h.host
FROM
items i ,hosts h
WHERE
h.hostid = i.hostid and i.error != "" ;
"""
获取关闭的告警器(适用于巡检)
def get_close_trigger(self):
sql = """
SELECT
`triggers`.description,
`hosts`.`host`
FROM
`triggers`
INNER JOIN functions ON functions.triggerid = `triggers`.triggerid
INNER JOIN items ON functions.itemid = items.itemid
INNER JOIN `hosts` ON items.hostid = `hosts`.hostid
WHERE
`triggers`.`status` <> 0
"""
组合操作
获取主机Item历史记录
# self.sql_query为SQL查询器
def get_host_item_history(self, hostname, item, startTime=int(time()) - 60 * 15, endTime=int(time())):
hostid = self.get_host_id(hostname)
# 获取主机id
if not hostid[0]:
return hostid
hostid = hostid[1]
# 获取itemID
itemid = self.get_host_item(hostid, item)
if not itemid[0]:
return itemid
itemid = itemid[1][0]["itemid"]
# 获取itemType
itemtype = self.get_itemid_type(itemid)
if not itemtype[0]:
return itemtype
# 历史数据表对应关系
tables_name = self.ZBX_HISTORY_TABLES[itemtype[1]]
# 获取历史数据
sql = """
SELECT
h.clock,
h.value
FROM
%s h
WHERE
h.itemid = '%s'
AND h.clock >= '%s'
AND h.clock <= '%s';
""" % (tables_name, itemid, startTime, endTime)
result = self.sql_query(sql)
进阶操作
获取Trigger可用率
def get_trigger_availability(self, hostname, trigger, startTime=0, endTime=0):
get_host_id = self.get_host_id(hostname)
if not get_host_id[0]:
return get_host_id
get_trigger_id = self.get_trigger_id(get_host_id[1], trigger)
if not get_trigger_id:
return get_trigger_id
calculateAvailability = self.calculateAvailability(
get_trigger_id[1], startTime, endTime)
return calculateAvailability
# 这一段根据ZabbixWeb PHP源码改写Python版
def calculateAvailability(self, triggerid, startTime=0, endTime=0):
'''
@description: ZABBIX可用率计算(照搬源码)
@param {triggerid} 触发器ID
@param {startTime} 开始时间
@param {endTime} 结束时间
@return: (True/False, Data)
'''
startTime = int(startTime)
endTime = int(endTime)
startValue = self.ZBX_MAPPING["TRIGGER_VALUE_FALSE"]
minValue = None
if startTime > 0 and startTime <= int(time()):
__sql = """
SELECT
e.eventid,e.value
FROM
events e
WHERE
e.objectid=%s
AND e.source=%s
AND e.object=%s
AND e.clock<%s
ORDER BY e.eventid DESC
LIMIT 1
OFFSET 0
""" % (triggerid,
self.ZBX_MAPPING["EVENT_SOURCE_TRIGGERS"],
self.ZBX_MAPPING["EVENT_OBJECT_TRIGGER"],
startTime)
result = self.sql_query(__sql)
logger.debug(__sql)
if result:
startValue = result[0]['value']
minValue = startTime
__sql = """
SELECT
COUNT(e.eventid) AS cnt,
MIN(e.clock) AS min_clock,
MAX(e.clock) AS max_clock
FROM
events e
WHERE
e.objectid=%s
AND e.source=%s
AND e.object=%s
""" % (triggerid,
self.ZBX_MAPPING["EVENT_SOURCE_TRIGGERS"],
self.ZBX_MAPPING["EVENT_OBJECT_TRIGGER"])
if startTime:
__sql += "AND e.clock>=%s " % startTime
if endTime:
__sql += " AND e.clock<=%s " % endTime
dbEvent = self.sql_query(__sql)
logger.debug(__sql)
if dbEvent[0]['cnt'] > 0:
if minValue is not None:
minValue = dbEvent[0]['min_clock']
maxValue = dbEvent[0]['max_clock']
else:
if startTime == 0 and endTime == 0:
maxValue = int(time())
minValue = maxValue - self.ZBX_MAPPING["SEC_PER_DAY"]
else:
resultDict = {
'true_time': 0,
'false_time': 0,
}
resultDict['true'] = 100 if self.ZBX_MAPPING["TRIGGER_VALUE_TRUE"] == startValue else 0
resultDict['false'] = 100 if self.ZBX_MAPPING["TRIGGER_VALUE_FALSE"] == startValue else 0
return True, resultDict
State = startValue
Time = minValue
True_time = 0
False_time = 0
if startTime == 0 and endTime == 0:
maxValue = int(time())
if endTime == 0:
endTime = maxValue
rows = 0
dbEvents = self.sql_query("""
SELECT
e.eventid,
e.clock,
e.value
FROM
events e
WHERE
e.objectid=%s
AND e.source=%s
AND e.object=%s
AND e.clock BETWEEN %s AND %s
ORDER BY e.eventid
""" % (triggerid,
self.ZBX_MAPPING["EVENT_SOURCE_TRIGGERS"],
self.ZBX_MAPPING["EVENT_OBJECT_TRIGGER"],
minValue, maxValue))
if dbEvents:
for row in dbEvents:
clock = row["clock"]
value = row["value"]
diff = max(int(clock) - int(Time), 0)
Time = clock
if State == 0:
False_time += diff
State = value
elif State == 1:
True_time += diff
State = value
if State == self.ZBX_MAPPING["TRIGGER_VALUE_FALSE"]:
False_time = False_time + endTime - Time
elif State == self.ZBX_MAPPING["TRIGGER_VALUE_TRUE"]:
True_time = True_time + endTime - Time
Total_time = True_time + False_time
if Total_time == 0:
resultDict = {
'true_time': 0,
'false_time': 0,
'true': 0,
'false': 0
}
else:
resultDict = {
'true_time': True_time,
'false_time': False_time,
'true': "%.4f" % ((100 * True_time) / Total_time),
'false': "%.4f" % ((100 * False_time) / Total_time)
}
return True, resultDict
return False, "dbEvents Query error!"