From f563526a2abec591503421eb8021d35ce3ee4a3d Mon Sep 17 00:00:00 2001 From: Mitsuo Takaki Date: Tue, 3 May 2016 02:28:58 -0700 Subject: [PATCH] Creating push_metrics() method to start pushing the URL latency, if it the metric id is configured. --- cachet_url_monitor/configuration.py | 30 ++++++++++++++++++++++++----- cachet_url_monitor/scheduler.py | 3 ++- config.yml | 6 +++--- tests/test_configuration.py | 12 ++++++------ tests/test_scheduler.py | 4 ++-- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/cachet_url_monitor/configuration.py b/cachet_url_monitor/configuration.py index c038a26..ebacf38 100644 --- a/cachet_url_monitor/configuration.py +++ b/cachet_url_monitor/configuration.py @@ -3,7 +3,7 @@ import abc import logging import re import requests -import timeit +import time from yaml import load @@ -22,6 +22,7 @@ class Configuration(object): in self.data['endpoint']['expectation']] for expectation in self.expectations: self.logger.info('Registered expectation: %s' % (expectation,)) + self.headers = {'X-Cachet-Token': self.data['cachet']['token']} def evaluate(self): """Sends the request to the URL set in the configuration and executes @@ -32,6 +33,7 @@ class Configuration(object): self.request = requests.request(self.data['endpoint']['method'], self.data['endpoint']['url'], timeout=self.data['endpoint']['timeout']) + self.current_timestamp = int(time.time()) except requests.ConnectionError: self.logger.warning('The URL is unreachable: %s %s' % (self.data['endpoint']['method'], @@ -56,15 +58,14 @@ class Configuration(object): if status > self.status: self.status = status - def push_status_and_metrics(self): + def push_status(self): params = {'id': self.data['cachet']['component_id'], 'status': self.status} - headers = {'X-Cachet-Token': self.data['cachet']['token']} component_request = requests.put('%s/components/%d' % (self.data['cachet']['api_url'], self.data['cachet']['component_id']), - params=params, headers=headers) - if component_request.status_code == 200: + params=params, headers=self.headers) + if component_request.ok: # Successful update self.logger.info('Component update: status [%d]' % (self.status,)) else: @@ -72,6 +73,25 @@ class Configuration(object): self.logger.warning('Component update failed with status [%d]: API' ' status: [%d]' % (component_request.status_code, self.status)) + def push_metrics(self): + if 'metric_id' in self.data['cachet'] and hasattr(self, 'request'): + params = {'id': self.data['cachet']['metric_id'], 'value': + self.request.elapsed.total_seconds(), 'timestamp': + self.current_timestamp} + metrics_request = requests.post('%s/metrics/%d/points' % + (self.data['cachet']['api_url'], + self.data['cachet']['metric_id']), params=params, + headers=self.headers) + + if metrics_request.ok: + # Successful metrics upload + self.logger.info('Metric uploaded: %.6f seconds' % + (self.request.elapsed.total_seconds(),)) + else: + self.logger.warning('Metric upload failed with status [%d]' % + (metrics_request.status_code,)) + + class Expectaction(object): """Base class for URL result expectations. Any new excpectation should extend this class and the name added to create() method. diff --git a/cachet_url_monitor/scheduler.py b/cachet_url_monitor/scheduler.py index ade6153..7fae92c 100644 --- a/cachet_url_monitor/scheduler.py +++ b/cachet_url_monitor/scheduler.py @@ -18,7 +18,8 @@ class Agent(object): cachet server. """ self.configuration.evaluate() - self.configuration.push_status_and_metrics() + self.configuration.push_status() + self.configuration.push_metrics() def start(self): """Sets up the schedule based on the configuration file.""" diff --git a/config.yml b/config.yml index f665398..537d4d2 100644 --- a/config.yml +++ b/config.yml @@ -8,10 +8,10 @@ endpoint: - type: LATENCY threshold: 1 - type: REGEX - regex: ".*.*" + regex: '.*.*' cachet: - api_url: http://status.cachethq.io/api/v1/ + api_url: https://demo.cachethq.io/api/v1 token: my_token component_id: 1 - metric_id: 1 + #metric_id: 1 frequency: 30 diff --git a/tests/test_configuration.py b/tests/test_configuration.py index a947299..39515ef 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -100,9 +100,9 @@ class ConfigurationTest(unittest.TestCase): self.mock_logger.exception.assert_called_with(('Unexpected HTTP ' 'response')) - def test_push_status_and_metrics(self): + def test_push_status(self): def put(url, params=None, headers=None): - assert url == 'http://status.cachethq.io/api/v1//components/1' + assert url == 'https://demo.cachethq.io/api/v1/components/1' assert params == {'id': 1, 'status': 1} assert headers == {'X-Cachet-Token': 'my_token'} @@ -112,11 +112,11 @@ class ConfigurationTest(unittest.TestCase): sys.modules['requests'].put = put self.configuration.status = 1 - self.configuration.push_status_and_metrics() + self.configuration.push_status() - def test_push_status_and_metrics_with_failure(self): + def test_push_status_with_failure(self): def put(url, params=None, headers=None): - assert url == 'http://status.cachethq.io/api/v1//components/1' + assert url == 'https://demo.cachethq.io/api/v1/components/1' assert params == {'id': 1, 'status': 1} assert headers == {'X-Cachet-Token': 'my_token'} @@ -126,4 +126,4 @@ class ConfigurationTest(unittest.TestCase): sys.modules['requests'].put = put self.configuration.status = 1 - self.configuration.push_status_and_metrics() + self.configuration.push_status() diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index 64b989e..6f1bd56 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -17,11 +17,11 @@ class AgentTest(unittest.TestCase): def test_execute(self): evaluate = self.configuration.evaluate - push_status_and_metrics = self.configuration.push_status_and_metrics + push_status = self.configuration.push_status self.agent.execute() evaluate.assert_called_once() - push_status_and_metrics.assert_called_once() + push_status.assert_called_once() def test_start(self): every = sys.modules['schedule'].every