import os from datetime import datetime import pymysql import requests CE_ENDPOINT = os.environ["CE_ENDPOINT"] CE_DB_HOST = os.environ["CE_DB_HOST"] CE_DB_PORT = 4000 CE_DB_USER = os.environ["CE_DB_USER"] CE_DB_PASSWD = os.environ["CE_DB_PASSWD"] CE_DB_NAME = "diagnose-rule-stats" def lambda_handler(event, context): if context.get_remaining_time_in_millis() < 60000: raise ValueError("the lambda function's timeout property should be configured at least 60s") _end = int(datetime.now().timestamp()) _start = _end - 600 try: trigger_stats = calculate_trigger_stats(_start, _end) write_trigger_stats_to_db(trigger_stats) except Exception as e: return { "code": 500, "error": e, } return {"code": 200} def query_api(uri, body=None): _url = "{}{}".format(CE_ENDPOINT, uri) if not body: return requests.get(_url).json() return requests.post(_url, json=body).json() def calculate_trigger_stats(start, end): log_uri = "/tasks/log-diag?status=success&begin={}&end={}".format(start, end) log_resp = query_api(log_uri, {"data": {"abnormal": True}}) metric_uri = "/tasks/metrics-advisor?status=success&begin={}&end={}".format(start, end) metric_resp = query_api(metric_uri, {"data": {"abnormal": True}}) joint_resp = log_resp + metric_resp stats = {} for _resp in joint_resp: # validate responses _data = _resp["data"] if _resp["status"] != "success" or not _data["abnormal"]: continue # convert timestamp to 1min steps _cts = _resp["created_at"] _ts = _cts - (_cts % 60) for _advice in _resp["data"]["advice"]: _key = "{}-{}".format(_ts, _advice["id"]) try: stats[_key]["cnt"] += 1 except KeyError: stats[_key] = {"id": _advice["id"], "time": _ts, "cnt": 1} return stats def write_trigger_stats_to_db(stats): conn = pymysql.connect( host=CE_DB_HOST, port=CE_DB_PORT, user=CE_DB_USER, password=CE_DB_PASSWD, database=CE_DB_NAME, charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor, ) with conn: with conn.cursor() as cursor: for stat in stats.values(): _ts = datetime.fromtimestamp(stat["time"]).strftime("%Y-%m-%d %H:%M:%S") sql = "REPLACE INTO `rule_trigger_details` (rule_id, ts, alert_cnt) VALUES ('{}', '{}', '{}')".format( stat["id"], _ts, stat["cnt"], ) try: cursor.execute(sql) except pymysql.IntegrityError: # skip exist rows continue # connection is not autocommit by default. So you must commit to save # your changes. conn.commit()