From d5e5d740fdb9c381f3ea626b8c2276769f6b6263 Mon Sep 17 00:00:00 2001 From: "simon.kagstrom" Date: Tue, 31 Mar 2009 17:16:10 +0000 Subject: [PATCH] Produce HTML output from the server --- Src/network-broker/network-broker | 39 ++++++++++++--- Src/network-broker/stats.py | 83 +++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 Src/network-broker/stats.py diff --git a/Src/network-broker/network-broker b/Src/network-broker/network-broker index 6660bbb..909fc8e 100755 --- a/Src/network-broker/network-broker +++ b/Src/network-broker/network-broker @@ -1,7 +1,7 @@ #!/usr/bin/env python -import socket, struct, syslog, time, thread, ip2country -import SocketServer +import socket, struct, syslog, time, thread, ip2country, sys +import SocketServer, stats FRODO_NETWORK_MAGIC = 0x1976 @@ -27,8 +27,7 @@ pkt_type_to_str = { def log(pri, msg, echo): syslog.syslog(pri, msg) - if echo: - print msg + print msg def log_error(msg, echo = False): log(syslog.LOG_ERR, msg, echo) @@ -206,6 +205,8 @@ class Peer: self.name = pkt.get_name() self.is_master = pkt.is_master() + self.srv.log_connection(self.name, self.country) + # Send list of peers if this is not a master if not self.is_master: lp = ListPeersPacket() @@ -308,7 +309,7 @@ class BrokerPacketHandler(SocketServer.DatagramRequestHandler): class Broker(SocketServer.UDPServer): - def __init__(self, host, req_handler, ip2c): + def __init__(self, host, req_handler, ip2c, stat_data, stat_html): SocketServer.UDPServer.__init__(self, host, req_handler) # Instead of setsockopt( ... REUSEADDR ... ) self.allow_reuse_address = True @@ -318,6 +319,23 @@ class Broker(SocketServer.UDPServer): self.ping_seq = 0 self.ip2c = ip2c + self.stat_html = stat_html + self.stat_data = stat_data + + stats.load(self.stat_data) + + def log_connection(self, who, country): + stats.add_connection(who, country) + + try: + stats.save(self.stat_data) + except Exception, e: + error_log("saving stats failed with %s" % str(e) ) + try: + stats.generate_html(self.stat_html) + except Exception, e: + error_log("generating HTML failed with %s" % str(e) ) + def send_data(self, dst, data): self.socket.sendto(data, dst) @@ -375,10 +393,19 @@ packet_class_by_type = { ACK : PingAckPacket, } +def usage(): + print "Usage: network-broker stat-data-file stat-html-file" + sys.exit(1) + if __name__ == "__main__": + + if len(sys.argv) != 3: + usage() + ip2c = ip2country.IP2Country(verbose=0) syslog.openlog("frodo") log_info("Starting Frodo network broker", True) - broker = Broker( ("", 46214), BrokerPacketHandler, ip2c) + broker = Broker( ("", 46214), BrokerPacketHandler, + ip2c, sys.argv[1], sys.argv[2]) thread.start_new_thread(ping_thread_fn, (broker, 5)) broker.serve_forever() diff --git a/Src/network-broker/stats.py b/Src/network-broker/stats.py new file mode 100644 index 0000000..45d66af --- /dev/null +++ b/Src/network-broker/stats.py @@ -0,0 +1,83 @@ +import sys, pickle +from operator import itemgetter + +class Container: + def __init__(self): + self.country_count = {} + self.last_10 = [] + + def add_country(self, country): + try: + cur = self.country_count[country] + except KeyError, e: + cur = 0 + + self.country_count[country] = cur + 1 + + def add_connection(self, who, country): + s = "%s (%s)" % (who, country) + self.last_10 = [s] + self.last_10[:9] + self.add_country(country) + +class HtmlGenerator: + def __init__(self, container): + self.container = container + + def generate(self, outf): + sorted_countries = sorted(self.container.country_count.items(), + reverse=True, key=itemgetter(1)) + + outf.write("\n") + outf.write("

Last %d connections

\n" % (len(self.container.last_10)) ) + for item in self.container.last_10: + outf.write("%s
\n" % (item) ) + + outf.write("

Country list

\n") + count = 1 + for country, num in sorted_countries: + outf.write("%3d. %s (%d)
\n" % (count, country, num) ) + count = count + 1 + outf.write("\n") + + +g_stat = None +def save(filename): + global g_stat + + of = open(filename, "wb") + pickle.dump(g_stat, of) + of.close() + +def generate_html(filename): + of = open(filename, "wb") + hg = HtmlGenerator(g_stat) + hg.generate(of) + of.close() + + +def load(filename): + global g_stat + + try: + of = open(filename, "r") + g_stat = pickle.load(of) + of.close() + except: + g_stat = Container() + +def add_connection(who, country): + g_stat.add_connection(who, country) + +if __name__ == "__main__": + load("/tmp/vobb") + for i in range(0, 10): + add_connection("MABOO", "Unknown country") + add_connection("SIMONK", "Sweden") + add_connection("SIMONK", "Sweden") + add_connection("SIMONK", "Sweden") + add_connection("Linda", "Germany") + add_connection("Linda", "Germany") + save("/tmp/vobb") + + hg = HtmlGenerator(g_stat) + hg.generate(sys.stdout)