[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r9497: Support python 2.3, add collection of running orconn bw stat (torflow/trunk)
Author: mikeperry
Date: 2007-02-06 00:47:35 -0500 (Tue, 06 Feb 2007)
New Revision: 9497
Added:
torflow/trunk/data/
Modified:
torflow/trunk/TorCtl.py
torflow/trunk/metatroller.py
torflow/trunk/nodemon.py
Log:
Support python 2.3, add collection of running orconn bw stats to node monitor.
Modified: torflow/trunk/TorCtl.py
===================================================================
--- torflow/trunk/TorCtl.py 2007-02-06 04:58:56 UTC (rev 9496)
+++ torflow/trunk/TorCtl.py 2007-02-06 05:47:35 UTC (rev 9497)
@@ -416,7 +416,7 @@
rj = re.search(r"^reject (\S+):([^-]+)(?:-(\d+))?", line)
bw = re.search(r"^bandwidth \d+ \d+ (\d+)", line)
if re.search(r"^opt hibernating 1", line):
- dead = 1
+ dead = 1 # XXX: Technically this may be stale..
if ac:
exitpolicy.append(ExitPolicyLine(1, *ac.groups()))
elif rj:
Modified: torflow/trunk/metatroller.py
===================================================================
--- torflow/trunk/metatroller.py 2007-02-06 04:58:56 UTC (rev 9496)
+++ torflow/trunk/metatroller.py 2007-02-06 05:47:35 UTC (rev 9497)
@@ -41,8 +41,8 @@
# Technically we could just add member vars as we need them, but this
# is a bit more clear
class MetaRouter(TorCtl.Router):
- def __init__(self, router):
- # XXX: Copy router stuff over
+ def __init__(self, router): # Promotion constructor :)
+ self.__dict__ = router.__dict__
self.failed = 0
self.suspected = 0
self.circ_selections = 0
@@ -51,10 +51,11 @@
self.reason_failed = {}
class MetaCircuit(TorCtl.Circuit):
- def __init__(self, circuit):
- # XXX: Copy circuit stuff over
+ def __init__(self, circuit): # Promotion
+ self.__dict__ = circuit.__dict__
self.detached_cnt = 0
self.used_cnt = 0
+ self.created_at = 0
class Stream:
def __init__(self):
@@ -90,7 +91,7 @@
try:
key_to_name[ns.idhex] = ns.name
name_to_key[ns.name] = ns.idhex
- r = c.get_router(ns)
+ r = MetaRouter(c.get_router(ns))
if ns.idhex in routers:
if routers[ns.idhex].name != r.name:
plog("NOTICE", "Router "+r.idhex+" changed names from "
@@ -107,7 +108,7 @@
except:
traceback.print_exception(*sys.exc_info())
continue
- sorted_r.sort(cmp, lambda sr: sr.bw)
+ sorted_r.sort(lambda x, y: cmp(y.bw, x.bw))
global total_r_bw, total_g_bw # lame....
for r in sorted_r:
@@ -146,11 +147,12 @@
attach_circ = circ
break
else:
- attach_circ = self.c.build_circuit(3, choose_entry_uniform,
+ attach_circ = MetaCircuit(
+ self.c.build_circuit(3, choose_entry_uniform,
choose_middle_uniform,
lambda path:
choose_exit_uniform(path,
- target_host, target_port))
+ target_host, target_port)))
circuits[attach_circ.cid] = attach_circ
# TODO: attach
elif status == "DETACHED":
Modified: torflow/trunk/nodemon.py
===================================================================
--- torflow/trunk/nodemon.py 2007-02-06 04:58:56 UTC (rev 9496)
+++ torflow/trunk/nodemon.py 2007-02-06 05:47:35 UTC (rev 9497)
@@ -16,16 +16,21 @@
from TorUtil import *
import sched, time
import thread
+import copy
class Reason:
def __init__(self, reason): self.reason = reason
ncircs = 0
count = 0
-class RouterReasons:
- # reason strings to Reason
- def __init__(self, target):
- self.name = target
+class RouterStats(TorCtl.Router):
+ # Behold, a "Promotion Constructor"!
+ # Also allows null superclasses! Python is awesome
+ def __init__(self, r=None):
+ if r:
+ self.__dict__ = r.__dict__
+ else:
+ self.down = 0
self.reasons = {} # For a fun time, move this outside __init__
tot_ncircs = 0
tot_count = 0
@@ -45,7 +50,31 @@
control_port = 9051
max_detach = 3
+def read_routers(c, nslist):
+ bad_key = 0
+ errors_lock.acquire()
+ for ns in nslist:
+ try:
+ key_to_name[ns.idhex] = ns.name
+ name_to_key[ns.name] = ns.idhex
+ r = RouterStats(c.get_router(ns))
+ if ns.name in errors:
+ if errors[ns.name].idhex != r.idhex:
+ plog("NOTICE", "Router "+r.name+" has multiple keys: "
+ +errors[ns.name].idhex+" and "+r.idhex)
+ errors[r.name] = r # XXX: We get names only from ORCONN :(
+ except TorCtl.ErrorReply:
+ bad_key += 1
+ if "Running" in ns.flags:
+ plog("INFO", "Running router "+ns.name+"="
+ +ns.idhex+" has no descriptor")
+ pass
+ except:
+ traceback.print_exception(*sys.exc_info())
+ continue
+ errors_lock.release()
+
# Make eventhandler
class NodeHandler(TorCtl.EventHandler):
def __init__(self, c):
@@ -59,13 +88,17 @@
if target not in key_to_name:
target = "AllClients:HASH"
else: target = key_to_name[target]
- elif target not in name_to_key:
+ elif target not in name_to_key:
+ plog("DEBUG", "IP? " + target)
target = "AllClients:IP"
if status == "READ" or status == "WRITE":
#plog("DEBUG", "Read: " + str(read) + " wrote: " + str(wrote))
errors_lock.acquire()
- if target not in errors: errors[target] = RouterReasons(target)
+ if target not in errors:
+ plog("NOTICE", "Buh?? No "+target)
+ errors[target] = RouterStats()
+ errors[target].name = target
errors[target].running_read += read
errors[target].running_wrote += wrote
errors_lock.release()
@@ -73,7 +106,12 @@
if status == "CLOSED" or status == "FAILED":
errors_lock.acquire()
- if target not in errors: errors[target] = RouterReasons(target)
+ if target not in errors:
+ plog("NOTICE", "Buh?? No "+target)
+ errors[target] = RouterStats()
+ errors[target].name = target
+ if status == "FAILED" and not errors[target].down:
+ status = status + "(Running)"
reason = status+":"+reason
if reason not in errors[target].reasons:
errors[target].reasons[reason] = Reason(reason)
@@ -101,16 +139,11 @@
reason, ncircs)))
def ns(self, eventtype, nslist):
- for ns in nslist:
- key_to_name[ns.idhex] = ns.name
- name_to_key[ns.name] = ns.idhex
-
+ read_routers(self.c, nslist)
+
def new_desc(self, eventtype, identities):
- for i in identities:
- nslist = self.c.get_network_status("id/"+i)
- for ns in nslist: # should be only 1, but eh
- key_to_name[ns.idhex] = ns.name
- name_to_key[ns.name] = ns.idhex
+ for i in identities: # Is this too slow?
+ read_routers(self.c, self.c.get_network_status("id/"+i))
def bw_stats(key, f):
routers = errors.values()
@@ -132,26 +165,30 @@
# 3. Routers sorted by tot bytes
bw_stats(lambda x: x.tot_read+x.tot_wrote, file("./data/r_by_tbytes", "w"))
# 4. Routers sorted by downstream bw
- bw_stats(lambda x: x.tot_read/(x.tot_age+0.005),
+ bw_stats(lambda x: x.tot_read/(x.tot_age+0.005),
file("./data/r_by_rbw", "w"))
# 5. Routers sorted by upstream bw
bw_stats(lambda x: x.tot_wrote/(x.tot_age+0.005), file("./data/r_by_wbw", "w"))
# 6. Routers sorted by total bw
- bw_stats(lambda x: (x.tot_read+x.tot_wrote)/(x.tot_age+0.005),
+ bw_stats(lambda x: (x.tot_read+x.tot_wrote)/(x.tot_age+0.005),
file("./data/r_by_tbw", "w"))
- bw_stats(lambda x: x.running_read,
+ bw_stats(lambda x: x.running_read,
file("./data/r_by_rrunbytes", "w"))
- bw_stats(lambda x: x.running_wrote,
+ bw_stats(lambda x: x.running_wrote,
file("./data/r_by_wrunbytes", "w"))
- bw_stats(lambda x: x.running_read+x.running_wrote,
+ bw_stats(lambda x: x.running_read+x.running_wrote,
file("./data/r_by_trunbytes", "w"))
-
f = file("./data/reasons", "w")
routers = errors.values()
- routers.sort(lambda x, y: cmp(y.tot_ncircs, x.tot_ncircs))
+ def notlambda(x, y):
+ if y.tot_ncircs or x.tot_ncircs:
+ return cmp(y.tot_ncircs, x.tot_ncircs)
+ else:
+ return cmp(y.tot_count, x.tot_count)
+ routers.sort(notlambda)
for r in routers:
f.write(r.name+" " +str(r.tot_ncircs)+"/"+str(r.tot_count)+"\n")
@@ -167,10 +204,8 @@
def startmon(c):
global key_to_name, name_to_key
nslist = c.get_network_status()
- for ns in nslist:
- key_to_name[ns.idhex] = ns.name
- name_to_key[ns.name] = ns.idhex
-
+ read_routers(c, nslist)
+
s=sched.scheduler(time.time, time.sleep)
s.enter(60, 1, save_stats, (s,))