Skip to content

Instantly share code, notes, and snippets.

@tawateer
Created December 13, 2016 03:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tawateer/3e7bf9c34141812372b3cccedad1b08e to your computer and use it in GitHub Desktop.
Save tawateer/3e7bf9c34141812372b3cccedad1b08e to your computer and use it in GitHub Desktop.
http montior base for openfalcon
#!/bin/env python
# -*- coding: utf-8 -*-
import os
import re
import time
import json
from urllib import urlencode
from io import BytesIO
import pycurl
def curl(url, method="get", headers={}, data={}, redirect=True, timeout=10):
buffer = BytesIO()
c = pycurl.Curl()
c.setopt(c.URL, url)
if headers != {}:
if isinstance(headers, list):
c.setopt(pycurl.HTTPHEADER, headers)
elif isinstance(headers, dict):
c.setopt(pycurl.HTTPHEADER, ["{0}: {1}".format(key, headers[key]) for key in headers])
else:
raise Exception("header must be list or dict")
if method.lower() == "post" and data != {}:
if isinstance(data, dict):
postfields = urlencode(data)
elif isinstance(data, unicode):
postfields = data.encode("utf-8")
elif isinstance(data, str):
postfields = data
else:
raise Exception("data format error")
c.setopt(c.POSTFIELDS, postfields)
c.setopt(pycurl.CONNECTTIMEOUT, 3)
c.setopt(pycurl.TIMEOUT, timeout)
c.setopt(c.FOLLOWLOCATION, redirect)
c.setopt(c.ENCODING, '!gzip')
c.setopt(c.WRITEFUNCTION, buffer.write)
c.perform()
body = buffer.getvalue()
resp_data = {
"code": c.getinfo(pycurl.HTTP_CODE),
"content": body,
# "length": c.getinfo(pycurl.CONTENT_LENGTH_DOWNLOAD),
"length": len(body),
"request_time": c.getinfo(c.TOTAL_TIME) * 1000
}
# print resp_data
c.close()
return resp_data
COND_REX= r"^\s*(dismatch|!=|==|>|>=|<|<=)\s*(\S+)\s*"
COND_P = re.compile(COND_REX)
def judge_oper(leftValue, operator, rightValue):
# print leftValue, operator, rightValue
if type(leftValue) == int and type(rightValue) != int:
rightValue = int(rightValue)
elif type(leftValue) == str and type(rightValue) != str:
rightValue = str(rightValue)
if operator == "dismatch":
if rightValue not in leftValue:
return True
else:
return False
elif operator == "!=":
return leftValue != rightValue
elif operator == "==":
return leftValue == rightValue
elif operator == ">":
return leftValue > rightValue
elif operator == ">=":
return leftValue >= rightValue
elif operator == "<":
return leftValue < rightValue
elif operator == "<=":
return leftValue <= rightValue
else:
raise Exception("operator error")
def judge(http_resp_data, cond):
def _judge_dict(_cond):
for key in _cond:
if key in http_resp_data:
leftValue = http_resp_data[key]
match = COND_P.match(_cond[key])
if match is None:
raise Exception("{0} format error".format(_cond[key]))
operator = match.group(1)
rightValue = match.group(2)
if judge_oper(leftValue, operator, rightValue):
# print True
return True
# print False
return False
if isinstance(cond, dict):
return _judge_dict(cond)
elif isinstance(cond, list):
for c in cond:
if _judge_dict(c):
return True
return False
else:
raise Exception("cond format error")
def monitor(metric, url, cond, req_data, step=60, redirect=True):
try:
resp_data = curl(
url,
req_data.get("method", "get"),
req_data.get("headers", {}),
req_data.get("data", {}),
redirect,
step-1
)
# print resp_data
ok = not judge(resp_data, cond)
value = int(ok)
except Exception, e:
value = 0
tags = "url={0}".format(url)
for key in req_data:
tags += ",{0}={1}".format(key, req_data[key])
record = {}
record['metric'] = metric
record['endpoint'] = os.uname()[1]
record['timestamp'] = int(time.time())
record['step'] = step
record['value'] = value
record['counterType'] = 'GAUGE'
record['tags'] = tags
return json.dumps([record])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment