python如何獲取Prometheus監(jiān)控數(shù)據(jù)
獲取Prometheus監(jiān)控數(shù)據(jù)
獲取Prometheus target數(shù)據(jù)
調(diào)用http://<prometheus.address>/api/v1/targets并解析。
def getTargetsStatus(address): ? ? url = address + '/api/v1/targets' ? ? response = requests.request('GET', url) ? ? if response.status_code == 200: ? ? ? ? targets = response.json()['data']['activeTargets'] ? ? ? ? aliveNum, totalNum = 0, 0 ? ? ? ? downList = [] ? ? ? ? for target in targets: ? ? ? ? ? ? totalNum += 1 ? ? ? ? ? ? if target['health'] == 'up': ? ? ? ? ? ? ? ? aliveNum += 1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? downList.append(target['labels']['instance']) ? ? ? ? print('-----------------------TargetsStatus--------------------------') ? ? ? ? print(str(aliveNum) + ' in ' + str(totalNum) + ' Targets are alive !!!') ? ? ? ? print('--------------------------------------------------------------') ? ? ? ? for down in downList: ? ? ? ? ? ? print('\033[31m\033[1m' + down + '\033[0m' + ' down !!!') ? ? ? ? print('-----------------------TargetsStatus--------------------------') ? ? else: ? ? ? ? print('\033[31m\033[1m' + 'Get targets status failed!' + '\033[0m')
獲取Prometheus 監(jiān)控信息(cpu、mem、disks)
調(diào)用http://<prometheus.address>/api/v1/query?query=<expr>并解析,其中expr為prometheus的查詢語句。
### 定義cpu、mem、disks使用率的空字典 diskUsageDict = {} cpuUsageDict = {} memUsageDict = {} ### 定義采集時間間隔 s monitorInterval = 5 ### 定義超時告警時間 s diskAlertTime = 5 cpuAlertTime = 300 memAlertTime = 300 ### 定義告警閾值 % diskThreshold = 80 cpuThreshold = 60 memThreshold = 70 def queryUsage(address, expr): url = address + '/api/v1/query?query=' + expr try: return json.loads(requests.get(url=url).content.decode('utf8', 'ignore')) except Exception as e: print(e) return {} def orderUsageDict(usageDict, currentTime, monitorInterval): ''' :param usageDict: 資源使用率字典 :param usageDict: 資源使用率字典 :param currentTime: 當(dāng)前獲取監(jiān)控數(shù)據(jù)的時間節(jié)點(diǎn) :return: :description: 剔除字典中不滿足連續(xù)超出閾值的數(shù)據(jù) ''' for key in list(usageDict.keys()): if currentTime - usageDict[key][1] >= monitorInterval: usageDict.pop(key) def getCurrentUsageGreater(address, record, threshold, usageDict, monitorInterval): ''' :param address: Prometheus address :param record: Prometheus rules record :param threshold: 閾值 :param usageDict: 資源使用率字典 :param monitorInterval: 監(jiān)控時間間隔 :return: :description: 獲取資源使用率大于閾值的數(shù)據(jù) ''' expr = record + '>=' + str(threshold) usage = queryUsage(address=address, expr=expr) currentTime = 0 if 'data' in usage and usage['data']['result']: for metric in usage['data']['result']: instance = metric['metric']['instance'] if record == 'node:fs_usage:ratio' or record == 'node:fs_root_usage:ratio': metricLabel = instance + ':' + metric['metric']['mountpoint'] else: metricLabel = instance utctime = metric['value'][0] value = metric['value'][1] describe = record.split(':')[1] if not metricLabel in usageDict.keys(): usageDict[metricLabel] = (utctime, utctime, describe, value) else: startTime = usageDict.get(metricLabel)[0] usageDict[metricLabel] = (startTime, utctime, describe, value) currentTime = utctime orderUsageDict(usageDict=usageDict, currentTime=currentTime, monitorInterval=monitorInterval) def printUsageDict(usageDict, alertTime): ''' :param usageDict: 資源使用率字典 :param alertTime: 監(jiān)控告警時間 :return: :description: 打印出超過監(jiān)控告警時間的數(shù)據(jù) ''' for key, value in usageDict.items(): deltaT = value[1] - value[0] if deltaT >= alertTime: print(key + ' ----- ' + value[2] + '\033[31m\033[1m ' + str(value[3]) + '\033[0m ----- lasted for\033[31m\033[1m %.2f \033[0mseconds' % deltaT) def monitorUsageGreater(address): ''' :param address: Prometheus address :return: :description: 持續(xù)監(jiān)控并輸出數(shù)據(jù) ''' while True: getCurrentUsageGreater(address, 'node:fs_usage:ratio', diskThreshold, diskUsageDict, monitorInterval) printUsageDict(diskUsageDict, alertTime=diskAlertTime) getCurrentUsageGreater(address, 'node:memory_usage:ratio', cpuThreshold, memUsageDict, monitorInterval) printUsageDict(memUsageDict, alertTime=memAlertTime) getCurrentUsageGreater(address, 'node:cpu_usage:ratio', memThreshold, cpuUsageDict, monitorInterval) printUsageDict(cpuUsageDict, alertTime=cpuAlertTime) time.sleep(monitorInterval)
其中有一些使用細(xì)節(jié),比如統(tǒng)一資源標(biāo)識符URI的構(gòu)建,將HttpEntity用UTF-8編碼方式轉(zhuǎn)換為字符串再解析為JSON對象,我都寫在注釋里了。
String paramValue="http_requests_total"; //HTTP客戶端連接工具 CloseableHttpClient httpClient=HttpClients.createDefault(); //參數(shù)里有特殊字符,不能直接寫成String(會報Illegal Character錯誤),用URIBuilder構(gòu)造。 URIBuilder uri=null; HttpGet get =null; try { //一對參數(shù),使用addParameter(param: ,value:)這個方法添加參數(shù)。 //若多對參數(shù),使用第二種方法(但其實(shí)在這里沒有這種情況):uri.addParameters(List<NameValuePair>); //這里的ip,port換成你的Prometheus的ip+port。paramValue要自己定義,比如http_request_total uri=new URIBuilder("http://ip:port/api/v1/query"); uri.addParameter("query",paramValue); //uri此時是http://ip:port/api/v1/query?query=http_requests_total get=new HttpGet(uri.build()); } catch (URISyntaxException e) { e.printStackTrace(); } JSONObject jsonObject=null; CloseableHttpResponse response=null; try { // 執(zhí)行請求并接收+轉(zhuǎn)換 得到j(luò)sonObject就可以解析了。 response = httpClient.execute(get); String resStr= EntityUtils.toString(response.getEntity(),"UTF-8"); jsonObject=JSONObject.parseObject(resStr);
通過promsql讀取prometheus內(nèi)的數(shù)據(jù)
需求是python讀取prometheus內(nèi)的數(shù)據(jù),做數(shù)據(jù)處理后入庫到mysql。這里主要說一下,python如何使用官方api通過promsql查詢prom內(nèi)的數(shù)據(jù)。
官方提供的api為:
http://ip:port/api/v1/query?query=
樣例如下:
html = urllib.request.urlopen('http://ip:port/api/v1/query?query=count(node_cpu_seconds_total{job="%s",mode="idle"})' %(s)) data = html.read().decode("utf-8") json = json.loads(data)
返回值為json類型,如下圖:
具體的json各位自己分析,瞬時值為value,值內(nèi)數(shù)據(jù),第一位是時間戳,第二位為查詢的結(jié)果值
區(qū)間向量返回值為values,也比較好理解。
還有個需求需要查詢之前的數(shù)據(jù),比如前一天,月初一周之類的,可以使用如下api:
http://ip:port/api/v1/query_range?query=avg(1-avg(rate(node_cpu_seconds_total{job="%s",mode="idle"}[5m]))by(instance))&start='+start+'&end='+end+'&step=15s
其中start為采集開始時間,end為采集結(jié)束時間,step為步長,即多久設(shè)個采集點(diǎn)。
start和end的格式如下:
2021-11-01T00:00:00Z
獲取方式可以采取以下方式:
獲取每月的第一周數(shù)據(jù),所以從每月一號零點(diǎn)開始到八號的零點(diǎn)
now = datetime.datetime.now() start = datetime.datetime(now.year, now.month, 1) end = datetime.datetime(now.year, now.month, 8) # 格式轉(zhuǎn)換:yyyy-mm-ddThh:MM:ssZ start_trans = "T".join(str(start).split(" "))+"Z" end_trans = "T".join(str(end).split(" "))+"Z"
獲取前一周的時間
now_time = datetime.datetime.now() one_week_ago_time = now_time + datetime.timedelta(days=-7) # 精確到毫秒 now = now_time.strftime("%Y-%m-%dT%H:%M:%S.%f") one_week_ago = one_week_ago_time.strftime("%Y-%m-%dT%H:%M:%S.%f") n = now[0:len(now)-7]+"Z" one_week = one_week_ago[0:len(one_week_ago)-7]+"Z"
如果獲取時間周期太長,返回數(shù)據(jù)太多會導(dǎo)致報錯,這時候可調(diào)整step大小,或者將時間段分成幾天獲取。
主要還是了解兩個api,其他的都是小問題
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python使用Pexpect庫實(shí)現(xiàn)自動化與終端交互的任務(wù)
Pexpect 是一個 Python 庫,用于自動化與終端交互的任務(wù),它提供了一種簡單的方式來編寫腳本,以便與終端程序進(jìn)行交互,下面我們就來深入了解一下Pexpect庫的具體使用吧2023-12-12PyCharm如何導(dǎo)入python項(xiàng)目的方法
這篇文章主要介紹了PyCharm如何導(dǎo)入python項(xiàng)目的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Python操作MongoDb數(shù)據(jù)庫流程詳解
這篇文章主要介紹了Python操作MongoDb數(shù)據(jù)庫流程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03django rest framework 實(shí)現(xiàn)用戶登錄認(rèn)證詳解
這篇文章主要介紹了django rest framework 實(shí)現(xiàn)用戶登錄認(rèn)證詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-07-07零基礎(chǔ)寫python爬蟲之使用urllib2組件抓取網(wǎng)頁內(nèi)容
文章詳細(xì)介紹了在python2.5環(huán)境下,如何使用urllib2這個python自帶的組件進(jìn)行抓取指定網(wǎng)頁內(nèi)容的,整個過程記錄的非常的詳細(xì),也很簡單,有需要的朋友可以參考下,寫出自己的python爬蟲2014-11-11Python+request+unittest實(shí)現(xiàn)接口測試框架集成實(shí)例
這篇文章主要介紹了Python+request+unittest實(shí)現(xiàn)接口測試框架集成實(shí)例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03pip更新問題的解決:'python -m pip install -
這篇文章主要介紹了pip更新問題的解決:'python -m pip install --upgrade pip' 報錯問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04