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