Skip to content

Commit

Permalink
Load avg checks: Corrected invalid casting in timeout parameter and e…
Browse files Browse the repository at this point in the history
…xtracted code into the checklib
  • Loading branch information
blackandred committed Oct 30, 2019
1 parent d55c8f7 commit ead7ce5
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 75 deletions.
26 changes: 12 additions & 14 deletions infracheck/checks/load-average
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,25 @@ Parameters:

import os
import sys
import inspect

path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + '/../../'
sys.path.insert(0, path)

class LoadAverageAuto:
from infracheck.infracheck.checklib.loadavg import BaseLoadAverageCheck


class LoadAverageAuto(BaseLoadAverageCheck):
def main(self, timing: str, max_load: float):
current_load_average = self.get_load_average(timing)

if current_load_average > max_load:
return False, "Load %f exceeds allowed max. load of %f" % (current_load_average, max_load)

return True, "Load at level of %f is ok" % current_load_average

@staticmethod
def get_load_average(timing: str) -> float:
if os.getenv('MOCK_LOAD_AVERAGE'):
return float(os.getenv('MOCK_LOAD_AVERAGE'))

if timing not in ['1', '5', '15']:
raise Exception('Invalid argument, expected type to be: 1, 5 or 15')
return False, "Load {:.2f} exceeds allowed max. load of {:.2f}. Current load: {:s}".format(
current_load_average, max_load, self.get_complete_avg()
)

load = {'1': os.getloadavg()[0], '5': os.getloadavg()[1], '15': os.getloadavg()[2]}
return load[timing]
return True, "Load at level of {:.2f} is ok, current load: {:s}".format(
current_load_average, self.get_complete_avg())


if __name__ == '__main__':
Expand Down
70 changes: 11 additions & 59 deletions infracheck/checks/load-average-auto
Original file line number Diff line number Diff line change
Expand Up @@ -15,75 +15,27 @@ Parameters:
"""

import os
import re
import sys
import inspect

path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + '/../../'
sys.path.insert(0, path)

class LoadAverageAuto:
from infracheck.infracheck.checklib.loadavg import BaseLoadAverageCheck


class LoadAverageAuto(BaseLoadAverageCheck):
def main(self, timing: str, maximum_above: float):
current_load_average = self.get_load_average(timing)
cpu_count = self.available_cpu_count()
max_load = cpu_count + maximum_above

if current_load_average > max_load:
return False, "Load %f exceeds allowed max. load of %f" % (current_load_average, max_load)

return True, "Load at level of %f is ok" % current_load_average

@staticmethod
def get_load_average(timing: str) -> float:
if os.getenv('MOCK_LOAD_AVERAGE'):
return float(os.getenv('MOCK_LOAD_AVERAGE'))

if timing not in ['1', '5', '15']:
raise Exception('Invalid argument, expected type to be: 1, 5 or 15')

load = {'1': os.getloadavg()[0], '5': os.getloadavg()[1], '15': os.getloadavg()[2]}
return load[timing]

@staticmethod
def available_cpu_count() -> int:
""" Number of available virtual or physical CPUs on this system, i.e.
user/real as output by time(1) when called with an optimally scaling
userspace-only program
:url: https://stackoverflow.com/a/1006301/6782994
"""

if os.getenv('MOCK_CPU_COUNT'):
return int(os.getenv('MOCK_CPU_COUNT'))

# cpuset
# cpuset may restrict the number of *available* processors
try:
with open('/proc/self/status') as f:
m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$', f.read())

if m:
res = bin(int(m.group(1).replace(',', ''), 16)).count('1')
if res > 0:
return int(res)
except IOError:
pass

# Python 2.6+
try:
import multiprocessing
return multiprocessing.cpu_count()
except (ImportError, NotImplementedError):
pass

# Linux
try:
with open('/proc/cpuinfo') as f:
res = f.read().count('processor\t:')

if res > 0:
return int(res)
except IOError:
pass
return False, "Load {:.2f} exceeds allowed max. load of {:.2f}. Current load: {:s}".format(
current_load_average, max_load, self.get_complete_avg())

raise Exception('Can not determine number of CPUs on this system')
return True, "Load at level of {:.2f} is ok. Current load: {:s}".format(
current_load_average, self.get_complete_avg())


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions infracheck/checks/ssh-command
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ if __name__ == '__main__':
ssh_bin=os.getenv('SSH_BIN', 'ssh'),
sshpass_bin=os.getenv('SSHPASS_BIN', 'sshpass'),
ssh_opts=os.getenv('SSH_OPTS', ''),
timeout=os.getenv('TIMEOUT', 15)
timeout=int(os.getenv('TIMEOUT', 15))
)

status, message = app.main(
command=os.getenv('COMMAND', 'uname -a'),
expected_keywords=os.getenv('EXPECTED_KEYWORDS', '').split(';'),
expected_exit_code=os.getenv('EXPECTED_EXIT_CODE', 0),
expected_exit_code=int(os.getenv('EXPECTED_EXIT_CODE', 0)),
unexpected_keywords=os.getenv('UNEXPECTED_KEYWORDS', '').split(';')
)

Expand Down
66 changes: 66 additions & 0 deletions infracheck/infracheck/checklib/loadavg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

import abc
import os
import re


class BaseLoadAverageCheck(abc.ABC):
@staticmethod
def get_complete_avg() -> str:
avg = os.getloadavg()
return '{:.2f}, {:.2f}, {:.2f}'.format(avg[0], avg[1], avg[2])

@staticmethod
def get_load_average(timing: str) -> float:
if os.getenv('MOCK_LOAD_AVERAGE'):
return float(os.getenv('MOCK_LOAD_AVERAGE'))

if timing not in ['1', '5', '15']:
raise Exception('Invalid argument, expected type to be: 1, 5 or 15')

load = {'1': os.getloadavg()[0], '5': os.getloadavg()[1], '15': os.getloadavg()[2]}
return load[timing]

@staticmethod
def available_cpu_count() -> int:
""" Number of available virtual or physical CPUs on this system, i.e.
user/real as output by time(1) when called with an optimally scaling
userspace-only program
:url: https://stackoverflow.com/a/1006301/6782994
"""

if os.getenv('MOCK_CPU_COUNT'):
return int(os.getenv('MOCK_CPU_COUNT'))

# cpuset
# cpuset may restrict the number of *available* processors
try:
with open('/proc/self/status') as f:
m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$', f.read())

if m:
res = bin(int(m.group(1).replace(',', ''), 16)).count('1')
if res > 0:
return int(res)
except IOError:
pass

# Python 2.6+
try:
import multiprocessing
return multiprocessing.cpu_count()
except (ImportError, NotImplementedError):
pass

# Linux
try:
with open('/proc/cpuinfo') as f:
res = f.read().count('processor\t:')

if res > 0:
return int(res)
except IOError:
pass

raise Exception('Can not determine number of CPUs on this system')

0 comments on commit ead7ce5

Please sign in to comment.