c5745a1f52cf33c1b0bc19f8a971fd8f79c99acc
[nepi.git] / src / nepi / data / processing / ping / parser.py
1 #!/usr/bin/env python
2
3 ###############################################################################
4 #
5 #    CCNX benchmark
6 #    Copyright (C) 2014 INRIA
7 #
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.
12 #
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.
17 #
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/>.
20 #
21 #
22 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
23 #
24 ###############################################################################
25
26 #
27 # This library contains functions to parse log files generated using ping. 
28 #
29
30 import collections
31 import re
32 import os
33
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")
36
37 def parse_file(filename):
38     """
39         filename: path to traceroute file
40
41     """
42
43     f = open(filename, "r")
44
45     # Traceroute info
46     target_ip = None
47     target_hostname = None
48    
49     data = []
50
51     for line in f:
52         # match traceroute to ...
53         m = re.match(_rre, line)
54         if not m:
55             continue
56
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))
64
65     f.close()
66
67     return data
68
69 def annotate_cn_node(graph, nid1, ips2nid, data):
70     for (target_ip, target_hostname, time) in data:
71         nid2 = ips2nid[target_ip]
72
73         if "delays" not in graph.edge[nid1][nid2]:
74             graph.edge[nid1][nid2]["delays"] = []
75
76         time = float(time.replace("ms", "").replace(" ",""))
77
78         graph.edge[nid1][nid2]["delays"].append(time)
79
80 def annotate_cn_graph(logs_dir, graph): 
81     """ Add delay inormation to graph using data collected using
82     ping.
83
84     """
85     ips2nid = dict()
86
87     for nid in graph.nodes():
88         ips = graph.node[nid]["ips"]
89         for ip in ips:
90             ips2nid[ip] = nid
91
92     # Walk through the ping logs...
93     found_files = False
94
95     for dirpath, dnames, fnames in os.walk(logs_dir):
96         # continue if we are not at the leaf level (if there are subdirectories)
97         if dnames: 
98             continue
99         
100         # Each dirpath correspond to a different host
101         nid = os.path.basename(dirpath)
102     
103         for fname in fnames:
104             if fname.endswith(".ping"):
105                 found_files = True
106                 filename = os.path.join(dirpath, fname)
107                 data = parse_file(filename)
108                 annotate_cn_node(graph, nid, ips2nid, data)
109
110     if not found_files:
111         msg = "No PING output files were found to parse at %s " % logs_dir 
112         raise RuntimeError, msg
113
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
120
121     return graph
122
123