@cryptotaxi247 / netdata-1 / commits / e89c23287

remove all regex part, using itertools and slicing instead; much better performance

lgz committed Dec 24, 2016 at 14:28 UTC e89c23287f64ac53177fc3f26e3beaea8c407044
1 file changed +26 -20
python.d/isc_dhcpd.chart.py
+26 -20
@@ -3,7 +3,6 @@
3 # Author: l2isbad
4
5 from base import SimpleService
6 -from re import compile
6 from time import mktime, strptime, gmtime, time
7 from os import stat
8 try:
@@ -12,6 +11,11 @@ try:
11 have_ipaddress = True
12 except ImportError:
13 have_ipaddress = False
14 +try:
15 + from itertools import filterfalse as filterfalse
16 +except ImportError:
17 + from itertools import ifilterfalse as filterfalse
18 +
19
20 priority = 60000
21 retries = 60
@@ -26,8 +30,8 @@ class Service(SimpleService):
30 # Will work only with 'default' db-time-format (weekday year/month/day hour:minute:second)
31 # TODO: update algorithm to parse correctly 'local' db-time-format
32 # (epoch <seconds-since-epoch>; # <day-name> <month-name> <day-number> <hours>:<minutes>:<seconds> <year>)
33 + # TODO: use threading to iter through file
34 # Also only ipv4 supported
30 - self.regex = compile(r'\d+(?:\.\d+){3}')
35
36 def check(self):
37 if not self._get_raw_data():
@@ -75,31 +79,24 @@ class Service(SimpleService):
79 Parses log file
80 :return: tuple(
81 [ipaddress, lease end time, ...],
78 - length of list,
82 time to parse leases file
83 )
84 """
85 try:
86 with open(self.leases_path, 'rt') as dhcp_leases:
84 - raw_result = []
85 -
87 time_start = time()
87 - for line in dhcp_leases:
88 - if line[0:3] == 'lea':
89 - raw_result.append(self.regex.search(line).group())
90 - elif line[2:6] == 'ends':
91 - raw_result.append(line[7:28])
92 - else:
93 - continue
88 + part1 = filterfalse(find_lease, dhcp_leases)
89 + part2 = filterfalse(find_ends, dhcp_leases)
90 + raw_result = dict(zip(part1, part2))
91 time_end = time()
92 +
93 file_parse_time = round((time_end - time_start) * 1000)
94
95 except Exception:
96 return None
97
98 else:
101 - raw_result_length = len(raw_result)
102 - result = (raw_result, raw_result_length, file_parse_time)
99 + result = (raw_result, file_parse_time)
100 return result
101
102 def _get_data(self):
@@ -112,11 +109,10 @@ class Service(SimpleService):
109 return None
110
111 # Result: {ipaddress: end lease time, ...}
115 - all_leases = dict(zip([raw_leases[0][_] for _ in range(0, raw_leases[1], 2)],
116 - [raw_leases[0][_] for _ in range(1, raw_leases[1], 2)]))
112 + all_leases = {k[6:len(k)-3]:v[7:len(v)-2] for k, v in raw_leases[0].items()}
113
114 # Result: [active binding, active binding....]. (Expire time (ends date;) - current time > 0)
119 - active_leases = [k for k, v in all_leases.items() if is_binding_active(all_leases[k])]
115 + active_leases = [k for k, v in all_leases.items() if is_bind_active(all_leases[k])]
116
117 # Result: {pool: number of active bindings in pool, ...}
118 pools_count = {pool: len([lease for lease in active_leases if is_address_in(lease, pool)])
@@ -135,14 +131,24 @@ class Service(SimpleService):
131 final_util = {''.join(['ut_', k]): v for k, v in pools_util.items()}
132
133 to_netdata = {'lsize': int(stat(self.leases_path)[6] / 1024)}
138 - to_netdata.update({'ptime': int(raw_leases[2])})
134 + to_netdata.update({'ptime': int(raw_leases[1])})
135 to_netdata.update(final_util)
136 to_netdata.update(final_count)
137
138 return to_netdata
143 -
144 -def is_binding_active(binding):
139 +
140 +
141 +def is_bind_active(binding):
142 return mktime(strptime(binding, '%w %Y/%m/%d %H:%M:%S')) - mktime(gmtime()) > 0
143
144 +
145 def is_address_in(address, pool):
146 return ipaddress(address) in ip_network(pool)
147 +
148 +
149 +def find_lease(value):
150 + return value[0:3] != 'lea'
151 +
152 +
153 +def find_ends(value):
154 + return value[2:6] != 'ends'