3 ###############################################################################
6 # Copyright (C) 2014 INRIA
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
24 ###############################################################################
27 # This library contains functions to parse log files generated using ping.
34 # RE to match line starting "traceroute to"
35 _rre = re.compile("\d+ bytes from ((?P<hostname>[^\s]+) )?\(?(?P<ip>[^\s]+)\)??: icmp_.eq=\d+ ttl=\d+ time=(?P<time>[^\s]+) ms")
37 def parse_file(filename):
39 filename: path to traceroute file
43 f = open(filename, "r")
47 target_hostname = None
52 # match traceroute to ...
53 m = re.match(_rre, line)
57 target_ip = m.groupdict()["ip"]
58 # FIX THIS: Make sure the regular expression does not inlcude
59 # the ')' in the ip group
60 target_ip = target_ip.replace(")","")
61 target_hostname = m.groupdict()["hostname"]
62 time = m.groupdict()["time"]
63 data.append((target_ip, target_hostname, time))
69 def annotate_cn_node(graph, nid1, ips2nid, data):
70 for (target_ip, target_hostname, time) in data:
71 nid2 = ips2nid[target_ip]
73 if "delays" not in graph.edge[nid1][nid2]:
74 graph.edge[nid1][nid2]["delays"] = []
76 time = float(time.replace("ms", "").replace(" ",""))
78 graph.edge[nid1][nid2]["delays"].append(time)
80 def annotate_cn_graph(logs_dir, graph):
81 """ Add delay inormation to graph using data collected using
87 for nid in graph.nodes():
88 ips = graph.node[nid]["ips"]
92 # Walk through the ping logs...
95 for dirpath, dnames, fnames in os.walk(logs_dir):
96 # continue if we are not at the leaf level (if there are subdirectories)
100 # Each dirpath correspond to a different host
101 nid = os.path.basename(dirpath)
104 if fname.endswith(".ping"):
106 filename = os.path.join(dirpath, fname)
107 data = parse_file(filename)
108 annotate_cn_node(graph, nid, ips2nid, data)
111 msg = "No PING output files were found to parse at %s " % logs_dir
112 raise RuntimeError, msg
114 # Take as weight the most frequent value
115 for nid1, nid2 in graph.edges():
116 delays = collections.Counter(graph.edge[nid1][nid2]["delays"])
117 weight = delays.most_common(1)[0][0]
118 del graph.edge[nid1][nid2]["delays"]
119 graph.edge[nid1][nid2]["weight"] = weight