Handle disconnected sockets in unbound collector. (#6561)
* Handle disconnected sockets in unbound collector. This adds an explicit check for the case of a socket that's already disconnected and skips logging an error message. The conditionn technically is an error, but it's one that we can recover from trivially by just doing nothing in this case (we were trying to disconnect the scoket anyway, so if it's already disconnected, we don't need to change anything). This uses Python's `errno` module so that we can detect this situation in a system-agnostic manner. Fixes #6434
Austin S. Hemmelgarn committed
Jul 30, 2019 at 16:21 UTC
63114bceddd8ee6916f0c8e5c642a579c2dfc1ac
2 files changed
+25
-16
collectors/python.d.plugin/python_modules/bases/FrameworkServices/SocketService.py
+3
-1
@@ -4,6 +4,7 @@
4
# Author: Ilya Mashchenko (ilyam8)
5
# SPDX-License-Identifier: GPL-3.0-or-later
6
7
+import errno
8
import socket
9
10
try:
@@ -181,7 +182,8 @@ class SocketService(SimpleService):
182
self._sock.shutdown(2) # 0 - read, 1 - write, 2 - all
183
self._sock.close()
184
except Exception as error:
184
- self.error(error)
185
+ if not (hasattr(error, 'errno') and error.errno == errno.ENOTCONN):
186
+ self.error(error)
187
self._sock = None
188
189
def _send(self, request=None):
collectors/python.d.plugin/unbound/unbound.chart.py
+22
-15
@@ -253,15 +253,19 @@ class Service(SocketService):
253
else:
254
self.request = b'UBCT1 status\n'
255
raw = self._get_raw_data()
256
- for line in raw.splitlines():
257
- if line.startswith('threads'):
258
- self.threads = int(line.split()[1])
259
- self._generate_perthread_charts()
260
- break
261
- if self.threads is None:
262
- self.info('Unable to auto-detect thread counts, disabling per-thread stats.')
263
- self.perthread = False
264
- self.request = tmp
256
+ if raw is None:
257
+ result = False
258
+ self.warning('Received no data from socket.')
259
+ else:
260
+ for line in raw.splitlines():
261
+ if line.startswith('threads'):
262
+ self.threads = int(line.split()[1])
263
+ self._generate_perthread_charts()
264
+ break
265
+ if self.threads is None:
266
+ self.info('Unable to auto-detect thread counts, disabling per-thread stats.')
267
+ self.perthread = False
268
+ self.request = tmp
269
return result
270
271
@staticmethod
@@ -274,10 +278,13 @@ class Service(SocketService):
278
raw = self._get_raw_data()
279
data = dict()
280
tmp = dict()
277
- for line in raw.splitlines():
278
- stat = line.split('=')
279
- tmp[stat[0]] = stat[1]
280
- for item in self.statmap:
281
- if item in tmp:
282
- data[self.statmap[item][0]] = float(tmp[item]) * self.statmap[item][1]
281
+ if raw is not None:
282
+ for line in raw.splitlines():
283
+ stat = line.split('=')
284
+ tmp[stat[0]] = stat[1]
285
+ for item in self.statmap:
286
+ if item in tmp:
287
+ data[self.statmap[item][0]] = float(tmp[item]) * self.statmap[item][1]
288
+ else:
289
+ self.warning('Received no data from socket.')
290
return data