Skip to content

Commit

Permalink
Add columns to perf_metric table for check status
Browse files Browse the repository at this point in the history
- Preparation for adding quick 'latest status' review method
  • Loading branch information
tym-xqo committed Aug 7, 2019
1 parent 5c8634a commit 317c6eb
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 47 deletions.
4 changes: 2 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ verify_ssl = true
[packages]
apscheduler = "*"
dba-metrics = {editable = true,path = "."}
nerium = {editable = true,git = "https://github.com/tym-xqo/nerium",ref = "e2eb289"}
# nerium = {editable = true, path = "../nerium"}
nerium = {editable = true,git = "https://github.com/tym-xqo/nerium"}
# nerium = {editable = true,path = "../nerium"}
pg8000 = "*"
slackclient = "*"
32 changes: 30 additions & 2 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 35 additions & 5 deletions dba_metrics/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
def get_metric(name, quiet=False):
metric = get_result_set(name)
metric.executed += "Z"
check_metric(metric)
metric = check_metric(metric)
return metric


Expand All @@ -46,16 +46,43 @@ def print_metric(name):

def store_metric(name):
metric = get_metric(name)
# fmt: off
sql = (
"insert into perf_metric (stamp, payload, name, host) "
"values (:stamp, :payload, :name, :host) "
"INSERT into perf_metric ("
" stamp, "
" payload, "
" name, "
" host, "
" status, "
" threshold_field, "
" threshold_gate) "
"VALUES ("
" :stamp, "
" :payload, "
" :name, "
" :host, "
" :status, "
" :threshold_field, "
" :threshold_gate) "
"returning metric_id"
)
# fmt: on
for i in metric.result:
stamp = metric.executed
payload = json.dumps(i, default=str)
status = metric.status
threshold_field = metric.threshold["field"]
threshold_gate = str(metric.threshold["gate"])
print(stamp, payload, status, threshold_field, threshold_gate)
insert = store_db.query(
sql, stamp=stamp, payload=payload, name=name, host=HOSTNAME
sql,
stamp=stamp,
payload=payload,
name=name,
host=HOSTNAME,
status=status,
threshold_field=threshold_field,
threshold_gate=threshold_gate,
)
return insert.export("json")

Expand Down Expand Up @@ -100,7 +127,10 @@ def create_table():
"stamp timestamp with time zone, "
"payload jsonb, "
"name text, "
"host text)"
"host text, "
"status text, "
"threshold_field text, "
"threshold_gate int)"
)
store_db.query(sql)

Expand Down
72 changes: 37 additions & 35 deletions dba_metrics/alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,29 @@
load_dotenv(find_dotenv(), override=override)

HOSTNAME = os.getenv("HOSTNAME", "localhost")
stopfile = Path("/tmp/dba-alert-pause")


def swap_status(status):
"""Toggle status between "clear" and "failure" on check status change
"""
opts = cycle(["clear", "failure"])
new_status = next(opts)
if status == new_status:
new_status = next(opts)
return new_status


def update_config(metric):
"""Rewrite sql metadata with new status after change
"""
sql = metric.body
metadata = metric.metadata
metadata_yaml = yaml.safe_dump(metadata)
metadata_block = f"---\n{metadata_yaml}---"
query_file = os.path.join("query_files", f"{metric.name}.sql")
with open(query_file, "w") as config_file:
new_content = "\n".join([metadata_block, sql, ""])
config_file.write(new_content)


def send_alert(metric):
Expand All @@ -27,6 +49,7 @@ def send_alert(metric):
threshold = metric.metadata["threshold"]["gate"]
status = metric.metadata["status"]
value = metric.value
alert = None

format = get_format("print")
full_metric = yaml.safe_dump(format.dump(metric).data)
Expand All @@ -42,65 +65,44 @@ def send_alert(metric):
if status == "failure":
color = "danger"

alert = slack_post(title=title, message=message, color=color)
return alert

stopfile = Path("/tmp/dba-alert-pause")
if not stopfile.exists() and status != "pause":
alert = slack_post(title=title, message=message, color=color)
update_config(metric)

def swap_status(status):
"""Toggle status between "clear" and "failure" on check status change
"""
opts = cycle(["clear", "failure"])
new_status = next(opts)
if status == new_status:
new_status = next(opts)
return new_status


def update_config(metric):
"""Rewrite sql metadata with new status after change
"""
sql = metric.body
metadata = metric.metadata
metadata_yaml = yaml.safe_dump(metadata)
metadata_block = f"---\n{metadata_yaml}---"
query_file = os.path.join("query_files", f"{metric.name}.sql")
with open(query_file, "w") as config_file:
new_content = "\n".join([metadata_block, sql, ""])
config_file.write(new_content)
metric.alert = alert
return metric


def check_metric(metric):
"""Compare metric check value against threshold;
Update status and send alert if comparsison triggers status change
"""
# TODO: Support failure modes other than `> threshold`
alert = None
if stopfile.exists():
return alert

try:
data = metric.result
status = metric.metadata["status"]
check = metric.metadata["threshold"]["field"]
threshold = metric.metadata["threshold"]["gate"]
except (KeyError, AttributeError):
return alert

if status == "pause":
return alert
return metric

if data:
value = max([row[check] for row in data])
metric.value = value

test = value >= threshold
if status == "failure":
test = value < threshold

if test:
metric.metadata["status"] = swap_status(status)
alert = send_alert(metric)
update_config(metric)
metric = send_alert(metric)

return alert
metric.status = metric.metadata["status"]
metric.threshold = metric.metadata["threshold"]
return metric


if __name__ == "__main__":
Expand Down
6 changes: 4 additions & 2 deletions format_files/print.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@


class ResultSchema(Schema):
name = fields.Str(attribute="name")
data = fields.List(fields.Dict(), attribute="result")
name = fields.Str()
result = fields.List(fields.Dict())
status = fields.Str()
threshold = fields.Dict()
stamp = fields.Str(attribute="executed")
4 changes: 3 additions & 1 deletion format_files/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@


class ResultSchema(Schema):
name = fields.Str(attribute="name")
name = fields.Str()
payload = fields.List(fields.Dict(), attribute="result")
status = fields.Str()
threshold = fields.Dict()
stamp = fields.Str(attribute="executed")

0 comments on commit 317c6eb

Please sign in to comment.