diff --git a/README.md b/README.md index de4e6c2..f336d91 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,59 @@ cachet-url-monitor ======================== -Python plugin for [cachet](cachethq.io) that monitors an URL, verifying it's response status and latency. \ No newline at end of file +Python plugin for [cachet](cachethq.io) that monitors an URL, verifying it's response status and latency. The frequency the URL is tested is configurable, along with the assertion applied to the request response. + +## Configuration + +```yaml +endpoint: + url: http://www.google.com + method: GET + timeout: 0.010 # seconds + expectation: + - type: HTTP_STATUS + status: 200 + - type: LATENCY + threshold: 1 + - type: REGEX + regex: ".*.*" +cachet: + api_url: http://status.cachethq.io/api/v1/ + token: my_token + component_id: 1 + metric_id: 1 +frequency: 30 +``` + +- **endpoint**, the configuration about the URL that will be monitored. + - **url**, the URL that is going to be monitored. + - **method**, the HTTP method that will be used by the monitor. + - **timeout**, how long we'll wait to consider the request failed. The unit of it is seconds. + - **expectation**, the list of expectations set for the URL. + - **HTTP_STATUS**, we will verify if the response status code matches what we expect. + - **LATENCY**, we measure how long the request took to get a response and fail if it's above the threshold. The unit is in seconds. + - **REGEX**, we verify if the response body matches the given regex. +- **cachet**, this is the settings for our cachet server. + - **api_url**, the cachet API endpoint. + - **token**, the API token. + - **component_id**, the id of the component we're monitoring. This will be used to update the status of the component. + - **metric_id**, this will be used to store the latency of the API. If this is not set, it will be ignored. +- **frequency**, how often we'll send a request to the given URL. The unit is in seconds. + +## Setting up + +The application should be installed using **virtualenv**, through the following command: + +``` +$ git clone git@github.com:mtakaki/cachet-url-monitor.git +$ virtualenv cachet-url-monitor +$ cd cachet-url-monitor +$ source bin/activate +$ pip install -r requirements.txt +``` + +To start the agent: + +``` +$ python cachet_url_monitor/scheduler.py config.yml +``` \ No newline at end of file diff --git a/cachet_url_monitor/configuration.py b/cachet_url_monitor/configuration.py index 02513c6..c038a26 100644 --- a/cachet_url_monitor/configuration.py +++ b/cachet_url_monitor/configuration.py @@ -20,6 +20,8 @@ class Configuration(object): self.data = load(file(self.config_file, 'r')) self.expectations = [Expectaction.create(expectation) for expectation in self.data['endpoint']['expectation']] + for expectation in self.expectations: + self.logger.info('Registered expectation: %s' % (expectation,)) def evaluate(self): """Sends the request to the URL set in the configuration and executes diff --git a/cachet_url_monitor/scheduler.py b/cachet_url_monitor/scheduler.py index a3d5291..ade6153 100644 --- a/cachet_url_monitor/scheduler.py +++ b/cachet_url_monitor/scheduler.py @@ -30,11 +30,12 @@ class Scheduler(object): self.logger = logging.getLogger('cachet_url_monitor.scheduler.Scheduler') self.configuration = Configuration(config_file) self.agent = Agent(self.configuration) + self.stop = False def start(self): self.agent.start() self.logger.info('Starting monitor agent...') - while True: + while not self.stop: schedule.run_pending() time.sleep(self.configuration.data['frequency']) @@ -42,6 +43,8 @@ class Scheduler(object): if __name__ == "__main__": FORMAT = "%(levelname)9s [%(asctime)-15s] %(name)s - %(message)s" logging.basicConfig(format=FORMAT, level=logging.INFO) + for handler in logging.root.handlers: + handler.addFilter(logging.Filter('cachet_url_monitor')) if len(sys.argv) <= 1: logging.fatal('Missing configuration file argument') diff --git a/config.yml b/config.yml index 8eee8d3..ae454ca 100644 --- a/config.yml +++ b/config.yml @@ -1,7 +1,7 @@ endpoint: url: http://localhost:8080/swagger method: GET - timeout: 0.010 + timeout: 0.01 expectation: - type: HTTP_STATUS status: 200 diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index aafbabc..2b2aef4 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -1,9 +1,11 @@ #!/usr/bin/env python +import logging import mock import unittest import sys sys.modules['schedule'] = mock.Mock() -from cachet_url_monitor.scheduler import Agent +sys.modules['cachet_url_monitor.configuration.Configuration'] = mock.Mock() +from cachet_url_monitor.scheduler import Agent,Scheduler class AgentTest(unittest.TestCase): @@ -31,3 +33,17 @@ class AgentTest(unittest.TestCase): every.assert_called_with(5) +class SchedulerTest(unittest.TestCase): + def setUp(self): + self.mock_configuration = sys.modules['cachet_url_monitor.configuration.Configuration'] + self.scheduler = Scheduler('config.yml') + + def test_init(self): + #TODO(mtakaki|2016-05-01): We need more assertions in this test. + assert self.scheduler.stop == False + + def test_start(self): + #TODO(mtakaki|2016-05-01): We need a better way of testing this method. + # Leaving it as a placeholder. + self.scheduler.stop = True + self.scheduler.start()