From 9a94e0095a51981cc668ac0269667a307c45923c Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Wed, 11 Jan 2012 09:49:53 +0100 Subject: add network_monitor --- sublab_project/sublab_monitor/__init__.py | 1 + sublab_project/sublab_monitor/models.py | 3 ++ sublab_project/sublab_monitor/storage.py | 63 ++++++++++++++++++++++ sublab_project/sublab_monitor/tasks.py | 46 ++++++++++++++++ .../templates/sublab_monitor/host_status.html | 6 +++ .../sublab_monitor/templatetags/__init__.py | 0 .../sublab_monitor/templatetags/host_status.py | 46 ++++++++++++++++ sublab_project/sublab_monitor/tests.py | 24 +++++++++ sublab_project/sublab_monitor/views.py | 1 + 9 files changed, 190 insertions(+) create mode 100644 sublab_project/sublab_monitor/__init__.py create mode 100644 sublab_project/sublab_monitor/models.py create mode 100644 sublab_project/sublab_monitor/storage.py create mode 100644 sublab_project/sublab_monitor/tasks.py create mode 100644 sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html create mode 100644 sublab_project/sublab_monitor/templatetags/__init__.py create mode 100644 sublab_project/sublab_monitor/templatetags/host_status.py create mode 100644 sublab_project/sublab_monitor/tests.py create mode 100644 sublab_project/sublab_monitor/views.py (limited to 'sublab_project/sublab_monitor') diff --git a/sublab_project/sublab_monitor/__init__.py b/sublab_project/sublab_monitor/__init__.py new file mode 100644 index 0000000..1b8cfc0 --- /dev/null +++ b/sublab_project/sublab_monitor/__init__.py @@ -0,0 +1 @@ +from sublab_monitor.storage import Storage, StorageError diff --git a/sublab_project/sublab_monitor/models.py b/sublab_project/sublab_monitor/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/sublab_project/sublab_monitor/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sublab_project/sublab_monitor/storage.py b/sublab_project/sublab_monitor/storage.py new file mode 100644 index 0000000..8b3e385 --- /dev/null +++ b/sublab_project/sublab_monitor/storage.py @@ -0,0 +1,63 @@ +import redis +import pickle +import sys + +# load some django settings here some day + + +class StorageError(Exception): + pass + + +def storage_error(typ): + return type('Storage%sError' % typ.__name__, (typ, StorageError), {}) + + +def raise_storage_error(): + typ, value, trace = sys.exc_info() + + raise storage_error(typ), value, trace + + +class Storage: + key_prefix = 'sublab_monitor.' + + def __init__(self, app_prefix): + self.key_prefix += '%s.' % app_prefix + + try: + self.redis = redis.StrictRedis() + except redis.RedisError: + raise_storage_error() + + def key(self, key): + return '%s%s' % (self.key_prefix, key) + + def get(self, key): + lookup_key = self.key(key) + + try: + entry = self.redis.get(lookup_key) + except redis.RedisError: + raise_storage_error() + + if entry is None: + return None + + try: + return pickle.loads(entry) + except pickle.PickleError: + raise_storage_error() + + def set(self, key, value): + lookup_key = self.key(key) + + try: + entry = pickle.dumps(value) + except pickle.PickleError: + raise_storage_error() + + try: + self.redis.set(lookup_key, entry) + except redis.RedisError: + raise_storage_error() diff --git a/sublab_project/sublab_monitor/tasks.py b/sublab_project/sublab_monitor/tasks.py new file mode 100644 index 0000000..33dcad6 --- /dev/null +++ b/sublab_project/sublab_monitor/tasks.py @@ -0,0 +1,46 @@ +"""Celery tasks. +""" +from datetime import timedelta +from celery.task import PeriodicTask +import subprocess + +import sublab_monitor + +class NetworkStatus(PeriodicTask): + """Periodic task for getting sublab network status + """ + hosts = { + 'taifun': '172.22.83.5', + 'trieste': '172.22.80.4', + 'nautilus': '172.22.80.7', + } + run_every = timedelta(minutes=4) + ignore_result = True + + def __init__(self, *args, **kwargs): + PeriodicTask.__init__(self, *args, **kwargs) + + + @staticmethod + def host_alive(host): + rc = subprocess.call(['ping', '-c', '2', '-W', '1', host]) + + if rc == 0: + return True + else: + return False + + def run(self, **kwargs): + """Ping all the hosts. + """ + self.logger = self.get_logger(**kwargs) + + results = {} + for host, target in self.hosts.items(): + results[host] = self.host_alive(target) + + storage = sublab_monitor.Storage('network_status') + for host, status in results.items(): + storage.set(host, status) + + return repr(results) diff --git a/sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html b/sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html new file mode 100644 index 0000000..5d26dd9 --- /dev/null +++ b/sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html @@ -0,0 +1,6 @@ + {{ hostname|capfirst }}: + + Online +   + Offline + diff --git a/sublab_project/sublab_monitor/templatetags/__init__.py b/sublab_project/sublab_monitor/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sublab_project/sublab_monitor/templatetags/host_status.py b/sublab_project/sublab_monitor/templatetags/host_status.py new file mode 100644 index 0000000..e119f60 --- /dev/null +++ b/sublab_project/sublab_monitor/templatetags/host_status.py @@ -0,0 +1,46 @@ +from django import template +import sublab_monitor + +register = template.Library() + +class HostStatusNode(template.Node): + def __init__(self, host): + self.host = host + + def host_status(self, context): + if self not in context.render_context: + try: + context.render_context[self] = sublab_monitor.Storage('network_status') + except sublab_monitor.StorageError: + return None + + storage = context.render_context[self] + try: + return storage.get(self.host) + except sublab_monitor.StorageError: + return None + + def host_context(self, context): + context_data = { + 'hostname': self.host, + 'status': self.host_status(context) + } + + return template.context.Context(context_data, autoescape=context.autoescape) + + def render(self, context): + t = template.loader.get_template('sublab_monitor/host_status.html') + c = self.host_context(context) + return t.render(c) + +@register.tag +def host_status(parser, token): + try: + tag_name, host = token.split_contents() + except ValueError: + raise template.TemplateSyntaxError( + "%r tag requires a single argument" % token.contents.split()[0]) + if not host[0] == host[-1] and host[0] in ('"', "'"): + raise template.TemplateSyntaxError( + "%r tag's argument should be in quotes" % token.contents.split()[0]) + return HostStatusNode(host[1:-1]) diff --git a/sublab_project/sublab_monitor/tests.py b/sublab_project/sublab_monitor/tests.py new file mode 100644 index 0000000..c80bb61 --- /dev/null +++ b/sublab_project/sublab_monitor/tests.py @@ -0,0 +1,24 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase +from sublab_monitor.tasks import NetworkStatus + +class SimpleTest(TestCase): + def test_reachable(self): + """ + Tests that for reachable hosts host_alive() returns True + """ + self.assertEqual(NetworkStatus.host_alive('127.0.0.1'), True) + + def test_unreachable(self): + """ + Tests that for unreachable hosts host_alive() returns False + """ + # Hopefully, this DoD? IP will never be reachable on the + # Internet :) + self.assertEqual(NetworkStatus.host_alive('8.5.4.3'), False) diff --git a/sublab_project/sublab_monitor/views.py b/sublab_project/sublab_monitor/views.py new file mode 100644 index 0000000..60f00ef --- /dev/null +++ b/sublab_project/sublab_monitor/views.py @@ -0,0 +1 @@ +# Create your views here. -- cgit v1.2.1