Improved monitoring backends

This commit is contained in:
Marc 2014-07-25 15:17:50 +00:00
parent 800ee58d2d
commit 72ef63ffdf
11 changed files with 139 additions and 101 deletions

View File

@ -51,7 +51,6 @@ Remember that, as always with QuerySets, any subsequent chained methods which im
* create custom field that returns backend python objects * create custom field that returns backend python objects
* Timezone awareness on monitoring system (reading server-side logs with different TZ than orchestra) maybe a settings value? (use UTC internally, timezone.localtime() when interacting with servers) * Timezone awareness on monitoring system (reading server-side logs with different TZ than orchestra) maybe a settings value? (use UTC internally, timezone.localtime() when interacting with servers)
* Resource metric: KB MB B? RESOURCE UNIT!! forms and serializers
* EMAIL backend operations which contain stderr messages (because under certain failures status code is still 0) * EMAIL backend operations which contain stderr messages (because under certain failures status code is still 0)
@ -72,3 +71,4 @@ at + clock time, midnight, noon- At 3:30 p.m., At 4:01, At noon
* backend logs with hal logo * backend logs with hal logo
* Use logs for storing monitored values

View File

@ -1,3 +1,5 @@
import textwrap
from django.template import Template, Context from django.template import Template, Context
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -17,24 +19,35 @@ class MailmanTraffic(ServiceMonitor):
model = 'lists.List' model = 'lists.List'
resource = ServiceMonitor.TRAFFIC resource = ServiceMonitor.TRAFFIC
def prepare(self):
current_date = timezone.localtime(self.current_date)
current_date = current_date.strftime("%b %d %H:%M:%S")
self.append(textwrap.dedent("""
function monitor () {
OBJECT_ID=$1
LAST_DATE=$2
LIST_NAME="$3"
MAILMAN_LOG="$4"
SUBSCRIBERS=$(list_members ${LIST_NAME} | wc -l)
SIZE=$(grep ' post to ${LIST_NAME} ' "${MAILMAN_LOG}" \
| awk '\"$LAST_DATE\"<=$0 && $0<=\"%s\"' \
| sed 's/.*size=\([0-9]*\).*/\\1/' \
| tr '\\n' '+' \
| xargs -i echo {} )
echo ${OBJECT_ID} $(( ${SIZE}*${SUBSCRIBERS} ))
}""" % current_date))
def monitor(self, mail_list): def monitor(self, mail_list):
context = self.get_context(mail_list) context = self.get_context(mail_list)
self.append( self.append(
"SUBSCRIBERS=$(list_members %(list_name)s | wc -l)\n" 'monitor %(object_id)i %(last_date)s "%(list_name)s" "%(log_file)s"' % context)
"SIZE=$(grep ' post to %(list_name)s ' %(mailman_log)s \\\n"
" | awk '\"%(last_date)s\"<=$0 && $0<=\"%(current_date)s\"' \\\n"
" | sed 's/.*size=\([0-9]*\).*/\\1/' \\\n"
" | tr '\\n' '+' \\\n"
" | xargs -i echo {}0 )\n"
"echo %(object_id)s $(( ${SIZE}*${SUBSCRIBERS} ))" % context)
def get_context(self, mail_list): def get_context(self, mail_list):
last_date = timezone.localtime(self.get_last_date(mail_list.pk)) last_date = timezone.localtime(self.get_last_date(mail_list.pk))
current_date = timezone.localtime(self.current_date)
return { return {
'mailman_log': settings.LISTS_MAILMAN_POST_LOG_PATH, 'mailman_log': settings.LISTS_MAILMAN_POST_LOG_PATH,
'list_name': mail_list.name, 'list_name': mail_list.name,
'object_id': mail_list.pk, 'object_id': mail_list.pk,
'last_date': last_date.strftime("%b %d %H:%M:%S"), 'last_date': last_date.strftime("%b %d %H:%M:%S"),
'current_date': current_date.strftime("%b %d %H:%M:%S"),
} }

View File

@ -81,8 +81,8 @@ class BackendLogAdmin(admin.ModelAdmin):
date_hierarchy = 'last_update' date_hierarchy = 'last_update'
inlines = [BackendOperationInline] inlines = [BackendOperationInline]
fields = [ fields = [
'backend', 'server', 'state', 'mono_script', 'mono_stdout', 'mono_stderr', 'backend', 'server_link', 'state', 'mono_script', 'mono_stdout',
'mono_traceback', 'exit_code', 'task_id', 'display_created', 'mono_stderr', 'mono_traceback', 'exit_code', 'task_id', 'display_created',
'display_last_update', 'execution_time' 'display_last_update', 'execution_time'
] ]
readonly_fields = fields readonly_fields = fields

