19 changed files with 271 additions and 229 deletions
-
6abonapp/locale/ru/LC_MESSAGES/django.po
-
48abonapp/templates/abonapp/charts.html
-
18abonapp/templates/abonapp/ext.htm
-
1abonapp/templates/abonapp/passport_view.html
-
1abonapp/urls_abon.py
-
51abonapp/views.py
-
6agent/netflow/netflow_handler.sh
-
2agent/netflow/start_netflow.sh
-
125agent/netflow/to_mysql.c
-
66agent/netflow/to_mysql.py
-
14static/js/Chart.min.js
-
6statistics/admin.py
-
53statistics/fields.py
-
18statistics/migrations/0002_delete_statelem.py
-
45statistics/models.py
-
12systemd_units/djing_rotate.service
-
11systemd_units/djing_rotate.timer
-
15taskapp/templates/taskapp/add_edit_task.html
-
2templates/all_base.html
@ -0,0 +1,48 @@ |
|||
{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} |
|||
{% load i18n %} |
|||
{% block content %} |
|||
|
|||
<div class="row"> |
|||
<div class="col-sm-12"> |
|||
<div class="panel panel-default"> |
|||
<div class="panel-heading"> |
|||
<h3 class="panel-title">График использования</h3> |
|||
</div> |
|||
<div class="panel-body"> |
|||
<canvas id="netChart" width="300" height="100"></canvas> |
|||
<script type="text/javascript"> |
|||
var myChart = new Chart('netChart', { |
|||
type: 'line', |
|||
data: { |
|||
datasets: [{ |
|||
label: 'Траффик абонента', |
|||
data: [{{ charts_data }}], |
|||
borderWidth: 1, |
|||
pointRadius: 1, |
|||
lineTension: 0.1 |
|||
}] |
|||
}, |
|||
options: { |
|||
scales: { |
|||
xAxes: [{ |
|||
type: 'time', |
|||
time: { |
|||
unit: 'hour', |
|||
min: {{ time_min }}, |
|||
max: {{ time_max }}, |
|||
displayFormats: { |
|||
hour: 'HH:MM:SS' |
|||
} |
|||
}, |
|||
position: 'bottom' |
|||
}] |
|||
} |
|||
} |
|||
}); |
|||
</script> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
{% endblock %} |
|||
@ -1,125 +0,0 @@ |
|||
#define _GNU_SOURCE |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <arpa/inet.h> |
|||
#include <string.h> |
|||
#include <stdint.h> |
|||
#include <stdbool.h> |
|||
#include <time.h> |
|||
|
|||
|
|||
#define FLOW_COLS 8 |
|||
#define uint unsigned int |
|||
|
|||
|
|||
uint32_t ip2int(const char* ip) |
|||
{ |
|||
uint32_t res = 0; |
|||
inet_pton(AF_INET, ip, &res); |
|||
return htonl(res); |
|||
} |
|||
|
|||
|
|||
uint str_split(char* str, const char* delimiter, char** pInChunks) |
|||
{ |
|||
char* dat = strtok(str, " "); |
|||
register uint n=0; |
|||
while(dat) |
|||
{ |
|||
pInChunks[n++] = dat; |
|||
dat = strtok(NULL, " "); |
|||
} |
|||
return n; |
|||
} |
|||
|
|||
|
|||
void curtime(char* pInStrTime, const uint maxlen) |
|||
{ |
|||
time_t rawtime; |
|||
time( &rawtime ); |
|||
strftime(pInStrTime, maxlen, "flowstat_%d%m%Y", localtime( &rawtime )); |
|||
} |
|||
|
|||
|
|||
void convert(char* query, char* pInRes) |
|||
{ |
|||
char* chunks[FLOW_COLS] = {NULL}; |
|||
|
|||
int chunk_count = str_split(query, " ", chunks); |
|||
|
|||
if(chunk_count < 7) |
|||
{ |
|||
printf("Too short input line\n"); |
|||
exit(1); |
|||
} |
|||
|
|||
uint32_t src_ip = ip2int(chunks[0]); |
|||
uint32_t dst_ip = ip2int(chunks[1]); |
|||
uint proto = atoi(chunks[2]); |
|||
uint16_t src_port = ip2int(chunks[3]); |
|||
uint16_t dst_port = ip2int(chunks[4]); |
|||
uint octets = atoi(chunks[5]); |
|||
uint packets = atoi(chunks[6]); |
|||
|
|||
sprintf(pInRes, ",(%u,%u,%u,%u,%u,%u,%u)\0", |
|||
src_ip, dst_ip, proto, src_port, dst_port, octets, packets); |
|||
} |
|||
|
|||
|
|||
int main() |
|||
{ |
|||
char buf_result_convert[0xff] = {0}; |
|||
FILE* f = stdin; |
|||
char* input_line = malloc(0xff); |
|||
size_t input_line_len = 0; |
|||
ssize_t read_len = 0; |
|||
char table_name[19] = {0}; |
|||
|
|||
curtime(table_name, 19); |
|||
|
|||
printf("CREATE TABLE IF NOT EXISTS %s (\n", table_name); |
|||
printf("`id` int(10) AUTO_INCREMENT NOT NULL,\n"); |
|||
printf("`src_ip` INT(10) UNSIGNED NOT NULL,\n"); |
|||
printf("`dst_ip` INT(10) UNSIGNED NOT NULL,\n"); |
|||
printf("`proto` smallint(2) unsigned NOT NULL DEFAULT 0,\n"); |
|||
printf("`src_port` smallint(5) unsigned NOT NULL DEFAULT 0,\n"); |
|||
printf("`dst_port` smallint(5) unsigned NOT NULL DEFAULT 0,\n"); |
|||
printf("`octets` INT unsigned NOT NULL DEFAULT 0,\n"); |
|||
printf("`packets` INT unsigned NOT NULL DEFAULT 0,\n"); |
|||
printf("PRIMARY KEY (`id`)\n"); |
|||
printf(") ENGINE=MyISAM DEFAULT CHARSET=utf8;\n"); |
|||
|
|||
char ins_sql[0xff] = {0}; |
|||
sprintf(ins_sql, "INSERT INTO %s(`src_ip`, `dst_ip`, `proto`, `src_port`, `dst_port`, `octets`, `packets`) VALUES", table_name); |
|||
|
|||
// always none |
|||
read_len = getline(&input_line, &input_line_len, f); |
|||
|
|||
while(true) |
|||
{ |
|||
register uint n=0xfff; |
|||
read_len = getline(&input_line, &input_line_len, f); |
|||
if(read_len <= 0) |
|||
break; |
|||
convert(input_line, buf_result_convert); |
|||
|
|||
printf("%s\n", ins_sql); |
|||
|
|||
// without first comma |
|||
printf("%s\n", buf_result_convert+1); |
|||
|
|||
while(n>0) |
|||
{ |
|||
read_len = getline(&input_line, &input_line_len, f); |
|||
if(read_len <= 0) |
|||
break; |
|||
convert(input_line, buf_result_convert); |
|||
printf("%s\n", buf_result_convert); |
|||
n--; |
|||
} |
|||
putc(';', stdout); |
|||
} |
|||
|
|||
free(input_line); |
|||
return 0; |
|||
} |
|||
@ -1,66 +0,0 @@ |
|||
#!/bin/env python3 |
|||
import sys |
|||
import socket |
|||
import struct |
|||
from re import sub |
|||
from django.utils import timezone |
|||
|
|||
|
|||
def ip2int(strip): |
|||
return struct.unpack("!I", socket.inet_aton(strip))[0] |
|||
|
|||
|
|||
def convert(query): |
|||
dat = sub(r'\s+', ' ', query.strip('\n')).split(' ') |
|||
|
|||
if len(dat) == 1: |
|||
return |
|||
|
|||
src_ip = ip2int(dat[0]) |
|||
dst_ip = ip2int(dat[1]) |
|||
proto = int(dat[2]) |
|||
src_port = int(dat[3]) |
|||
dst_port = int(dat[4]) |
|||
octets = int(dat[5]) |
|||
packets = int(dat[6]) |
|||
|
|||
sql = ",(%d,%d,%d,%d,%d,%d,%d)" % ( |
|||
src_ip, dst_ip, proto, src_port, dst_port, octets, packets |
|||
) |
|||
return sql |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
f = sys.stdin |
|||
table_name = "flowstat_%s" % timezone.now().strftime("%d%m%Y") |
|||
print(("CREATE TABLE IF NOT EXISTS %s (" % table_name)) |
|||
print("`id` int(10) AUTO_INCREMENT NOT NULL,") |
|||
print("`src_ip` INT(10) UNSIGNED NOT NULL,") |
|||
print("`dst_ip` INT(10) UNSIGNED NOT NULL,") |
|||
print("`proto` smallint(2) unsigned NOT NULL DEFAULT 0,") |
|||
print("`src_port` smallint(5) unsigned NOT NULL DEFAULT 0,") |
|||
print("`dst_port` smallint(5) unsigned NOT NULL DEFAULT 0,") |
|||
print("`octets` INT unsigned NOT NULL DEFAULT 0,") |
|||
print("`packets` INT unsigned NOT NULL DEFAULT 0,") |
|||
print("PRIMARY KEY (`id`)") |
|||
print(") ENGINE=MyISAM DEFAULT CHARSET=utf8;") |
|||
ins_sql = r"INSERT INTO %s(`src_ip`, `dst_ip`, `proto`, `src_port`, `dst_port`, `octets`, `packets`) VALUES" % table_name |
|||
|
|||
# always none |
|||
f.readline() |
|||
|
|||
while True: |
|||
n = 0xfff |
|||
rs = convert(f.readline()) |
|||
if not rs: exit() |
|||
# without first comma |
|||
print(ins_sql) |
|||
print((rs[1:])) |
|||
while n > 0: |
|||
rs = convert(f.readline()) |
|||
if not rs: exit() |
|||
print(rs) |
|||
n -= 1 |
|||
print(';') |
|||
|
|||
f.close() |
|||
14
static/js/Chart.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,6 +0,0 @@ |
|||
from django.contrib import admin |
|||
|
|||
from . import models |
|||
|
|||
|
|||
admin.site.register(models.StatElem) |
|||
@ -0,0 +1,53 @@ |
|||
# |
|||
# Get from https://github.com/Niklas9/django-unixdatetimefield |
|||
# |
|||
import datetime |
|||
import time |
|||
|
|||
import django.db.models as models |
|||
|
|||
|
|||
class UnixDateTimeField(models.DateTimeField): |
|||
|
|||
# TODO(niklas9): |
|||
# * should we take care of transforming between time zones in any way here ? |
|||
# * get default datetime format from settings ? |
|||
DEFAULT_DATETIME_FMT = '%Y-%m-%d %H:%M:%S' |
|||
TZ_CONST = '+' |
|||
# TODO(niklas9): |
|||
# * metaclass below just for Django < 1.9, fix a if stmt for it? |
|||
#__metaclass__ = models.SubfieldBase |
|||
description = "Unix timestamp integer to datetime object" |
|||
|
|||
def get_internal_type(self): |
|||
return 'PositiveIntegerField' |
|||
|
|||
def to_python(self, val): |
|||
if val is None or isinstance(val, datetime.datetime): |
|||
return val |
|||
if isinstance(val, datetime.date): |
|||
return datetime.datetime(val.year, val.month, val.day) |
|||
elif self._is_string(val): |
|||
# TODO(niklas9): |
|||
# * not addressing time zone support as todo above for now |
|||
if self.TZ_CONST in val: |
|||
val = val.split(self.TZ_CONST)[0] |
|||
return datetime.datetime.strptime(val, self.DEFAULT_DATETIME_FMT) |
|||
else: |
|||
return datetime.datetime.fromtimestamp(float(val)) |
|||
|
|||
def _is_string(value, val): |
|||
return isinstance(val, str) |
|||
|
|||
def get_db_prep_value(self, val, *args, **kwargs): |
|||
if val is None: |
|||
if self.default == models.fields.NOT_PROVIDED: return None |
|||
return self.default |
|||
return int(time.mktime(val.timetuple())) |
|||
|
|||
def value_to_string(self, obj): |
|||
val = self._get_val_from_obj(obj) |
|||
return self.to_python(val).strftime(self.DEFAULT_DATETIME_FMT) |
|||
|
|||
def from_db_value(self, val, expression, connection, context): |
|||
return self.to_python(val) |
|||
@ -0,0 +1,18 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9 on 2017-04-25 13:27 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('statistics', '0001_initial'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.DeleteModel( |
|||
name='StatElem', |
|||
), |
|||
] |
|||
@ -1,18 +1,47 @@ |
|||
|
|||
|
|||
import math |
|||
from django.db import models |
|||
from django.utils import timezone |
|||
|
|||
from mydefs import MyGenericIPAddressField |
|||
from .fields import UnixDateTimeField |
|||
|
|||
|
|||
class StatElem(models.Model): |
|||
src_ip = MyGenericIPAddressField() |
|||
dst_ip = MyGenericIPAddressField() |
|||
proto = models.PositiveSmallIntegerField(default=0) |
|||
src_port = models.PositiveIntegerField(default=0) |
|||
dst_port = models.PositiveIntegerField(default=0) |
|||
cur_time = UnixDateTimeField(primary_key=True) |
|||
ip = MyGenericIPAddressField() |
|||
octets = models.PositiveIntegerField(default=0) |
|||
packets = models.PositiveIntegerField(default=0) |
|||
|
|||
@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: |
|||
db_table = 'flowstat' |
|||
abstract = True |
|||
|
|||
|
|||
def getModel(): |
|||
|
|||
class DynamicStatElem(StatElem): |
|||
class Meta: |
|||
db_table = 'flowstat_%s' % timezone.now().strftime("%d%m%Y") |
|||
abstract = False |
|||
return DynamicStatElem |
|||
@ -0,0 +1,12 @@ |
|||
[Unit] |
|||
Description=A job for rotate djing netflow data |
|||
|
|||
[Service] |
|||
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/bin" |
|||
Type=oneshot |
|||
ExecStart=/bin/bash -c "kill -HUP `cat /run/flow.pid.6343`" |
|||
User=root |
|||
Group=root |
|||
|
|||
[Install] |
|||
WantedBy=multi-user.target |
|||
@ -0,0 +1,11 @@ |
|||
[Unit] |
|||
Description=Run every one minute rotate flows for djing |
|||
|
|||
[Timer] |
|||
OnCalendar=*-*-* *:*:59 |
|||
Persistent=true |
|||
RandomizedDelaySec=5 |
|||
Unit=djing_rotate.service |
|||
|
|||
[Install] |
|||
WantedBy=timers.target |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue