Skip to content
Snippets Groups Projects
Commit 9d2a36fd authored by David Schmitz's avatar David Schmitz
Browse files

snmp: work on start/stop of statistics per rule

parent 3af53b01
No related branches found
No related tags found
No related merge requests found
...@@ -23,6 +23,7 @@ from django.conf import settings ...@@ -23,6 +23,7 @@ from django.conf import settings
from datetime import datetime, timedelta from datetime import datetime, timedelta
import json import json
import os import os
import time
from flowspec.models import Route from flowspec.models import Route
from flowspec.junos import create_junos_name from flowspec.junos import create_junos_name
...@@ -131,6 +132,36 @@ def get_snmp_stats(): ...@@ -131,6 +132,36 @@ def get_snmp_stats():
return results return results
def lock_history_file(wait=1):
first=1
success=0
while first or wait:
first=0
try:
os.mkdir(settings.SNMP_TEMP_FILE+".lock") # TODO use regular file than dir
logger.info("lock_history_file(): creating lock dir succeeded")
success=1
return success
except OSError, e:
logger.error("lock_history_file(): creating lock dir failed: OSError: "+str(e))
success=0
except Exception as e:
logger.error("lock_history_file(): lock already exists")
logger.error("lock_history_file(): creating lock dir failed: "+str(e))
success=0
if not success and wait:
time.sleep(1)
return success;
def unlock_history_file():
try:
os.rmdir(settings.SNMP_TEMP_FILE+".lock") # TODO use regular file than dir
logger.info("unlock_history_file(): succeeded")
return 1
except Exception as e:
logger.info("unlock_history_file(): failed "+str(e))
return 0
def load_history(): def load_history():
history = {} history = {}
try: try:
...@@ -165,15 +196,29 @@ def helper_rule_ts_parse(ts_string): ...@@ -165,15 +196,29 @@ def helper_rule_ts_parse(ts_string):
return ts return ts
def poll_snmp_statistics(): def poll_snmp_statistics():
logger.info("Polling SNMP statistics.") logger.info("poll_snmp_statistics(): Polling SNMP statistics.")
# load history
history = load_history()
# get new data # first, determine current ts, before calling get_snmp_stats
now = datetime.now() now = datetime.now()
nowstr = now.isoformat() nowstr = now.isoformat()
# get new data
try:
logger.info("poll_snmp_statistics(): snmpstats: nowstr="+str(nowstr))
newdata = get_snmp_stats()
except Exception as e:
logger.info("poll_snmp_statistics(): get_snmp_stats failed: "+str(e))
return False
# lock history file access
success = lock_history_file(1)
if not success:
logger.error("poll_snmp_statistics(): locking history file failed, aborting");
return False
# load history
history = load_history()
zero_measurement = { "bytes" : 0, "packets" : 0 } zero_measurement = { "bytes" : 0, "packets" : 0 }
null_measurement = 0 null_measurement = 0
null_measurement_missing = 1 null_measurement_missing = 1
...@@ -181,20 +226,22 @@ def poll_snmp_statistics(): ...@@ -181,20 +226,22 @@ def poll_snmp_statistics():
try: try:
last_poll_no_time = history['_last_poll_no_time'] last_poll_no_time = history['_last_poll_no_time']
except Exception as e: except Exception as e:
logger.info("got exception while trying to access history[_last_poll_time]: "+str(e)) logger.info("poll_snmp_statistics(): got exception while trying to access history[_last_poll_time]: "+str(e))
last_poll_no_time=None last_poll_no_time=None
logger.info("poll_snmp_statistics(): snmpstats: last_poll_no_time="+str(last_poll_no_time))
history['_last_poll_no_time']=nowstr history['_last_poll_no_time']=nowstr
try: try:
history_per_rule = history['_per_rule'] history_per_rule = history['_per_rule']
except Exception as e: except Exception as e:
history_per_rule = {} history_per_rule = {}
# do actual update
try: try:
logger.info("snmpstats: nowstr="+str(nowstr)+", last_poll_no_time="+str(last_poll_no_time)) logger.info("poll_snmp_statistics(): before store: snmpstats: nowstr="+str(nowstr)+", last_poll_no_time="+str(last_poll_no_time))
newdata = get_snmp_stats() #newdata = get_snmp_stats()
# update history # proper update history
samplecount = settings.SNMP_MAX_SAMPLECOUNT samplecount = settings.SNMP_MAX_SAMPLECOUNT
for rule in newdata: for rule in newdata:
counter = {"ts": nowstr, "value": newdata[rule]} counter = {"ts": nowstr, "value": newdata[rule]}
...@@ -214,7 +261,7 @@ def poll_snmp_statistics(): ...@@ -214,7 +261,7 @@ def poll_snmp_statistics():
if ts!=None and (now - ts).total_seconds() >= settings.SNMP_REMOVE_RULES_AFTER: if ts!=None and (now - ts).total_seconds() >= settings.SNMP_REMOVE_RULES_AFTER:
toremove.append(rule) toremove.append(rule)
except Exception as e: except Exception as e:
logger.info("snmpstats: old rules remove loop: rule="+str(rule)+" got exception "+str(e)) logger.info("poll_snmp_statistics(): old rules remove loop: rule="+str(rule)+" got exception "+str(e))
for rule in toremove: for rule in toremove:
history.pop(rule, None) history.pop(rule, None)
...@@ -251,7 +298,7 @@ def poll_snmp_statistics(): ...@@ -251,7 +298,7 @@ def poll_snmp_statistics():
counter = {"ts": nowstr, "value": newdata[flowspec_params_str]} counter = {"ts": nowstr, "value": newdata[flowspec_params_str]}
counter_is_null = False counter_is_null = False
except Exception as e: except Exception as e:
logger.info("snmpstats: STATISTICS_PER_RULE: exception: rule_id="+str(rule_id)+" : "+str(e)) logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: exception: rule_id="+str(rule_id)+" : "+str(e))
counter = {"ts": nowstr, "value": null_measurement_missing } counter = {"ts": nowstr, "value": null_measurement_missing }
counter_is_null = True counter_is_null = True
else: else:
...@@ -261,10 +308,10 @@ def poll_snmp_statistics(): ...@@ -261,10 +308,10 @@ def poll_snmp_statistics():
try: try:
if not rule_id in history_per_rule: if not rule_id in history_per_rule:
if rule_status!="ACTIVE": if rule_status!="ACTIVE":
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case notexisting inactive") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case notexisting inactive")
#history_per_rule[rule_id] = [counter] #history_per_rule[rule_id] = [counter]
else: else:
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case notexisting active") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case notexisting active")
if counter_is_null: if counter_is_null:
history_per_rule[rule_id] = [counter_zero] history_per_rule[rule_id] = [counter_zero]
else: else:
...@@ -272,7 +319,7 @@ def poll_snmp_statistics(): ...@@ -272,7 +319,7 @@ def poll_snmp_statistics():
else: else:
rec = history_per_rule[rule_id] rec = history_per_rule[rule_id]
if rule_status!="ACTIVE": if rule_status!="ACTIVE":
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing inactive") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing inactive")
rec.insert(0, counter) rec.insert(0, counter)
else: else:
last_value = rec[0] last_value = rec[0]
...@@ -282,20 +329,20 @@ def poll_snmp_statistics(): ...@@ -282,20 +329,20 @@ def poll_snmp_statistics():
else: else:
last_ts = helper_stats_store_parse_ts(last_value['ts']) last_ts = helper_stats_store_parse_ts(last_value['ts'])
rule_newer_than_last = last_ts==None or rule_last_updated > last_ts rule_newer_than_last = last_ts==None or rule_last_updated > last_ts
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" rule_last_updated="+str(rule_last_updated)+", last_value="+str(last_value)) logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" rule_last_updated="+str(rule_last_updated)+", last_value="+str(last_value))
if last_is_null and rule_newer_than_last: if last_is_null and rule_newer_than_last:
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 11") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 11")
if counter_is_null: if counter_is_null:
rec.insert(0, counter_zero) rec.insert(0, counter_zero)
else: else:
rec.insert(0, counter_zero) rec.insert(0, counter_zero)
rec.insert(0, counter) rec.insert(0, counter)
elif last_is_null and not rule_newer_than_last: elif last_is_null and not rule_newer_than_last:
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 10") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 10")
rec.insert(0, counter_zero) rec.insert(0, counter_zero)
rec.insert(0, counter) rec.insert(0, counter)
elif not last_is_null and rule_newer_than_last: elif not last_is_null and rule_newer_than_last:
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 01") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 01")
if counter_is_null: if counter_is_null:
rec.insert(0, counter_null) rec.insert(0, counter_null)
rec.insert(0, counter_zero) rec.insert(0, counter_zero)
...@@ -304,10 +351,10 @@ def poll_snmp_statistics(): ...@@ -304,10 +351,10 @@ def poll_snmp_statistics():
rec.insert(0, counter_zero) rec.insert(0, counter_zero)
rec.insert(0, counter) rec.insert(0, counter)
elif not last_is_null and not rule_newer_than_last: elif not last_is_null and not rule_newer_than_last:
logger.info("snmpstats: STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 00") logger.info("poll_snmp_statistics(): STATISTICS_PER_RULE: rule_id="+str(rule_id)+" case existing active 00")
rec.insert(0, counter) rec.insert(0, counter)
rec = rec[:samplecount] history_per_rule[rule_id] = rec[:samplecount]
except Exception as e: except Exception as e:
logger.info("snmpstats: 2 STATISTICS_PER_RULE: exception: "+str(e)) logger.info("snmpstats: 2 STATISTICS_PER_RULE: exception: "+str(e))
...@@ -315,16 +362,28 @@ def poll_snmp_statistics(): ...@@ -315,16 +362,28 @@ def poll_snmp_statistics():
# store updated history # store updated history
save_history(history, nowstr) save_history(history, nowstr)
logger.info("poll_snmp_statistics(): Polling finished.")
logger.info("Polling finished.")
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
logger.error("Polling failed.") logger.error("poll_snmp_statistics(): Polling failed. exception: "+str(e))
logger.info("Polling end: last_poll_no_time="+str(last_poll_no_time))
unlock_history_file()
logger.info("poll_snmp_statistics(): Polling end: last_poll_no_time="+str(last_poll_no_time))
def add_initial_zero_value(rule_id, zero_or_null=True): def add_initial_zero_value(rule_id, zero_or_null=True):
logger.info("add_initial_zero_value(): rule_id="+str(rule_id)) logger.info("add_initial_zero_value(): rule_id="+str(rule_id))
# get new data
now = datetime.now()
nowstr = now.isoformat()
# lock history file access
success = lock_history_file(1)
if not success:
logger.error("add_initial_zero_value(): locking history file failed, aborting");
return False
# load history # load history
history = load_history() history = load_history()
...@@ -333,9 +392,6 @@ def add_initial_zero_value(rule_id, zero_or_null=True): ...@@ -333,9 +392,6 @@ def add_initial_zero_value(rule_id, zero_or_null=True):
except Exception as e: except Exception as e:
history_per_rule = {} history_per_rule = {}
# get new data
now = datetime.now()
nowstr = now.isoformat()
if zero_or_null: if zero_or_null:
zero_measurement = { "bytes" : 0, "packets" : 0 } zero_measurement = { "bytes" : 0, "packets" : 0 }
...@@ -346,19 +402,24 @@ def add_initial_zero_value(rule_id, zero_or_null=True): ...@@ -346,19 +402,24 @@ def add_initial_zero_value(rule_id, zero_or_null=True):
samplecount = settings.SNMP_MAX_SAMPLECOUNT samplecount = settings.SNMP_MAX_SAMPLECOUNT
# TODO: check and if needed remove previous null_measurement
try: try:
if rule_id in history_per_rule: if rule_id in history_per_rule:
history_per_rule[rule_id].insert(0, counter) rec = history_per_rule[rule_id]
history_per_rule[rule_id] = history_per_rule[rule_id][:samplecount] last_rec = rec[0]
if last_rec==None or (zero_or_null and last_rec['value']==0) or ((not zero_or_null) and last_rec['value']!=0):
rec.insert(0, counter)
history_per_rule[rule_id] = rec[:samplecount]
else: else:
history_per_rule[rule_id] = [counter] if zero_or_null:
except Exception as e: history_per_rule[rule_id] = [counter]
logger.info("add_initial_zero_value(): 2 STATISTICS_PER_RULE: exception: "+str(e))
history['_per_rule'] = history_per_rule history['_per_rule'] = history_per_rule
# store updated history # store updated history
save_history(history, nowstr) save_history(history, nowstr)
except Exception as e:
logger.info("add_initial_zero_value(): failure: exception: "+str(e))
unlock_history_file()
...@@ -86,10 +86,10 @@ def edit(route, callback=None): ...@@ -86,10 +86,10 @@ def edit(route, callback=None):
commit, response = applier.apply(operation="replace") commit, response = applier.apply(operation="replace")
if commit: if commit:
status = "ACTIVE" status = "ACTIVE"
#try: try:
# snmp_add_initial_zero_value.delay(str(route.id), True) snmp_add_initial_zero_value.delay(str(route.id), True)
#except Exception as e: except Exception as e:
# logger.error("edit(): route="+str(route)+", ACTIVE, add_initial_zero_value failed: "+str(e)) logger.error("edit(): route="+str(route)+", ACTIVE, add_initial_zero_value failed: "+str(e))
else: else:
status = "ERROR" status = "ERROR"
route.status = status route.status = status
...@@ -124,10 +124,10 @@ def delete(route, **kwargs): ...@@ -124,10 +124,10 @@ def delete(route, **kwargs):
if "reason" in kwargs and kwargs['reason'] == 'EXPIRED': if "reason" in kwargs and kwargs['reason'] == 'EXPIRED':
status = 'EXPIRED' status = 'EXPIRED'
reason_text = " Reason: %s " % status reason_text = " Reason: %s " % status
#try: try:
# snmp_add_initial_zero_value.delay(str(route.id), False) snmp_add_initial_zero_value.delay(str(route.id), False)
#except Exception as e: except Exception as e:
# logger.error("edit(): route="+str(route)+", INACTIVE, add_null_value failed: "+str(e)) logger.error("edit(): route="+str(route)+", INACTIVE, add_null_value failed: "+str(e))
else: else:
status = "ERROR" status = "ERROR"
route.status = status route.status = status
...@@ -350,13 +350,11 @@ def snmp_add_initial_zero_value(rule_id, zero_or_null=True): ...@@ -350,13 +350,11 @@ def snmp_add_initial_zero_value(rule_id, zero_or_null=True):
else: else:
logger.info("snmp_add_initial_zero_value(): in child process (pid="+str(pid)+", npid="+str(npid)+")") logger.info("snmp_add_initial_zero_value(): in child process (pid="+str(pid)+", npid="+str(npid)+")")
if snmp_lock_create(1): try:
try: snmpstats.add_initial_zero_value(rule_id, zero_or_null)
snmpstats.add_initial_zero_value(rule_id, zero_or_null) logger.info("snmp_add_initial_zero_value(): rule_id="+str(rule_id)+" sucesss")
logger.info("snmp_add_initial_zero_value(): rule_id="+str(rule_id)+" sucesss") except Exception as e:
except Exception as e: logger.error("snmp_add_initial_zero_value(): rule_id="+str(rule_id)+" failed: "+str(e))
logger.error("snmp_add_initial_zero_value(): rule_id="+str(rule_id)+" failed: "+str(e))
snmp_lock_remove()
#exit_process() #exit_process()
logger.info("exit_process(): before exit in child process (pid="+str(pid)+", npid="+str(npid)+")") logger.info("exit_process(): before exit in child process (pid="+str(pid)+", npid="+str(npid)+")")
......
...@@ -13,6 +13,8 @@ function myreloadPage() { ...@@ -13,6 +13,8 @@ function myreloadPage() {
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header">{{ route.name }}</h1> <h1 class="page-header">{{ route.name }}</h1>
<div>(all times are in {{ tz }}; current System time: {{ mytime|date:'Y-m-d H:i' }})</div>
<br>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment