-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add scheduler for monitors and placeholder for functionalities
- Loading branch information
1 parent
e81dda1
commit f2e93ae
Showing
14 changed files
with
348 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,28 @@ | ||
-- table to store monitors | ||
CREATE TABLE monitors ( | ||
monitor_id SERIAL PRIMARY KEY, | ||
org_id INT NOT NULL, | ||
monitor_name TEXT NOT NULL, | ||
monitor_type TEXT NOT NULL, | ||
monitor_body JSONB NOT NULL, | ||
is_active boolean DEFAULT TRUE, | ||
frequency INT DEFAULT 300, | ||
interval INT DEFAULT 300, | ||
timeout INT DEFAULT 5, | ||
expectation JSONB, | ||
alerts TEXT[], | ||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
-- monitor run history | ||
create table run_history ( | ||
run_id SERIAL PRIMARY KEY, | ||
org_id INT NOT NULL, | ||
monitor_id INT NOT NULL, | ||
outcome boolean NOT NULL, | ||
response_time INT NOT NULL, | ||
response text, | ||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
|
||
select * from monitors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
""" | ||
Created On: July 2024 | ||
Created By: Sourav Saha | ||
""" | ||
import os | ||
import logging | ||
from rich.logging import RichHandler | ||
|
||
# load environment variables | ||
from dotenv import load_dotenv | ||
base_dir = os.path.dirname(os.getcwd()) | ||
load_dotenv(f"{base_dir}/.env") | ||
load_dotenv(f"{base_dir}/.env.local", override=True) | ||
|
||
logging.basicConfig(level='INFO', format='%(message)s', datefmt="[%X]", handlers=[RichHandler()]) | ||
logger = logging.getLogger() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,82 @@ | ||
from utils import logger | ||
from utils import DatabaseManager | ||
import time | ||
import requests | ||
from commons import logger | ||
from db_util import DatabaseManager | ||
|
||
db = DatabaseManager() | ||
|
||
def create_monitor(data: dict): | ||
def get_monitor_by_id(monitor_id: int): | ||
sql = f"select * from monitors where monitor_id={monitor_id}" | ||
_df = db.query(sql) | ||
monitor = _df.to_dict('records')[0] | ||
return monitor | ||
|
||
def get_monitor_by_orgid(org_id: int): | ||
sql = f"select * from monitors where org_id={org_id}" | ||
return db.query(sql) | ||
|
||
def get_all_monitors(): | ||
sql = "select * from monitors where is_active" | ||
df = db.query(sql) | ||
return df | ||
|
||
def insert_monitor(data: dict): | ||
logger.info(f"Creating monitor: {data}") | ||
sql = """insert into monitors (monitor_type, monitor_name, monitor_body, timeout, frequency, expectation, alerts) | ||
sql = """insert into monitors (monitor_type, monitor_name, monitor_body, timeout, interval, expectation, alerts) | ||
values (%(monitor_type)s, %(monitor_name)s, %(monitor_body)s, %(timeout)s, %(frequency)s, %(expectation)s, %(alerts)s) | ||
returning monitor_id | ||
""" | ||
monitor_id = db.insert(sql, data) | ||
logger.info(f"Inserted Monitor with id {monitor_id}") | ||
return monitor_id | ||
|
||
def update_monitor(monitor_id: int, data: dict): | ||
logger.info(f"Updating monitor: {data}") | ||
logger.info(f"Updated Monitor with id {monitor_id}") | ||
pass | ||
|
||
def delete_monitor(monitor_id: int): | ||
logger.info(f"Deleting monitor: #{monitor_id}") | ||
sql = f"delete from monitors where monitor_id = {monitor_id}" | ||
db.query(sql) | ||
logger.info(f"Deleted Monitor with id {monitor_id}") | ||
|
||
def run_monitor_by_id(monitor_id): | ||
monitor = get_monitor_by_id(monitor_id) | ||
start_time = time.time() | ||
try: | ||
if monitor['monitor_type'] == 'api': | ||
outcome, response = run_api_monitor(monitor['monitor_body'], monitor.get('expectation')) | ||
else: | ||
outcome, response = False | ||
|
||
except Exception as e: | ||
logger.error(f"Error running monitor: {e}") | ||
outcome, response = False | ||
|
||
# store run history | ||
response_time = time.time() - start_time | ||
sql = f"""insert into run_history (org_id, monitor_id, outcome, response_time, response) values | ||
({monitor['org_id']}, {monitor_id}, {outcome}, {response_time}, '{response}') | ||
""" | ||
db.insert(sql) | ||
return outcome | ||
|
||
def run_api_monitor(monitor_body: dict, expectation: dict): | ||
res = requests.request( | ||
monitor_body.get('method'), monitor_body.get('url'), | ||
headers=monitor_body.get('headers'), | ||
params=monitor_body.get('params'), | ||
data=monitor_body.get('body') | ||
) | ||
logger.info(f"Response: {res.status_code} | {res.reason}") | ||
|
||
if expectation: | ||
response_code_list = expectation.get('response_codes') | ||
is_allow_list = expectation.get('is_allow_list') | ||
outcome = (is_allow_list and res.status_code in response_code_list) or (not is_allow_list and res.status_code not in response_code_list) | ||
|
||
else: | ||
outcome = 200 <= res.status_code < 300 | ||
|
||
return outcome, res.status_code |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from typing import Literal, Optional | ||
from pydantic import BaseModel, Extra, PositiveInt, Field | ||
|
||
class MonitorModel(BaseModel): | ||
org_id: PositiveInt | None = None | ||
# monitor_type: Literal["api", "website", "database", "server", "ssl", "mq"] | ||
monitor_name: str | None = None | ||
monitor_body: dict | None = None | ||
timeout: int | None = None | ||
interval: int | None = None | ||
expectation: dict | None = None | ||
alerts: list[int] | None = None | ||
is_active: bool | None = None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.