hosts-ping: moving averages added
[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
120 if not host['best'] or host['best'] > avg['best']:
121 host['best'] = avg['best']
122
123 if not host['worst'] or host['worst'] < avg['worst']:
124 host['worst'] = avg['worst']
125
126 host['attempts'] += avg['attempts']
127 host['loss'] += avg['loss']
128
129 except:
130 pass #start from scratch...
131
132
133 def save_json(filename, smoke_array):
134 smoke_dict = {}
135
136 for host in smoke_array:
137 smoke_dict[host['ip']] = host
138
139 json.dump(smoke_dict, open(filename, 'w'))
140
141
142 # main program
143
144 smokeping = []
145 smpater = []
146
147 for radek in open(hosts):
148 if radek[0] != '#':
149 is_smokeping = 'smokeping' in radek and not 'hidden' in radek
150 is_smpater = 'smpater' in radek
151 if is_smokeping or is_smpater:
152 slovo = radek.split("\t")
153 host = { 'ip': slovo[0], 'name': slovo[1].split(' ')[0], 'attempts': attempts }
154 (host['avg'], host['best'], host['worst'], host['loss']) = try_to_ping(host['ip'])
155
156 if is_smokeping:
157 host['smokename'] = smokenam_style(host['name'], smokeping_prefix, smokeping_babble_length)
158 smokeping.append(host)
159 else:
160 host['smokename'] = smokenam_style(host['name'], smpater_prefix, smpater_babble_length)
161 smpater.append(host)
162
163 # smokeping
164
165 red_treshold = (0, 100, 50, 200)
166 green_treshold = (0, 7, 5, 20)
167 html = open(smokeping_html, 'w')
168 html.write("<h1>Aktuální odezva klientských zařízení</h1>");
169 html.write(table_head % time.ctime());
170
171 for kolikaty, host in enumerate(sorted(smokeping, key = lambda host: -host['loss']*attempts*timeout-host['avg'])):
172 append_host(html, host, smokeping_url, kolikaty+1, red_treshold, green_treshold)
173
174 html.write(table_end)
175 html.close()
176
177 # smpater
178
179 red_treshold = (0, 50, 20, 100)
180 green_treshold = (0, 5, 2, 10)
181 html = open(smpater_html, 'w')
182 html.write("<h1>Aktuální odezva páteřních routerů</h1>");
183 html.write(table_head % time.ctime());
184
185 for kolikaty, host in enumerate(sorted(smpater, key = lambda host: -host['loss']*attempts*timeout-host['avg'])):
186 append_host(html, host, smpater_url, kolikaty+1, red_treshold, green_treshold)
187
188 html.write(table_end)
189 html.close()
190
191 # smokeping average
192
193 red_treshold = (1000, 100, 20, 500)
194 green_treshold = (0, 7, 5, 20)
195 merge_json_avgs(smokeping_avg_json, smokeping)
196 html = open(smokeping_avg_html, 'w')
197 html.write("<h1>Průměrná odezva klientských zařízení</h1>");
198 html.write(table_head % time.ctime());
199
200 for kolikaty, host in enumerate(sorted(smokeping, key = lambda host: -host['loss']*attempts*timeout-host['avg'])):
201 append_host(html, host, smokeping_url, kolikaty+1, red_treshold, green_treshold)
202
203 html.write(table_end)
204 html.close()
205 save_json(smokeping_avg_json, smokeping)
206
207 # smpater average
208
209 red_treshold = (100, 50, 10, 200)
210 green_treshold = (0, 5, 2, 10)
211 merge_json_avgs(smpater_avg_json, smpater)
212 html = open(smpater_avg_html, 'w')
213 html.write("<h1>Průměrná odezva páteřních routerů</h1>");
214 html.write(table_head % time.ctime());
215
216 for kolikaty, host in enumerate(sorted(smpater, key = lambda host: -host['loss']*attempts*timeout-host['avg'])):
217 append_host(html, host, smpater_url, kolikaty+1, red_treshold, green_treshold)
218
219 html.write(table_end)
220 html.close()
221 save_json(smpater_avg_json, smpater)
This page took 0.428024 seconds and 4 git commands to generate.