View File

@ -97,6 +97,10 @@ class ServiceBackend(plugins.Plugin):
else: else:
self.cmds[-1][1].append(cmd) self.cmds[-1][1].append(cmd)
def prepare(self):
""" hook for executing something at the beging """
pass
def commit(self): def commit(self):
""" """
apply the configuration, usually reloading a service apply the configuration, usually reloading a service

View File

@ -38,11 +38,11 @@ def execute(operations):
cache = {} cache = {}
for operation in operations: for operation in operations:
servers = router.get_servers(operation, cache=cache) servers = router.get_servers(operation, cache=cache)
print cache
for server in servers: for server in servers:
key = (server, operation.backend) key = (server, operation.backend)
if key not in scripts: if key not in scripts:
scripts[key] = (operation.backend(), [operation]) scripts[key] = (operation.backend(), [operation])
scripts[key][0].prepare()
else: else:
scripts[key][1].append(operation) scripts[key][1].append(operation)
method = getattr(scripts[key][0], operation.action) method = getattr(scripts[key][0], operation.action)

View File

@ -60,7 +60,7 @@ class BackendLog(models.Model):
traceback = models.TextField(_("traceback")) traceback = models.TextField(_("traceback"))
exit_code = models.IntegerField(_("exit code"), null=True) exit_code = models.IntegerField(_("exit code"), null=True)
task_id = models.CharField(_("task ID"), max_length=36, unique=True, null=True, task_id = models.CharField(_("task ID"), max_length=36, unique=True, null=True,
help_text="Celery task ID") help_text="Celery task ID when used as execution backend")
created = models.DateTimeField(_("created"), auto_now_add=True) created = models.DateTimeField(_("created"), auto_now_add=True)
last_update = models.DateTimeField(_("last update"), auto_now=True) last_update = models.DateTimeField(_("last update"), auto_now=True)

View File

@ -173,6 +173,7 @@ def create_resource_relation():
return data return data
def __get__(self, obj, cls): def __get__(self, obj, cls):
""" proxy handled object """
self.obj = obj self.obj = obj
return self return self

View File

@ -25,8 +25,8 @@ class ResourceSerializer(serializers.ModelSerializer):
if not running_syncdb(): if not running_syncdb():
# TODO why this is even loaded during syncdb? # TODO why this is even loaded during syncdb?
for resources in Resource.group_by_content_type(): for ct, resources in Resource.objects.group_by('content_type'):
model = resources[0].content_type.model_class() model = ct.model_class()
try: try:
router.insert(model, 'resources', ResourceSerializer, required=False, many=True) router.insert(model, 'resources', ResourceSerializer, required=False, many=True)
except KeyError: except KeyError:

View File

