@cryptotaxi247 / netdata-1 / commits / e7158e772

Convert SpigotMC module to use regexes for parsing. (#5507)

This makes the parsing a bit more robust at the cost of some performance. Additionally, this relaxes the parsing logic surrounding the handling of the user counts to just grab the first integer after the timestamp and treat it as the count of users. Fixes: #4131

Austin S. Hemmelgarn committed Mar 6, 2019 at 08:12 UTC e7158e772e55059895bb662b08f810e5530b13fe
1 file changed +27 -15
collectors/python.d.plugin/spigotmc/spigotmc.chart.py
+27 -15
@@ -5,6 +5,7 @@
5
6 import socket
7 import platform
8 +import re
9
10 from bases.FrameworkServices.SimpleService import SimpleService
11
@@ -37,6 +38,17 @@ CHARTS = {
38 ]
39 }
40 }
41 +_TPS_REGEX = re.compile(
42 + r'^.*: .*?' # Message lead-in
43 + r'(\d{1,2}.\d+), .*?' # 1-minute TPS value
44 + r'(\d{1,2}.\d+), .*?' # 5-minute TPS value
45 + r'(\d{1,2}\.\d+).*$', # 15-minute TPS value
46 + re.X | re.A
47 +)
48 +_LIST_REGEX = re.compile(
49 + r'(\d+)', # Current user count.
50 + re.X | re.A
51 +)
52
53
54 class Service(SimpleService):
@@ -91,33 +103,33 @@ class Service(SimpleService):
103 data = {}
104 try:
105 raw = self.console.command('tps')
94 - # The above command returns a string that looks like this:
95 - # '§6TPS from last 1m, 5m, 15m: §a19.99, §a19.99, §a19.99\n'
96 - # The values we care about are the three numbers after the :
97 - tmp = raw.split(':')[1].split(',')
98 - data['tps1'] = float(tmp[0].lstrip(u' §a*')) * PRECISION
99 - data['tps5'] = float(tmp[1].lstrip(u' §a*')) * PRECISION
100 - data['tps15'] = float(tmp[2].lstrip(u' §a*').rstrip()) * PRECISION
106 + match = _TPS_REGEX.match(raw)
107 + if match:
108 + data['tps1'] = int(float(match.group(1)) * PRECISION)
109 + data['tps5'] = int(float(match.group(2)) * PRECISION)
110 + data['tps15'] = int(float(match.group(3)) * PRECISION)
111 + else:
112 + self.error('Unable to process TPS values.')
113 except mcrcon.MCRconException:
114 self.error('Unable to fetch TPS values.')
115 except socket.error:
116 self.error('Connection is dead.')
117 self.alive = False
118 return None
107 - except (TypeError, LookupError):
108 - self.error('Unable to process TPS values.')
119 try:
120 raw = self.console.command('list')
111 - # The above command returns a string that looks like this:
112 - # 'There are 0/20 players online:'
113 - # We care about the first number here.
114 - data['users'] = int(raw.split()[2].split('/')[0])
121 + match = _LIST_REGEX.search(raw)
122 + if not match:
123 + raw = self.console.command('online')
124 + match = _LIST_REGEX.search(raw)
125 + if match:
126 + data['users'] = int(match.group(1))
127 + else:
128 + self.error('Unable to process user counts.')
129 except mcrcon.MCRconException:
130 self.error('Unable to fetch user counts.')
131 except socket.error:
132 self.error('Connection is dead.')
133 self.alive = False
134 return None
121 - except (TypeError, LookupError):
122 - self.error('Unable to process user counts.')
135 return data