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'