2014-07-10 15:19:06 +00:00
|
|
|
import datetime
|
|
|
|
|
2014-07-11 14:48:46 +00:00
|
|
|
from django.utils import timezone
|
2014-07-14 14:56:48 +00:00
|
|
|
from django.utils.functional import cached_property
|
2023-11-17 12:25:13 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2014-07-10 15:19:06 +00:00
|
|
|
|
2015-04-05 10:46:24 +00:00
|
|
|
from orchestra.contrib.orchestration import ServiceBackend
|
2014-07-09 16:17:43 +00:00
|
|
|
|
2015-08-04 09:47:39 +00:00
|
|
|
from . import helpers
|
|
|
|
|
2014-07-09 16:17:43 +00:00
|
|
|
|
|
|
|
class ServiceMonitor(ServiceBackend):
|
|
|
|
TRAFFIC = 'traffic'
|
|
|
|
DISK = 'disk'
|
|
|
|
MEMORY = 'memory'
|
|
|
|
CPU = 'cpu'
|
2014-07-11 21:09:17 +00:00
|
|
|
# TODO UNITS
|
2014-07-16 15:20:16 +00:00
|
|
|
actions = ('monitor', 'exceeded', 'recovery')
|
2014-10-11 16:21:51 +00:00
|
|
|
abstract = True
|
2015-08-04 09:47:39 +00:00
|
|
|
delete_old_equal_values = False
|
|
|
|
monthly_sum_old_values = False
|
2014-07-09 16:17:43 +00:00
|
|
|
|
|
|
|
@classmethod
|
2014-10-21 16:13:18 +00:00
|
|
|
def get_plugins(cls):
|
2014-10-11 16:21:51 +00:00
|
|
|
""" filter controller classes """
|
|
|
|
return [
|
2015-04-14 15:22:01 +00:00
|
|
|
plugin for plugin in cls.plugins if issubclass(plugin, ServiceMonitor)
|
2014-10-11 16:21:51 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_verbose_name(cls):
|
|
|
|
return _("[M] %s") % super(ServiceMonitor, cls).get_verbose_name()
|
2014-07-09 16:17:43 +00:00
|
|
|
|
2014-07-14 14:56:48 +00:00
|
|
|
@cached_property
|
|
|
|
def current_date(self):
|
|
|
|
return timezone.now()
|
|
|
|
|
|
|
|
@cached_property
|
|
|
|
def content_type(self):
|
2016-04-27 12:55:35 +00:00
|
|
|
from django.contrib.contenttypes.models import ContentType
|
2014-07-14 14:56:48 +00:00
|
|
|
app_label, model = self.model.split('.')
|
|
|
|
model = model.lower()
|
2014-07-21 12:20:04 +00:00
|
|
|
return ContentType.objects.get_by_natural_key(app_label, model)
|
2014-07-14 14:56:48 +00:00
|
|
|
|
|
|
|
def get_last_data(self, object_id):
|
2014-07-10 15:19:06 +00:00
|
|
|
from .models import MonitorData
|
|
|
|
try:
|
2014-07-14 14:56:48 +00:00
|
|
|
return MonitorData.objects.filter(content_type=self.content_type,
|
2015-04-27 12:24:17 +00:00
|
|
|
monitor=self.get_name(), object_id=object_id).latest()
|
2014-07-10 15:19:06 +00:00
|
|
|
except MonitorData.DoesNotExist:
|
2014-07-14 14:56:48 +00:00
|
|
|
return None
|
|
|
|
|
|
|
|
def get_last_date(self, object_id):
|
|
|
|
data = self.get_last_data(object_id)
|
|
|
|
if data is None:
|
|
|
|
return self.current_date - datetime.timedelta(days=1)
|
2014-10-27 13:29:02 +00:00
|
|
|
return data.created_at
|
2014-07-10 15:19:06 +00:00
|
|
|
|
2014-07-16 15:20:16 +00:00
|
|
|
def process(self, line):
|
2015-08-05 22:58:35 +00:00
|
|
|
""" line -> object_id, value, state"""
|
|
|
|
result = line.split()
|
|
|
|
if len(result) != 2:
|
|
|
|
cls_name = self.__class__.__name__
|
|
|
|
raise ValueError("%s expected '<id> <value>' got '%s'" % (cls_name, line))
|
|
|
|
# State is None, unless your monitor needs to keep track of it
|
|
|
|
result.append(None)
|
|
|
|
return result
|
2014-07-16 15:20:16 +00:00
|
|
|
|
2014-07-10 15:19:06 +00:00
|
|
|
def store(self, log):
|
2014-09-22 15:59:53 +00:00
|
|
|
""" stores monitored values from stdout """
|
2016-04-27 12:55:35 +00:00
|
|
|
from django.contrib.contenttypes.models import ContentType
|
2014-07-10 15:19:06 +00:00
|
|
|
from .models import MonitorData
|
|
|
|
name = self.get_name()
|
|
|
|
app_label, model_name = self.model.split('.')
|
2014-07-21 12:20:04 +00:00
|
|
|
ct = ContentType.objects.get_by_natural_key(app_label, model_name.lower())
|
2014-07-10 15:19:06 +00:00
|
|
|
for line in log.stdout.splitlines():
|
2014-07-09 16:17:43 +00:00
|
|
|
line = line.strip()
|
2015-08-05 22:58:35 +00:00
|
|
|
object_id, value, state = self.process(line)
|
2015-05-10 17:33:36 +00:00
|
|
|
if isinstance(value, bytes):
|
|
|
|
value = value.decode('ascii')
|
2015-08-05 22:58:35 +00:00
|
|
|
if isinstance(state, bytes):
|
|
|
|
state = state.decode('ascii')
|
2015-07-27 12:55:35 +00:00
|
|
|
content_object = ct.get_object_for_this_type(pk=object_id)
|
2015-07-23 12:41:42 +00:00
|
|
|
MonitorData.objects.create(
|
2015-08-05 22:58:35 +00:00
|
|
|
monitor=name, object_id=object_id, content_type=ct, value=value, state=state,
|
2015-07-23 12:41:42 +00:00
|
|
|
created_at=self.current_date, content_object_repr=str(content_object),
|
|
|
|
)
|
2014-07-09 16:17:43 +00:00
|
|
|
|
2015-05-07 14:09:37 +00:00
|
|
|
def execute(self, *args, **kwargs):
|
|
|
|
log = super(ServiceMonitor, self).execute(*args, **kwargs)
|
2016-10-28 10:31:11 +00:00
|
|
|
if log.state == log.SUCCESS:
|
2016-10-25 09:34:33 +00:00
|
|
|
self.store(log)
|
2014-07-09 16:17:43 +00:00
|
|
|
return log
|
2015-08-04 09:47:39 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def aggregate(cls, dataset):
|
|
|
|
if cls.delete_old_equal_values:
|
|
|
|
return helpers.delete_old_equal_values(dataset)
|
|
|
|
elif cls.monthly_sum_old_values:
|
|
|
|
return helpers.monthly_sum_old_values(dataset)
|