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.
32 # RE to match line starting "traceroute to"
33 _rre = re.compile("\d+ bytes from ((?P<hostname>[^\s]+) )?\(?(?P<ip>[^\s]+)\)??: icmp_.eq=\d+ ttl=\d+ time=(?P<time>[^\s]+) ms")
35 def parse_file(filename):
37 filename: path to traceroute file
41 f = open(filename, "r")
45 target_hostname = None
50 # match traceroute to ...
51 m = re.match(_rre, line)
55 target_ip = m.groupdict()["ip"]
56 # FIX THIS: Make sure the regular expression does not inlcude
57 # the ')' in the ip group
58 target_ip = target_ip.replace(")","")
59 target_hostname = m.groupdict()["hostname"]
60 time = m.groupdict()["time"]
61 data.append((target_ip, target_hostname, time))
67 def annotate_cn_node(graph, nid1, ips2nids, data):
68 for (target_ip, target_hostname, time) in data:
69 nid2 = ips2nid[target_ip]
71 if "delays" not in graph.edge[nid1][nid2]:
72 graph.edge[nid1][nid2]["delays"] = []
74 time = float(time.replace("ms", "").replace(" ",""))
76 graph.edge[nid1][nid2]["delays"].append(time)
78 def annotate_cn_graph(logs_dir, graph):
79 """ Add delay inormation to graph using data collected using
85 for nid in graph.nodes():
86 ips = graph.node[nid]["ips"]
90 # Walk through the ping logs...
91 for dirpath, dnames, fnames in os.walk(logs_dir):
92 # continue if we are not at the leaf level (if there are subdirectories)
96 # Each dirpath correspond to a different host
97 nid = os.path.basename(dirpath)
100 if fname.endswith(".ping"):
101 filename = os.path.join(dirpath, fname)
102 data = parse_file(filename)
103 annotate_cn_node(graph, nid, ips2nids, data)
105 # Take as weight the most frequent value
106 for nid1, nid2 in graph.edges():
107 delays = collections.Counter(graph.edge[nid1][nid2]["delays"])
108 weight = delays.most_common(1)[0][0]
109 del graph.edge[nid1][nid2]["delays"]
110 graph.edge[nid1][nid2]["weight"] = weight