commit 297b2a422e989b5d672e5acda93f80d653226bd3 Author: David Fifield david@bamsoftware.com Date: Thu Dec 22 09:42:37 2011 -0800
Add facilitator-graph.py.
This program takes a facilitator log as input and produces a graph of the number of simultaneous proxies. --- experiments/facilitator-graph.py | 135 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 135 insertions(+), 0 deletions(-)
diff --git a/experiments/facilitator-graph.py b/experiments/facilitator-graph.py new file mode 100755 index 0000000..41271a7 --- /dev/null +++ b/experiments/facilitator-graph.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python + +# Makes a graph of flash proxy counts from a facilitator log. + +import datetime +import getopt +import re +import sys + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np + +POLL_INTERVAL = 10.0 + +def usage(f = sys.stdout): + print >> f, """\ +Usage: %s -o OUTPUT [INPUTFILE] + +Makes a graph of flash proxy counts from a facilitator log. + -h, --help show this help. + -o, --output=OUTPUT output file name (required).\ +""" % sys.argv[0] + +output_file_name = None + +opts, args = getopt.gnu_getopt(sys.argv[1:], "ho:", ["help", "output="]) +for o, a in opts: + if o == "-h" or o == "--help": + usage() + sys.exit() + elif o == "-o" or o == "--output": + output_file_name = a + +if not output_file_name: + usage() + sys.exit() + +if len(args) == 0: + input_file = sys.stdin +elif len(args) == 1: + input_file = open(args[0]) +else: + usage() + sys.exit() + +def format_date(d, pos=None): + d = matplotlib.dates.num2date(d) + return d.strftime("%B %d") + +def timedelta_to_seconds(delta): + return delta.days * (24 * 60 * 60) + delta.seconds + delta.microseconds / 1000000.0 + +class Block(object): + def __init__(self, ip, date): + self.ip = ip + self.begin_date = date + self.end_date = date + +prev_date = None +seen = {} +current = [] +blocks = [] +for line in input_file: + m = re.match(r'(\d+-\d+-\d+ \d+:\d+:\d+) proxy ([\d.]+):\d+ connects', line) + if not m: + continue + date_str, ip = m.groups() + date = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S") + + if prev_date is None or prev_date != date.date(): + print date.date() + prev_date = date.date() + + block = seen.get(ip) + if block is None: + block = Block(ip, date) + seen[ip] = block + current.append(block) + # Poor man's priority queue: keep the first to expire (oldest) at the + # tail of the list. + current.sort(key = lambda x: x.end_date, reverse = True) + else: + block.end_date = date + + # Delete all those that are now expired. + while current: + block = current[-1] + delta = timedelta_to_seconds(date - block.end_date) + if delta > POLL_INTERVAL * 1.5: + blocks.append(block) + current.pop() + del seen[block.ip] + else: + break + +events = [] +for block in blocks: + events.append(("begin", block.begin_date)) + events.append(("end", block.end_date + datetime.timedelta(seconds = POLL_INTERVAL / 2))) +# Handle any still alive at the end. +while current: + block = current[-1] + events.append(("begin", block.begin_date)) + events.append(("end", date)) + current.pop() + del seen[block.ip] + +events.sort(key = lambda x: x[1]) + +data = [] +num = 0 +for i, event in enumerate(events): + t = event[1] + data.append((t, num)) + if event[0] == "begin": + num += 1 + elif event[0] == "end": + num -= 1 + data.append((t, num)) +data = np.array(data) + +fig = plt.figure() +ax = fig.add_axes([0.10, 0.30, 0.88, 0.60]) +ax.set_ylabel(u"Number of proxies", fontsize=8) +fig.set_size_inches((8, 3)) + +ax.tick_params(direction="out", top="off", right="off") +ax.set_frame_on(False) +ax.xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(format_date)) +fig.autofmt_xdate() + +plt.fill_between(data[:,0], data[:,1], linewidth=0, color="black") + +fig.savefig(output_file_name)
tor-commits@lists.torproject.org