Openvz traffic0
This commit is contained in:
parent
bc398644b7
commit
121e1a4b1c
|
@ -29,10 +29,12 @@ class MailmanTraffic(ServiceMonitor):
|
|||
"echo %(object_id)s $(( ${SIZE}*${SUBSCRIBERS} ))" % context)
|
||||
|
||||
def get_context(self, mail_list):
|
||||
last_date = timezone.localtime(self.get_last_date(mail_list.pk))
|
||||
current_date = timezone.localtime(self.current_date)
|
||||
return {
|
||||
'mailman_log': settings.LISTS_MAILMAN_POST_LOG_PATH,
|
||||
'list_name': mail_list.name,
|
||||
'object_id': mail_list.pk,
|
||||
'last_date': timezone.localtime(self.get_last_date(mail_list)).strftime("%b %d %H:%M:%S"),
|
||||
'current_date': timezone.localtime(self.get_current_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"),
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.contrib import admin
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from djcelery.humanize import naturaldate
|
||||
|
||||
from orchestra.admin.html import monospace_format
|
||||
from orchestra.admin.utils import link
|
||||
|
@ -30,7 +31,7 @@ class RouteAdmin(admin.ModelAdmin):
|
|||
|
||||
def display_model(self, route):
|
||||
try:
|
||||
return route.backend_class().model
|
||||
return escape(route.backend_class().model)
|
||||
except KeyError:
|
||||
return "<span style='color: red;'>NOT AVAILABLE</span>"
|
||||
display_model.short_description = _("model")
|
||||
|
@ -61,7 +62,9 @@ class BackendOperationInline(admin.TabularInline):
|
|||
try:
|
||||
return link('instance')(self, operation)
|
||||
except:
|
||||
return _("deleted %s %s") % (operation.content_type, operation.object_id)
|
||||
return _("deleted {0} {1}").format(
|
||||
escape(operation.content_type), escape(operation.object_id)
|
||||
)
|
||||
instance_link.allow_tags = True
|
||||
instance_link.short_description = _("Instance")
|
||||
|
||||
|
@ -71,8 +74,8 @@ class BackendOperationInline(admin.TabularInline):
|
|||
|
||||
class BackendLogAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'id', 'backend', 'server_link', 'display_state', 'exit_code', 'created',
|
||||
'execution_time',
|
||||
'id', 'backend', 'server_link', 'display_state', 'exit_code',
|
||||
'display_created', 'execution_time',
|
||||
)
|
||||
list_display_links = ('id', 'backend')
|
||||
list_filter = ('state', 'backend')
|
||||
|
@ -80,14 +83,10 @@ class BackendLogAdmin(admin.ModelAdmin):
|
|||
inlines = [BackendOperationInline]
|
||||
fields = [
|
||||
'backend', 'server', 'state', 'mono_script', 'mono_stdout', 'mono_stderr',
|
||||
'mono_traceback', 'exit_code', 'task_id', 'created', 'last_update',
|
||||
'execution_time'
|
||||
]
|
||||
readonly_fields = [
|
||||
'backend', 'server', 'state', 'mono_script', 'mono_stdout', 'mono_stderr',
|
||||
'mono_traceback', 'exit_code', 'task_id', 'created', 'last_update',
|
||||
'execution_time'
|
||||
'mono_traceback', 'exit_code', 'task_id', 'display_created',
|
||||
'display_last_update', 'execution_time'
|
||||
]
|
||||
readonly_fields = fields
|
||||
|
||||
def server_link(self, log):
|
||||
url = reverse('admin:orchestration_server_change', args=(log.server.pk,))
|
||||
|
@ -118,6 +117,20 @@ class BackendLogAdmin(admin.ModelAdmin):
|
|||
return monospace_format(escape(log.traceback))
|
||||
mono_traceback.short_description = _("traceback")
|
||||
|
||||
def display_last_update(self, log):
|
||||
return '<div title="{0}">{1}</div>'.format(
|
||||
escape(str(log.last_update)), escape(naturaldate(log.last_update)),
|
||||
)
|
||||
display_last_update.short_description = _("last update")
|
||||
display_last_update.allow_tags = True
|
||||
|
||||
def display_created(self, log):
|
||||
return '<div title="{0}">{1}</div>'.format(
|
||||
escape(str(log.created)), escape(naturaldate(log.created)),
|
||||
)
|
||||
display_created.short_description = _("created")
|
||||
display_created.allow_tags = True
|
||||
|
||||
def get_queryset(self, request):
|
||||
""" Order by structured name and imporve performance """
|
||||
qs = super(BackendLogAdmin, self).get_queryset(request)
|
||||
|
|
|
@ -31,7 +31,7 @@ class ServiceBackend(object):
|
|||
|
||||
def __unicode__(self):
|
||||
return type(self).__name__
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self)
|
||||
|
||||
|
|
|
@ -13,14 +13,14 @@ from . import settings
|
|||
|
||||
def BashSSH(backend, log, server, cmds):
|
||||
from .models import BackendLog
|
||||
script = '\n\n'.join(['set -e'] + cmds + ['exit 0'])
|
||||
script = '\n\n'.join(['set -e', 'set -o pipefail'] + cmds + ['exit 0'])
|
||||
script = script.replace('\r', '')
|
||||
log.script = script
|
||||
log.save()
|
||||
|
||||
try:
|
||||
# In order to avoid "Argument list too long" we while generate first a
|
||||
# script file, then scp the escript and safely execute in remote
|
||||
# Avoid "Argument list too long" on large scripts by genereting a file
|
||||
# and scping it to the remote server
|
||||
digest = hashlib.md5(script).hexdigest()
|
||||
path = os.path.join(settings.ORCHESTRATION_TEMP_SCRIPT_PATH, digest)
|
||||
with open(path, 'w') as script_file:
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from django.contrib import admin, messages
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from djcelery.humanize import naturaldate
|
||||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.filters import UsedContentTypeFilter
|
||||
|
@ -100,6 +102,8 @@ def resource_inline_factory(resources):
|
|||
form = ResourceForm
|
||||
formset = ResourceInlineFormSet
|
||||
can_delete = False
|
||||
fields = ('verbose_name', 'used', 'display_last_update', 'allocated',)
|
||||
readonly_fields = ('used', 'display_last_update',)
|
||||
|
||||
class Media:
|
||||
css = {
|
||||
|
@ -109,6 +113,13 @@ def resource_inline_factory(resources):
|
|||
def has_add_permission(self, *args, **kwargs):
|
||||
""" Hidde add another """
|
||||
return False
|
||||
|
||||
def display_last_update(self, log):
|
||||
return '<div title="{0}">{1}</div>'.format(
|
||||
escape(str(log.last_update)), escape(naturaldate(log.last_update)),
|
||||
)
|
||||
display_last_update.short_description = _("last update")
|
||||
display_last_update.allow_tags = True
|
||||
|
||||
return ResourceInline
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ import datetime
|
|||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils import timezone
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from orchestra.apps.orchestration import ServiceBackend
|
||||
from orchestra.utils.functional import cached
|
||||
|
||||
|
||||
class ServiceMonitor(ServiceBackend):
|
||||
|
@ -23,18 +23,29 @@ class ServiceMonitor(ServiceBackend):
|
|||
if backend != ServiceMonitor and ServiceMonitor in backend.__mro__:
|
||||
yield backend
|
||||
|
||||
@cached
|
||||
def get_last_date(self, obj):
|
||||
@cached_property
|
||||
def current_date(self):
|
||||
return timezone.now()
|
||||
|
||||
@cached_property
|
||||
def content_type(self):
|
||||
app_label, model = self.model.split('.')
|
||||
model = model.lower()
|
||||
return ContentType.objects.get(app_label=app_label, model=model)
|
||||
|
||||
def get_last_data(self, object_id):
|
||||
from .models import MonitorData
|
||||
try:
|
||||
ct = ContentType.objects.get_for_model(type(obj))
|
||||
return MonitorData.objects.filter(content_type=ct, object_id=obj.pk).latest().date
|
||||
return MonitorData.objects.filter(content_type=self.content_type,
|
||||
object_id=object_id).latest()
|
||||
except MonitorData.DoesNotExist:
|
||||
return self.get_current_date() - datetime.timedelta(days=1)
|
||||
|
||||
@cached
|
||||
def get_current_date(self):
|
||||
return timezone.now()
|
||||
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)
|
||||
return data.date
|
||||
|
||||
def store(self, log):
|
||||
""" object_id value """
|
||||
|
@ -46,7 +57,7 @@ class ServiceMonitor(ServiceBackend):
|
|||
line = line.strip()
|
||||
object_id, value = line.split()
|
||||
MonitorData.objects.create(monitor=name, object_id=object_id,
|
||||
content_type=ct, value=value, date=self.get_current_date())
|
||||
content_type=ct, value=value, date=self.current_date)
|
||||
|
||||
def execute(self, server):
|
||||
log = super(ServiceMonitor, self).execute(server)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from django import forms
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from djcelery.humanize import naturaldate
|
||||
|
||||
from orchestra.forms.widgets import ShowTextWidget, ReadOnlyWidget
|
||||
|
||||
|
@ -9,8 +11,6 @@ class ResourceForm(forms.ModelForm):
|
|||
required=False)
|
||||
used = forms.IntegerField(label=_("Used"), widget=ShowTextWidget(),
|
||||
required=False)
|
||||
last_update = forms.DateTimeField(label=_("Last update"), widget=ShowTextWidget(),
|
||||
required=False)
|
||||
allocated = forms.IntegerField(label=_("Allocated"))
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -101,10 +101,12 @@ class FTPTraffic(ServiceMonitor):
|
|||
' | xargs echo %(object_id)s """ % context)
|
||||
|
||||
def get_context(self, user):
|
||||
last_date = timezone.localtime(self.get_last_date(user.pk))
|
||||
current_date = timezone.localtime(self.current_date)
|
||||
return {
|
||||
'log_file': settings.USERS_FTP_LOG_PATH,
|
||||
'last_date': timezone.localtime(self.get_last_date(user)).strftime("%Y%m%d%H%M%S"),
|
||||
'current_date': timezone.localtime(self.get_current_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,
|
||||
'username': user.username,
|
||||
}
|
||||
|
|
|
@ -3,18 +3,32 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from orchestra.apps.resources import ServiceMonitor
|
||||
|
||||
|
||||
class OpenVZDisk(ServiceMonitor):
|
||||
model = 'vps.VPS'
|
||||
resource = ServiceMonitor.DISK
|
||||
|
||||
|
||||
class OpenVZMemory(ServiceMonitor):
|
||||
model = 'vps.VPS'
|
||||
resource = ServiceMonitor.MEMORY
|
||||
|
||||
|
||||
class OpenVZTraffic(ServiceMonitor):
|
||||
model = 'vps.VPS'
|
||||
resource = ServiceMonitor.TRAFFIC
|
||||
|
||||
|
||||
|
||||
def process(self, line, obj):
|
||||
""" diff with last stored value """
|
||||
object_id, value = line.split()
|
||||
last = self.get_last_data(object_id)
|
||||
if not last or last.value > value:
|
||||
return object_id, value
|
||||
return object_id, value-last.value
|
||||
|
||||
def monitor(self, container):
|
||||
""" Get OpenVZ container traffic on a Proxmox +2.0 cluster """
|
||||
context = self.get_context(container)
|
||||
self.append(
|
||||
"CONF=$(grep -r 'HOSTNAME=\"%(hostname)s\"' /etc/pve/nodes/*/openvz/*.conf)" % context)
|
||||
self.append('NODE=$(echo "${CONF}" | cut -d"/" -f5)')
|
||||
self.append('CTID=$(echo "${CONF}" | cut -d"/" -f7 | cur -d"\." -f1)')
|
||||
self.append(
|
||||
"ssh root@${NODE} vzctl exec ${CTID} cat /proc/net/dev \\\n"
|
||||
" | grep venet0 \\\n"
|
||||
" | awk -F: '{print $2}' \\\n"
|
||||
" | awk '{print $1+$9}'")
|
||||
|
||||
def get_context(self, container):
|
||||
return {
|
||||
'hostname': container.hostname,
|
||||
}
|
||||
|
|
|
@ -219,9 +219,11 @@ class Apache2Traffic(ServiceMonitor):
|
|||
}' %(log_file)s || echo 0; } | xargs echo %(object_id)s """ % context)
|
||||
|
||||
def get_context(self, site):
|
||||
last_date = timezone.localtime(self.get_last_date(site.pk))
|
||||
current_date = timezone.localtime(self.current_date)
|
||||
return {
|
||||
'log_file': os.path.join(settings.WEBSITES_BASE_APACHE_LOGS, site.unique_name),
|
||||
'last_date': timezone.localtime(self.get_last_date(site)).strftime("%Y%m%d%H%M%S"),
|
||||
'current_date': timezone.localtime(self.get_current_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,
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from django.utils.timesince import timesince as django_timesince
|
||||
from django.utils.timezone import is_aware, utc
|
||||
|
||||
|
||||
# TODO deprecate in favour of celery timesince
|
||||
def timesince(d, now=None, reversed=False):
|
||||
""" Hack to provide second precision under 2 minutes """
|
||||
if not now:
|
||||
now = datetime.now(utc if is_aware(d) else None)
|
||||
|
||||
delta = (d - now) if reversed else (now - d)
|
||||
s = django_timesince(d, now=now, reversed=reversed)
|
||||
|
||||
if len(s.split(' ')) is 2:
|
||||
count, name = s.split(' ')
|
||||
if name in ['minutes', 'minute']:
|
||||
seconds = delta.seconds % 60
|
||||
extension = '%(number)d %(type)s' % {'number': seconds, 'type': 'seconds'}
|
||||
if int(count) is 0:
|
||||
return extension
|
||||
elif int(count) < 2:
|
||||
s += ', %s' % extension
|
||||
return s
|
||||
|
||||
|
||||
def timeuntil(d, now=None):
|
||||
"""
|
||||
Like timesince, but returns a string measuring the time until
|
||||
the given time.
|
||||
"""
|
||||
return timesince(d, now, reversed=True)
|
Loading…
Reference in a new issue