mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-26 19:35:12 +00:00
Sometimes a metric previously reported from collectd is not available anymore. Previously, this caused scyllatop to log and exception to the user - which in effect destroyes the user experience and inhibits monitoring other metrics. This patch makes ScyllaTop handle this problem. It will display such metrics and 'not available', and exclude them from some and average computations. Closes issue #1287. Signed-off-by: Yoav Kleinberger <yoav@scylladb.com> Message-Id: <1465301178-27544-1-git-send-email-yoav@scylladb.com>
57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
import socket
|
|
import re
|
|
import atexit
|
|
import os
|
|
import parseexception
|
|
import logging
|
|
|
|
COLLECTD_EXAMPLE_CONFIGURATION = '\n'.join(['LoadPlugin unixsock',
|
|
'',
|
|
'<Plugin unixsock>',
|
|
' SocketFile "{socket}"',
|
|
' SocketGroup "wheel"',
|
|
' SocketPerms "0660"',
|
|
' DeleteSocket false',
|
|
'</Plugin>'])
|
|
|
|
|
|
class Collectd(object):
|
|
_FIRST_LINE_PATTERN = re.compile('^(?P<lines>\d+)')
|
|
|
|
def __init__(self, socketName):
|
|
try:
|
|
self._connect(socketName)
|
|
atexit.register(self._cleanup)
|
|
except Exception as e:
|
|
logging.error('could not connect to {0}. {1}'.format(socketName, e))
|
|
quit()
|
|
|
|
def _connect(self, socketName):
|
|
logging.info('connecting to unix socket: {0}'.format(socketName))
|
|
self._socket = socket.socket(socket.SOCK_STREAM, socket.AF_UNIX)
|
|
self._socket.connect(socketName)
|
|
self._lineReader = os.fdopen(self._socket.fileno())
|
|
|
|
def query(self, command):
|
|
self._send(command)
|
|
return self._readLines()
|
|
|
|
def _send(self, command):
|
|
withNewline = '{command}\n'.format(command=command)
|
|
octets = withNewline.encode('ascii')
|
|
self._socket.send(octets)
|
|
|
|
def _readLines(self):
|
|
line = self._lineReader.readline()
|
|
if line.strip() == '-1 No such value':
|
|
return None
|
|
match = self._FIRST_LINE_PATTERN.search(line)
|
|
if match is None:
|
|
raise parseexception.ParseException('could not parse first line of response from collectd: {0}'.format(line))
|
|
howManyLines = int(match.groupdict()['lines'])
|
|
return [self._lineReader.readline() for _ in range(howManyLines)]
|
|
|
|
def _cleanup(self):
|
|
self._lineReader.close()
|
|
self._socket.close()
|