You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

101 lines
3.3 KiB

import math
from datetime import datetime, timedelta, date, time
from django.db import models, ProgrammingError
from django.utils import timezone
from mydefs import MyGenericIPAddressField
from .fields import UnixDateTimeField
from mydefs import LogicError
class StatManager(models.Manager):
def traffic_by_ip(self, ip):
try:
traf = self.order_by('-cur_time').filter(ip=ip, octets__gt=524288)[0]
now = datetime.now()
if traf.cur_time < now - timedelta(minutes=55):
return False, traf
else:
return True, traf
except IndexError:
return False, None
except ProgrammingError as e:
raise LogicError(e)
def chart(self, ip_addr, count_of_parts=12):
def byte_to_mbit(x):
return ((x/60)*8)/2**20
def split_list(lst, chunk_count):
chunk_size = len(lst) // chunk_count
return [lst[i:i+chunk_size] for i in range(0, len(lst), chunk_size)]
def avarage(elements):
return sum(elements) / len(elements)
charts_data = self.filter(ip=ip_addr)
charts_times = [cd.cur_time.timestamp()*1000 for cd in charts_data]
charts_octets = [byte_to_mbit(cd.octets) for cd in charts_data]
if len(charts_octets) > 0 and len(charts_octets) == len(charts_times):
charts_octets = split_list(charts_octets, count_of_parts)
charts_octets = [avarage(c) for c in charts_octets]
charts_times = split_list(charts_times, count_of_parts)
charts_times = [avarage(t) for t in charts_times]
charts_data = map(lambda x, y: (x, y), charts_times, charts_octets)
charts_data = ["{x: new Date(%d), y: %.2f}" % (cd[0], cd[1]) for cd in charts_data]
midnight = datetime.combine(date.today(), time.min)
charts_data.append("{x:new Date(%d),y:0}" % (int((midnight + timedelta(days=1)).timestamp()) * 1000))
return charts_data
else:
return
class StatElem(models.Model):
cur_time = UnixDateTimeField(primary_key=True)
ip = MyGenericIPAddressField()
octets = models.PositiveIntegerField(default=0)
packets = models.PositiveIntegerField(default=0)
objects = StatManager()
def save(self, *args, **kwargs):
return
def delete(self, *args, **kwargs):
return
@staticmethod
def percentile(N, percent, key=lambda x:x):
"""
Find the percentile of a list of values.
@parameter N - is a list of values. Note N MUST BE already sorted.
@parameter percent - a float value from 0.0 to 1.0.
@parameter key - optional key function to compute value from each element of N.
@return - the percentile of the values
"""
if not N:
return None
k = (len(N)-1) * percent
f = math.floor(k)
c = math.ceil(k)
if f == c:
return key(N[int(k)])
d0 = key(N[int(f)]) * (c-k)
d1 = key(N[int(c)]) * (k-f)
return d0+d1
class Meta:
abstract = True
def getModel():
class DynamicStatElem(StatElem):
class Meta:
db_table = 'flowstat_%s' % datetime.now().strftime("%d%m%Y")
abstract = False
return DynamicStatElem