bug fixes
[svn/Prometheus-QoS/.git] / optional-tools / hosts-ping.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 import ping, socket
5 import os, time, json
6
7 # (G)2013 xChaos, Arachne Labs http://arachne.cz + SPOJE.NET http://spoje.net
8
9 hosts = "/etc/hosts"
10 timeout = 1500 #timeout in ms
11 interval = 200 #ping interval in ms
12 attempts = 10
13
14 tld = ".czf"
15 domain = ".brevnov.czf"
16 smokeping_prefix = "Klienti"
17 smpater_prefix = "Backbone"
18 smokeping_babble_length = 3
19 smpater_babble_length = 2
20 smokeping_html = "/var/www/html/web/sites/sysifos/hosts-ping/index.html"
21 smpater_html = "/var/www/html/web/sites/sysifos/hosts-ping/backbone.html"
22 smokeping_avg_html = "/var/www/html/web/sites/sysifos/hosts-ping/avg.html"
23 smpater_avg_html = "/var/www/html/web/sites/sysifos/hosts-ping/backbone-avg.html"
24 smokeping_avg_json = "/var/www/html/web/sites/sysifos/hosts-ping/smokeping.json"
25 smpater_avg_json = "/var/www/html/web/sites/sysifos/hosts-ping/smpater.json"
26 smokeping_url = "http://sisyfos.brevnov.czf/cgi-bin/smokeping.cgi?filter=%s&target=%s"
27 smpater_url = "http://tartarus.brevnov.czf/cgi-bin/smokeping.cgi?filter=%s&target=%s"
28 table_head = """
29 <table class="decorated last">
30 <caption>hosts ping (%s)</caption><thead><tr>
31 <th style="text-align: right;">#</th>
32 <th>hostname</th>
33 <th style="text-align: right;">loss</th>
34 <th style="text-align: right;">avg</th>
35 <th style="text-align: right;">best</th>
36 <th style="text-align: right;">worst</th>
37 </tr></thead><tbody>
38 """
39 table_end = """
40 </tbody></table>
41 <br />
42 <p>Page generated by (G)2013 xChaos hosts-ping version 0.2-a</p>
43 """
44
45 def try_to_ping(host):
46 sum = 0.0
47 best = None
48 worst = None
49 loss = 0
50
51 for i in range(0, attempts):
52 try:
53 delay = ping.Ping(host, timeout = timeout).do() #timeout in ms
54 time.sleep(interval/1000)
55
56 if delay:
57 sum += delay
58
59 if not best or best > delay:
60 best = delay
61
62 if not worst or worst < delay:
63 worst = delay
64
65 else:
66 loss += 1
67
68 except socket.error, e:
69 loss += 1
70
71 return (sum/attempts, best, worst, loss)
72
73
74 def smokenam_style(hostname, prefix, babble_length):
75
76 if not tld in hostname:
77 hostname += domain
78
79 babble = hostname.split('.')
80 return '.'.join([prefix,] + [a_tooth for a_tooth in reversed(babble)][1:babble_length] + ['-'.join(babble),])
81
82
83 def append_host(html, host, base_url, counter, red_treshold, green_treshold):
84 style = {'right': 'text-align: right;'}
85 columns = ('loss','avg','best','worst')
86
87 for kolikaty, column in enumerate(columns):
88 style[column] = style['right']
89
90 if not host[column]:
91 host[column] = 0 #don't want it to be "None" type
92
93 if host[column] > red_treshold[kolikaty]:
94 style[column] += ' color: red;'
95 elif host[column] < green_treshold[kolikaty]:
96 style[column] += ' color: green;'
97
98 loss = 100*host['loss']/host['attempts']
99 html.write( ('<tr class="%s"><td style="%s">%d</td><td><a href="%s" target="_blank" class="blue">%s</a></td><td style="%s">%.1f%%</td>' + "\n")
100 % (('even', 'odd')[counter % 2], style['right'], counter, base_url % (host['name'], host['smokename']), host['name'], style['loss'], loss))
101
102 if host['avg'] and host['best'] and host['worst']:
103 html.write( ('<td style="%s">%.1f</td><td style="%s">%.1f</td><td style="%s">%.1f</td></tr>' + "\n")
104 % (style['avg'], host['avg'], style['best'], host['best'], style['worst'], host['worst']))
105 else:
106 html.write(3*('<td style="%s">-</td>' % style['loss']) + "\n")
107
108
109 def merge_json_avgs(filename, smoke_array):
110
111 try:
112 avg_dict = json.load(open(filename))
113
114 for host in smoke_array:
115 avg = avg_dict.get(host['ip'])
116 if avg:
117 if host['avg'] and avg['avg'] and avg['attempts']+host['attempts']-avg['loss']-host['loss'] > 0:
118 host['avg'] = ((avg['attempts']-avg['loss'])*avg['avg']+(host['attempts']-host['loss'])*host['avg'])/(avg['attempts']+host['attempts']-avg['loss']-host['loss'])
119 else:
120 host['avg'] = avg['avg']
121
122 if not host['best'] or host['best'] > avg['best']:
123 host['best'] = avg['best']
124
125 if not host['worst'] or host['worst'] < avg['worst']:
126 host['worst'] = avg['worst']
127
128 host['attempts'] += avg['attempts']
129 host['loss'] += avg['loss']
130
131 except:
132 pass #start from scratch...
133
134
135 def save_json(filename, smoke_array):
136 smoke_dict = {}
137
138 for host in smoke_array:
139 smoke_dict[host['ip']] = host
140
141 json.dump(smoke_dict, open(filename, 'w'))
142
143
144 # main program
145
146 smokeping = []
147 smpater = []
148
149 for radek in open(hosts):
150 if radek[0] != '#':
151 is_smokeping = 'smokeping' in radek and not 'hidden' in radek
152 is_smpater = 'smpater' in radek
153 if is_smokeping or is_smpater:
154 slovo = radek.split("\t")
155 host = { 'ip': slovo[0], 'name': slovo[1].split(' ')[0], 'attempts': attempts }
156 (host['avg'], host['best'], host['worst'], host['loss']) = try_to_ping(host['ip'])
157
158 if is_smokeping:
159 host['smokename'] = smokenam_style(host['name'], smokeping_prefix, smokeping_babble_length)
160 smokeping.append(host)
161 else:
162 host['smokename'] = smokenam_style(host['name'], smpater_prefix, smpater_babble_length)
163 smpater.append(host)
164
165 # smokeping
166
167 red_treshold = (0, 100, 50, 200)
168 green_treshold = (0, 7, 5, 20)
169 html = open(smokeping_html, 'w')
170 html.write("<h1>Aktuální odezva klientských zařízení</h1>");
171 html.write(table_head % time.ctime());
172
173 for kolikaty, host in enumerate(sorted(smokeping, key = lambda host: -host['loss']*host['attempts']*timeout-host['avg'])):
174 append_host(html, host, smokeping_url, kolikaty+1, red_treshold, green_treshold)
175
176 html.write(table_end)
177 html.close()
178
179 # smpater
180
181 red_treshold = (0, 50, 20, 100)
182 green_treshold = (0, 5, 2, 10)
183 html = open(smpater_html, 'w')
184 html.write("<h1>Aktuální odezva páteřních routerů</h1>");
185 html.write(table_head % time.ctime());
186
187 for kolikaty, host in enumerate(sorted(smpater, key = lambda host: -host['loss']*host['attempts']*timeout-host['avg'])):
188 append_host(html, host, smpater_url, kolikaty+1, red_treshold, green_treshold)
189
190 html.write(table_end)
191 html.close()
192
193 # smokeping average
194
195 red_treshold = (1000, 100, 20, 500)
196 green_treshold = (0, 7, 5, 20)
197 merge_json_avgs(smokeping_avg_json, smokeping)
198 html = open(smokeping_avg_html, 'w')
199 html.write("<h1>Průměrná odezva klientských zařízení</h1>");
200 html.write(table_head % time.ctime());
201
202 for kolikaty, host in enumerate(sorted(smokeping, key = lambda host: -host['loss']*host['attempts']*timeout-host['avg'])):
203 append_host(html, host, smokeping_url, kolikaty+1, red_treshold, green_treshold)
204
205 html.write(table_end)
206 html.close()
207 save_json(smokeping_avg_json, smokeping)
208
209 # smpater average
210
211 red_treshold = (100, 50, 10, 200)
212 green_treshold = (0, 5, 2, 10)
213 merge_json_avgs(smpater_avg_json, smpater)
214 html = open(smpater_avg_html, 'w')
215 html.write("<h1>Průměrná odezva páteřních routerů</h1>");
216 html.write(table_head % time.ctime());
217
218 for kolikaty, host in enumerate(sorted(smpater, key = lambda host: -host['loss']*host['attempts']*timeout-host['avg'])):
219 append_host(html, host, smpater_url, kolikaty+1, red_treshold, green_treshold)
220
221 html.write(table_end)
222 html.close()
223 save_json(smpater_avg_json, smpater)
This page took 0.397298 seconds and 4 git commands to generate.