Prometheus의 결과를 이용하여 알람 등을 구현할 때 HTTP API를 이용하는 것이 좋다.

HTTP API | Prometheus
An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.
구현하고 나서 보면 어려운 것이 아닌데 구현하기 전에는 어려운 그런 것이다. PACS 다운로드 여부를 판단하는 방법으로 그 동안에는 vnstat을 이용한 통계치를 이용했다. Prometheus를 이용하여 모니터링 하는 시점에서 더 이상 그런 방법을 이용하고 싶지 않았다. 또한, PACS 자료는 DB와 이미지 저장 공간이 서로 다르다. 그래서 정말로 이미지 저장을 하는 TrueNAS 의 트래픽 만을 감지해서 알람을 구현하고 싶었다.
처음에 어려웠던 부분은 query 에 ‘up’ 이라고 되어 있는 부분 때문에 무엇을 입력해야 하는지 찾는 것이었다. 이런 저런 시도 끝에 prometheus에서 수집하는 metrics을 입력하면 된다는 것을 알게 되었다. TrueNAS는 1개만 운영하고 있으니 따로 다른 방법으로 구별해 줄 필요는 아직 없었다.
import requests
import json
import os
msg = requests.get("http://10.10.10.184:9090/api/v1/query?query=servers_truenas_local_interface_em0_if_octets_rx")
r0 = int(float(json.loads(msg.text)['data']['result'][0]['value'][1]))
print(r0)
msg = requests.get("http://10.10.10.184:9090/api/v1/query?query=servers_truenas_local_interface_em1_if_octets_rx")
r1 = int(float(json.loads(msg.text)['data']['result'][0]['value'][1]))
print(r1)
msg = requests.get("http://10.10.10.184:9090/api/v1/query?query=servers_truenas_local_interface_em0_if_octets_tx")
t0 = int(float(json.loads(msg.text)['data']['result'][0]['value'][1]))
print(t0)
msg = requests.get("http://10.10.10.184:9090/api/v1/query?query=servers_truenas_local_interface_em1_if_octets_tx")
t1 = int(float(json.loads(msg.text)['data']['result'][0]['value'][1]))
print(t1)
if r1 < 1000:
os.system("sudo docker exec msg /root/msg_complete")
if t0 + t1 > 1e6:
os.system("sudo docker exec msg /root/msg_start")
구간별 평균치를 이용하는 경우 다음과 같은 방법을 이용하면 된다. Promethues 도커 컨테이너의 경우 UTC 기반이기 때문에 시간을 변경하는 부분이 필요하다.
datetime의 astimezone 을 이용해야 정말로 UTC에 해당하는 시간 값을 받을 수 있다.
import requests
import json
import os
import datetime
now = datetime.datetime.now()
now_timestamp = str(int(now.astimezone(datetime.timezone.utc).timestamp()))
before = now - datetime.timedelta(minutes=1)
before_timestamp = str(int(before.astimezone(datetime.timezone.utc).timestamp()))
msg = requests.get("http://10.10.10.184:9090/api/v1/query_range?query=servers_truenas_local_interface_em0_if_octets_rx&start=" + before_timestamp+ "&end=" + now_timestamp + "&step=1m")
r0 = int(float(json.loads(msg.text)['data']['result'][0]['values'][-1][1]))
print(r0)