@ -1,3 +1,5 @@
import textwrap
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -15,16 +17,16 @@ class SystemUserBackend(ServiceController):
def save(self, user): def save(self, user):
context = self.get_context(user) context = self.get_context(user)
if user.is_main: if user.is_main:
self.append( self.append(textwrap.dedent("""
"if [[ $( id %(username)s ) ]]; then \n" if [[ $( id %(username)s ) ]]; then
" usermod --password '%(password)s' %(username)s \n" usermod --password '%(password)s' %(username)s
"else \n" else
" useradd %(username)s --password '%(password)s' \\\n" useradd %(username)s --password '%(password)s' \
" --shell /bin/false \n" --shell /bin/false
"fi" % context fi
) mkdir -p %(home)s
self.append("mkdir -p %(home)s" % context) chown %(username)s.%(username)s %(home)s""" % context
self.append("chown %(username)s.%(username)s %(home)s" % context) ))
else: else:
self.delete(user) self.delete(user)
@ -63,14 +65,21 @@ class FTPTraffic(ServiceMonitor):
resource = ServiceMonitor.TRAFFIC resource = ServiceMonitor.TRAFFIC
verbose_name = _('FTP traffic') verbose_name = _('FTP traffic')
def monitor(self, user): def prepare(self):
context = self.get_context(user) current_date = timezone.localtime(self.current_date)
self.append(""" current_date = current_date.strftime("%Y%m%d%H%M%S")
grep "UPLOAD\|DOWNLOAD" %(log_file)s | grep " \\[%(username)s\\] " | awk ' self.append(textwrap.dedent("""
function monitor () {
OBJECT_ID=$1
INI_DATE=$2
USERNAME="$3"
LOG_FILE="$4"
grep "UPLOAD\|DOWNLOAD" "${LOG_FILE}" \
| grep " \\[${USERNAME}\\] " \
| awk -v ini="${INI_DATE}" '
BEGIN { BEGIN {
ini = "%(last_date)s" end = "%s"
end = "%(current_date)s" sum = 0
months["Jan"] = "01" months["Jan"] = "01"
months["Feb"] = "02" months["Feb"] = "02"
months["Mar"] = "03" months["Mar"] = "03"
@ -93,20 +102,21 @@ class FTPTraffic(ServiceMonitor):
split(l[3], b, " ") split(l[3], b, " ")
sum += b[1] sum += b[1]
} END { } END {
if ( sum )
print sum print sum
else
print 0
} }
' | xargs echo %(object_id)s """ % context) ' | xargs echo ${OBJECT_ID}
}""" % current_date))
def monitor(self, user):
context = self.get_context(user)
self.append(
'monitor %(object_id)i %(last_date)s "%(username)s" "%(log_file)s"' % context)
def get_context(self, user): def get_context(self, user):
last_date = timezone.localtime(self.get_last_date(user.pk)) last_date = timezone.localtime(self.get_last_date(user.pk))
current_date = timezone.localtime(self.current_date)
return { return {
'log_file': settings.USERS_FTP_LOG_PATH, 'log_file': settings.USERS_FTP_LOG_PATH,
'last_date': last_date.strftime("%Y%m%d%H%M%S"), 'last_date': last_date.strftime("%Y%m%d%H%M%S"),
'current_date': current_date.strftime("%Y%m%d%H%M%S"),
'object_id': user.pk, 'object_id': user.pk,
'username': user.username, 'username': user.username,
} }

View File

@ -1,3 +1,4 @@
import textwrap
import os import os
from django.template import Template, Context from django.template import Template, Context
@ -182,14 +183,19 @@ class Apache2Traffic(ServiceMonitor):
resource = ServiceMonitor.TRAFFIC resource = ServiceMonitor.TRAFFIC
verbose_name = _("Apache 2 Traffic") verbose_name = _("Apache 2 Traffic")
def monitor(self, site): def prepare(self):
context = self.get_context(site) current_date = timezone.localtime(self.current_date)
self.append("""{ current_date = current_date.strftime("%Y%m%d%H%M%S")
awk 'BEGIN { self.append(textwrap.dedent("""
ini = "%(last_date)s" function monitor () {
end = "%(current_date)s" OBJECT_ID=$1
INI_DATE=$2
LOG_FILE="$3"
{
awk -v ini="${INI_DATE}" '
BEGIN {
end = "%s"
sum = 0 sum = 0
months["Jan"] = "01"; months["Jan"] = "01";
months["Feb"] = "02"; months["Feb"] = "02";
months["Mar"] = "03"; months["Mar"] = "03";
@ -216,14 +222,18 @@ class Apache2Traffic(ServiceMonitor):
sum += $NF sum += $NF
} END { } END {
print sum print sum
}' %(log_file)s || echo 0; } | xargs echo %(object_id)s """ % context) }' "${LOG_FILE}" || echo 0
} | xargs echo ${OBJECT_ID}
}""" % current_date))
def monitor(self, site):
context = self.get_context(site)
self.append('monitor %(object_id)i %(last_date)s "%(log_file)s"' % context)
def get_context(self, site): def get_context(self, site):
last_date = timezone.localtime(self.get_last_date(site.pk)) last_date = timezone.localtime(self.get_last_date(site.pk))
current_date = timezone.localtime(self.current_date)
return { return {
'log_file': os.path.join(settings.WEBSITES_BASE_APACHE_LOGS, site.unique_name), 'log_file': os.path.join(settings.WEBSITES_BASE_APACHE_LOGS, site.unique_name),
'last_date': last_date.strftime("%Y%m%d%H%M%S"), 'last_date': last_date.strftime("%Y%m%d%H%M%S"),
'current_date': current_date.strftime("%Y%m%d%H%M%S"),
'object_id': site.pk, 'object_id': site.pk,
} }

View File

@ -118,8 +118,8 @@ AUTHENTICATION_BACKENDS = [
] ]
# Email config #TODO Email config
EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend' #EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend'
################################# #################################