Remedy all the pylint-errors
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
'''Client for the routerstats collection'''
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import logging
|
import logging
|
||||||
@@ -16,46 +17,54 @@ logging.basicConfig(
|
|||||||
datefmt='%Y-%m-%d %H:%M:%S')
|
datefmt='%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
class NotConnected(Exception):
|
class NotConnected(Exception):
|
||||||
logging.error('NotConnected error')
|
'''Raise to make it known that you are not connected'''
|
||||||
pass
|
|
||||||
|
|
||||||
class routerstats_client():
|
class RouterstatsClient():
|
||||||
|
'''Client itself'''
|
||||||
def __init__(self, host, port, passwd_file):
|
def __init__(self, host, port, passwd_file):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.connected = False
|
self.connected = False
|
||||||
|
self.sock = None
|
||||||
self.passwd_file = passwd_file
|
self.passwd_file = passwd_file
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
|
'''Do connect'''
|
||||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
self.sock.connect((self.host, self.port))
|
self.sock.connect((self.host, self.port))
|
||||||
self.sock.settimeout(1)
|
self.sock.settimeout(1)
|
||||||
logging.info('Connected to ' + str(self.host))
|
logging.info('Connected to %s', self.host)
|
||||||
self.login()
|
self.login()
|
||||||
self.connected = True
|
self.connected = True
|
||||||
except ConnectionRefusedError as error:
|
except ConnectionRefusedError as error:
|
||||||
logging.error('Could not connect to ' + str(self.host) + ':' + str(self.port))
|
logging.error('Could not connect to %s:%s', self.host, self.port)
|
||||||
raise ConnectionRefusedError(error)
|
raise ConnectionRefusedError from error
|
||||||
except ConnectionError as error:
|
except ConnectionError as error:
|
||||||
logging.error('Could not connect to ' + str(self.host) + ':' + str(self.port) + ': ' + str(error))
|
logging.error('Could not connect to %s:%s: %s',
|
||||||
|
self.host,
|
||||||
|
self.port,
|
||||||
|
error)
|
||||||
except TimeoutError as error:
|
except TimeoutError as error:
|
||||||
logging.error('Timed out')
|
logging.error('Timed out')
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
#Wait for server to say "hello"
|
'''Do the login routine.
|
||||||
#Reply with password
|
Wait for server to greet us with "hello"
|
||||||
#Wait for "Welcome"
|
reply with the password
|
||||||
|
wait for "Welcome"
|
||||||
|
'''
|
||||||
|
|
||||||
logging.debug('Logging in')
|
logging.debug('Logging in')
|
||||||
try:
|
try:
|
||||||
hello = self.sock.recv(5)
|
hello = self.sock.recv(5)
|
||||||
except TimeoutError:
|
except TimeoutError as exception:
|
||||||
logging.error('Timeout while waiting for Hello')
|
logging.error('Timeout while waiting for Hello')
|
||||||
raise ConnectionError('Timed out waiting for Hello when connecting')
|
raise ConnectionError('Timed out waiting for Hello when connecting') from exception
|
||||||
if not hello == b'Hello':
|
if not hello == b'Hello':
|
||||||
logging.error('No Hello from server: %s', hello)
|
logging.error('No Hello from server: %s', hello)
|
||||||
raise ConnectionError('Server did not greet us with Hello during login')
|
raise ConnectionError('Server did not greet us with Hello during login')
|
||||||
with open(self.passwd_file, 'r') as passwd_file:
|
with open(self.passwd_file, 'r', encoding='utf-8') as passwd_file:
|
||||||
passwd = passwd_file.readline()
|
passwd = passwd_file.readline()
|
||||||
passwd = passwd.rstrip()
|
passwd = passwd.rstrip()
|
||||||
logging.debug('Sending password: %s', passwd)
|
logging.debug('Sending password: %s', passwd)
|
||||||
@@ -66,31 +75,34 @@ class routerstats_client():
|
|||||||
logging.error('Not Welcome: %s', response)
|
logging.error('Not Welcome: %s', response)
|
||||||
raise ConnectionError('We are not greeted with Welcome after sending password')
|
raise ConnectionError('We are not greeted with Welcome after sending password')
|
||||||
return True
|
return True
|
||||||
except TimeoutError:
|
except TimeoutError as exception:
|
||||||
raise ConnectionError('Timed out while waiting for server to greet us after sending password')
|
raise ConnectionError(
|
||||||
|
'Timed out while waiting for server to greet us after sending password') from exception
|
||||||
|
|
||||||
def send(self, tosend):
|
def send(self, tosend):
|
||||||
|
'''Send some data'''
|
||||||
if self.connected:
|
if self.connected:
|
||||||
logging.debug('Sending ' + str(tosend))
|
logging.debug('Sending %s', tosend)
|
||||||
send_bytes = bytes(tosend + "\n", 'utf-8')
|
send_bytes = bytes(tosend + "\n", 'utf-8')
|
||||||
try:
|
try:
|
||||||
self.sock.send(send_bytes)
|
self.sock.send(send_bytes)
|
||||||
except OSError as error:
|
except OSError as error:
|
||||||
logging.error('Cound not send to server: ' + str(error))
|
logging.error('Cound not send to server: %s', error)
|
||||||
self.connected = False
|
self.connected = False
|
||||||
raise NotConnected
|
raise NotConnected from error
|
||||||
try:
|
try:
|
||||||
self.sock.getpeername()
|
self.sock.getpeername()
|
||||||
except OSError as error:
|
except OSError as error:
|
||||||
logging.error('Could not send to server: ' + str(error))
|
logging.error('Could not send to server: %s', error)
|
||||||
self.connected = False
|
self.connected = False
|
||||||
raise NotConnected
|
raise NotConnected from error
|
||||||
else:
|
else:
|
||||||
logging.error('Not connected to server')
|
logging.error('Not connected to server')
|
||||||
raise NotConnected('Not connected to server')
|
raise NotConnected('Not connected to server')
|
||||||
|
|
||||||
def recv(self):
|
def recv(self):
|
||||||
if self.connected != True:
|
'''Receive some data'''
|
||||||
|
if self.connected is not True:
|
||||||
logging.error('Trying to recv when not connected')
|
logging.error('Trying to recv when not connected')
|
||||||
raise NotConnected
|
raise NotConnected
|
||||||
line = b''
|
line = b''
|
||||||
@@ -105,7 +117,7 @@ class routerstats_client():
|
|||||||
if line.endswith(b'\n'):
|
if line.endswith(b'\n'):
|
||||||
#We're done for now, returning value
|
#We're done for now, returning value
|
||||||
line = line.strip().decode('utf-8')
|
line = line.strip().decode('utf-8')
|
||||||
logging.debug('Received from server: ' + str(line))
|
logging.debug('Received from server: %s', line)
|
||||||
return line
|
return line
|
||||||
else:
|
else:
|
||||||
blanks += 1
|
blanks += 1
|
||||||
@@ -115,72 +127,86 @@ class routerstats_client():
|
|||||||
logging.debug('Too many blank reads, and still no complete line')
|
logging.debug('Too many blank reads, and still no complete line')
|
||||||
self.connected = False
|
self.connected = False
|
||||||
raise NotConnected
|
raise NotConnected
|
||||||
|
except TimeoutError:
|
||||||
|
logging.error('Timeout while fetching data, got: %s' ,line)
|
||||||
|
break
|
||||||
except OSError as error:
|
except OSError as error:
|
||||||
if str(error) == 'timed out':
|
if str(error) == 'timed out':
|
||||||
#This is expected, as it is how we loop
|
#This is expected, as it is how we loop
|
||||||
break
|
break
|
||||||
logging.error('OSError: ' + str(error))
|
logging.error('OSError: %s', error)
|
||||||
logging.debug('Got: ' + str(line))
|
logging.debug('Got: %s', line)
|
||||||
self.connected = False
|
self.connected = False
|
||||||
raise NotConnected(error)
|
raise NotConnected(error) from error
|
||||||
except TimeoutError:
|
return None
|
||||||
logging.error('Timeout while fetching data, got: ' + str(line))
|
|
||||||
break
|
|
||||||
|
|
||||||
def handle_server_msg(received: str):
|
def handle_server_msg(received: str):
|
||||||
'''Do something about something from the server'''
|
'''Do something about something from the server'''
|
||||||
try:
|
try:
|
||||||
timestamp, zone = received.split()
|
timestamp, zone = received.split()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logging.error('Could not parse ' + str(received) + ' into two distinct values')
|
logging.error('Could not parse %s into two distinct values', received)
|
||||||
return
|
return None
|
||||||
try:
|
try:
|
||||||
timestamp = int(timestamp)
|
timestamp = int(timestamp)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logging.error('Could not parse ' + str(timestamp) + ' as an int')
|
logging.error('Could not parse %s as an int', timestamp)
|
||||||
return
|
return None
|
||||||
toret = {'timestamp': timestamp, 'net_dnat': 0, 'loc-net': 0}
|
toret = {'timestamp': timestamp, 'net_dnat': 0, 'loc-net': 0}
|
||||||
try:
|
try:
|
||||||
toret[zone] += 1
|
toret[zone] += 1
|
||||||
except KeyError as error:
|
except KeyError as error:
|
||||||
logging.debug('Ignoring zone: ' + str(error))
|
logging.debug('Ignoring zone: %s', error)
|
||||||
logging.debug('Parsed to: ' + str(toret))
|
logging.debug('Parsed to: %s', toret)
|
||||||
return toret
|
return toret
|
||||||
|
|
||||||
def handle(received, client):
|
def handle(received, client):
|
||||||
'''Do things with whatever came from the server'''
|
'''Do things with whatever came from the server'''
|
||||||
if not received:
|
if not received:
|
||||||
return
|
return None
|
||||||
if received == 'ping':
|
if received == 'ping':
|
||||||
client.send('pong')
|
client.send('pong')
|
||||||
return True
|
return True
|
||||||
elif received is not None:
|
if received is not None:
|
||||||
if received:
|
if received:
|
||||||
return handle_server_msg(received)
|
return handle_server_msg(received)
|
||||||
|
return None
|
||||||
|
|
||||||
class UpdateRRD:
|
class UpdateRRD:
|
||||||
'''Handle updates to the rrd-file, since we cannot update more than once every second'''
|
'''Handle updates to the rrd-file, since we cannot update more than once every second'''
|
||||||
def __init__(self, rrdfile):
|
def __init__(self, rrdfile):
|
||||||
self.rrdfile = rrdfile
|
self.rrdfile = rrdfile
|
||||||
if os.path.isfile(rrdfile) != True:
|
if os.path.isfile(rrdfile) is not True:
|
||||||
self.create()
|
self.create()
|
||||||
self.toupdate = {'timestamp': None, 'net_dnat': 0, 'loc-net': 0}
|
self.toupdate = {'timestamp': None, 'net_dnat': 0, 'loc-net': 0}
|
||||||
self.freshdict = self.toupdate.copy()
|
self.freshdict = self.toupdate.copy()
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
rrdtool.create(self.rrdfile, "--start", "1000000000", "--step", "10", "DS:net_dnat:ABSOLUTE:10:0:U", "DS:loc-net:ABSOLUTE:10:0:U", "RRA:AVERAGE:0.5:1:1d", "RRA:AVERAGE:0.5:1:1M")
|
'''Create self.rrdfile'''
|
||||||
logging.debug('Created rrdfile ' + str(self.rrdfile))
|
rrdtool.create(
|
||||||
|
self.rrdfile,
|
||||||
|
"--start",
|
||||||
|
"1000000000",
|
||||||
|
"--step",
|
||||||
|
"10",
|
||||||
|
"DS:net_dnat:ABSOLUTE:10:0:U",
|
||||||
|
"DS:loc-net:ABSOLUTE:10:0:U",
|
||||||
|
"RRA:AVERAGE:0.5:1:1d",
|
||||||
|
"RRA:AVERAGE:0.5:1:1M")
|
||||||
|
logging.debug('Created rrdfile %s', self.rrdfile)
|
||||||
|
|
||||||
def push(self):
|
def push(self):
|
||||||
|
'''Send data to rrdtool'''
|
||||||
#Make sure we're not doing something stupid..
|
#Make sure we're not doing something stupid..
|
||||||
info = rrdtool.info(self.rrdfile)
|
info = rrdtool.info(self.rrdfile)
|
||||||
if self.toupdate['timestamp'] is None:
|
if self.toupdate['timestamp'] is None:
|
||||||
return False
|
return False
|
||||||
if info['last_update'] > self.toupdate['timestamp']:
|
if info['last_update'] > self.toupdate['timestamp']:
|
||||||
logging.error('Trying to update when rrdfile is newer than our timestamp. Ignoring line and resetting.')
|
logging.error(
|
||||||
|
'Trying to update when rrdfile is newer than our timestamp. Ignoring line and resetting.')
|
||||||
self.toupdate = self.freshdict.copy()
|
self.toupdate = self.freshdict.copy()
|
||||||
return False
|
return False
|
||||||
elif info['last_update'] == self.toupdate['timestamp']:
|
if info['last_update'] == self.toupdate['timestamp']:
|
||||||
logging.error('last update and toupdate timestamp are the same, this should not happen')
|
logging.error('last update and toupdate timestamp are the same, this should not happen')
|
||||||
self.toupdate = self.freshdict.copy()
|
self.toupdate = self.freshdict.copy()
|
||||||
return False
|
return False
|
||||||
@@ -202,6 +228,7 @@ class UpdateRRD:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def add(self, input_dict):
|
def add(self, input_dict):
|
||||||
|
'''Add data to be added later'''
|
||||||
if self.toupdate['timestamp'] is None:
|
if self.toupdate['timestamp'] is None:
|
||||||
#Never touched, just overwrite with whatever we got
|
#Never touched, just overwrite with whatever we got
|
||||||
self.toupdate = input_dict
|
self.toupdate = input_dict
|
||||||
@@ -215,15 +242,16 @@ class UpdateRRD:
|
|||||||
self.toupdate['loc-net'] += input_dict['loc-net']
|
self.toupdate['loc-net'] += input_dict['loc-net']
|
||||||
elif input_dict['timestamp'] < self.toupdate['timestamp']:
|
elif input_dict['timestamp'] < self.toupdate['timestamp']:
|
||||||
diff = self.toupdate['timestamp'] - input_dict['timestamp']
|
diff = self.toupdate['timestamp'] - input_dict['timestamp']
|
||||||
if diff == 1:
|
if diff <= 5:
|
||||||
#Might be because something is a bit slow sometimes?
|
#Might be because something is a bit slow sometimes?
|
||||||
input_dict['timestamp'] = self.toupdate['timestamp']
|
input_dict['timestamp'] = self.toupdate['timestamp']
|
||||||
else:
|
else:
|
||||||
logging.error('Newly fetched data is older than what we have in the queue already. Passing.')
|
logging.error('Newly fetched data is older than what we have in the queue already. Passing.')
|
||||||
else:
|
else:
|
||||||
logging.error('Not sure what to do here? ' + str(input_dict) + str(self.toupdate))
|
logging.error('Not sure what to do here? %s: %s', input_dict, self.toupdate)
|
||||||
|
|
||||||
def loop(client, rrdupdater):
|
def initial_connect(client):
|
||||||
|
'''Loop here until first connection is made'''
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
client.connect()
|
client.connect()
|
||||||
@@ -231,6 +259,10 @@ def loop(client, rrdupdater):
|
|||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
def loop(client, rrdupdater):
|
||||||
|
'''Main loop'''
|
||||||
|
initial_connect(client)
|
||||||
|
|
||||||
tries = 0
|
tries = 0
|
||||||
loops = 0
|
loops = 0
|
||||||
while True:
|
while True:
|
||||||
@@ -238,7 +270,7 @@ def loop(client, rrdupdater):
|
|||||||
retval = handle(client.recv(), client)
|
retval = handle(client.recv(), client)
|
||||||
if retval:
|
if retval:
|
||||||
loops = 0
|
loops = 0
|
||||||
if retval == True:
|
if retval is True:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
rrdupdater.add(retval)
|
rrdupdater.add(retval)
|
||||||
@@ -248,7 +280,8 @@ def loop(client, rrdupdater):
|
|||||||
#Want to wait until at least 5 secs have passed since last actual data fetch..
|
#Want to wait until at least 5 secs have passed since last actual data fetch..
|
||||||
rrdupdater.push()
|
rrdupdater.push()
|
||||||
if loops >= 60:
|
if loops >= 60:
|
||||||
logging.error('No data in 60 seconds. We expect a ping/pong every 30. Lost connection, probably')
|
logging.error(
|
||||||
|
'No data in 60 seconds. We expect a ping/pong every 30. Lost connection, probably')
|
||||||
loops = 0
|
loops = 0
|
||||||
raise NotConnected
|
raise NotConnected
|
||||||
except NotConnected:
|
except NotConnected:
|
||||||
@@ -256,18 +289,18 @@ def loop(client, rrdupdater):
|
|||||||
client.connect()
|
client.connect()
|
||||||
tries = 0
|
tries = 0
|
||||||
except ConnectionRefusedError as error:
|
except ConnectionRefusedError as error:
|
||||||
logging.debug(str(error))
|
logging.debug('%s', error)
|
||||||
tries += 1
|
tries += 1
|
||||||
if tries >= 5:
|
tries = min(tries, 5)
|
||||||
tries = 5
|
|
||||||
time.sleep(tries)
|
time.sleep(tries)
|
||||||
except ConnectionRefusedError as error:
|
except ConnectionRefusedError as error:
|
||||||
logging.debug(str(error))
|
logging.debug('%s', error)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
break
|
break
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
'''Main is main'''
|
||||||
config_section = 'client'
|
config_section = 'client'
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@@ -276,12 +309,12 @@ def main():
|
|||||||
parser.add_argument('-c', '--config', help='config file to load')
|
parser.add_argument('-c', '--config', help='config file to load')
|
||||||
parser.add_argument('-d', '--debug', action='store_true', help='enable debug')
|
parser.add_argument('-d', '--debug', action='store_true', help='enable debug')
|
||||||
|
|
||||||
args, remaining_args = parser.parse_known_args()
|
args, _ = parser.parse_known_args()
|
||||||
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
logging.root.setLevel(logging.DEBUG)
|
logging.root.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
logging.debug('Starting as PID ' + str(os.getpid()))
|
logging.debug('Starting as PID %s', os.getpid())
|
||||||
|
|
||||||
found = False
|
found = False
|
||||||
if args.config:
|
if args.config:
|
||||||
@@ -304,10 +337,31 @@ def main():
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
parser.add_argument('-r', '--host', dest='host', help='ip/hostname to connect to', default=config[config_section]['host'])
|
parser.add_argument(
|
||||||
parser.add_argument('-p', '--port', dest='port', type=int, help='port to connect to', default=config[config_section]['port'])
|
'-r',
|
||||||
parser.add_argument('-v', '--vardir', dest='vardir', help='directory for storing rrd file', default=config[config_section]['var_dir'])
|
'--host',
|
||||||
parser.add_argument('-w', '--pwdfile', dest='passwd_file', help='password file', default=config[config_section]['passwd_file'])
|
dest='host',
|
||||||
|
help='ip/hostname to connect to',
|
||||||
|
default=config[config_section]['host'])
|
||||||
|
parser.add_argument(
|
||||||
|
'-p',
|
||||||
|
'--port',
|
||||||
|
dest='port',
|
||||||
|
type=int,
|
||||||
|
help='port to connect to',
|
||||||
|
default=config[config_section]['port'])
|
||||||
|
parser.add_argument(
|
||||||
|
'-v',
|
||||||
|
'--vardir',
|
||||||
|
dest='vardir',
|
||||||
|
help='directory for storing rrd file',
|
||||||
|
default=config[config_section]['var_dir'])
|
||||||
|
parser.add_argument(
|
||||||
|
'-w',
|
||||||
|
'--pwdfile',
|
||||||
|
dest='passwd_file',
|
||||||
|
help='password file',
|
||||||
|
default=config[config_section]['passwd_file'])
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
logging.debug(args)
|
logging.debug(args)
|
||||||
@@ -321,7 +375,7 @@ def main():
|
|||||||
logging.error('Cannot find var dir %s', args.vardir)
|
logging.error('Cannot find var dir %s', args.vardir)
|
||||||
|
|
||||||
rrdupdater = UpdateRRD(args.vardir + '/routerstats.rrd')
|
rrdupdater = UpdateRRD(args.vardir + '/routerstats.rrd')
|
||||||
client = routerstats_client(args.host, args.port, args.passwd_file)
|
client = RouterstatsClient(args.host, args.port, args.passwd_file)
|
||||||
loop(client, rrdupdater)
|
loop(client, rrdupdater)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user