Skip to content

Commit

Permalink
Checks: Added load-average and load-average-auto
Browse files Browse the repository at this point in the history
  • Loading branch information
blackandred committed Oct 28, 2019
1 parent af67f86 commit 7ff61d1
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 2 deletions.
4 changes: 2 additions & 2 deletions docs/source/custom-scripts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ A few examples:
:language: bash
:linenos:

.. literalinclude:: ../../infracheck/checks/replication-running
:language: bash
.. literalinclude:: ../../infracheck/checks/load-average
:language: python
:linenos:
8 changes: 8 additions & 0 deletions docs/source/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,11 @@ Parameters:
.. include:: ../../infracheck/checks/reminder
:start-after: <sphinx>
:end-before: </sphinx>

.. include:: ../../infracheck/checks/load-average-auto
:start-after: <sphinx>
:end-before: </sphinx>

.. include:: ../../infracheck/checks/load-average
:start-after: <sphinx>
:end-before: </sphinx>
17 changes: 17 additions & 0 deletions infracheck/checks-tests/load-average-auto-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

echo " >> Assert that load 11.6 is higher than 10+1"
MAXIMUM_ABOVE=1.0 MOCK_CPU_COUNT=10 MOCK_LOAD_AVERAGE=11.6 ./infracheck/checks/load-average-auto
if [[ $? != 1 ]]; then
echo " >> Test failed."
exit 1
fi

echo " >> Assert that load 20 is ok, when we have 30 cores and MAXIMUM_ABOVE=0.5"
MAXIMUM_ABOVE=0.5 MOCK_CPU_COUNT=20 MOCK_LOAD_AVERAGE=20 ./infracheck/checks/load-average-auto
if [[ $? != 0 ]]; then
echo " >> Test failed."
exit 1
fi

exit 0
24 changes: 24 additions & 0 deletions infracheck/checks-tests/load-average-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

echo " >> Assert that 1.5 core load is more than 1.0 core allowed"
MAX_LOAD=1.0 MOCK_LOAD_AVERAGE=1.5 ./infracheck/checks/load-average
if [[ $? != 1 ]]; then
echo " >> Test failed."
exit 1
fi

echo " >> Assert that 1.5 core load is more than 1.0 core allowed (using integer instead of float)"
MAX_LOAD=1 MOCK_LOAD_AVERAGE=1.5 ./infracheck/checks/load-average
if [[ $? != 1 ]]; then
echo " >> Test failed."
exit 1
fi

echo " >> Assert that load of 10.1 is ok, when we allow load of max. 15.0"
MAX_LOAD=15 MOCK_LOAD_AVERAGE=10.1 ./infracheck/checks/load-average
if [[ $? != 0 ]]; then
echo " >> Test failed."
exit 1
fi

exit 0
51 changes: 51 additions & 0 deletions infracheck/checks/load-average
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3

"""
<sphinx>
load-average
------------
Checks if the load average is not below specified number
Parameters:
- max_load (unit: processor cores, example: 5.0, default: 1)
- timing (default: 15. The load average time: 1, 5, 15)
</sphinx>
"""

import os
import sys


class LoadAverageAuto:
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')

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


if __name__ == '__main__':
app = LoadAverageAuto()
status, message = app.main(
timing=os.getenv('TIMING', '15'),
max_load=float(os.getenv('MAX_LOAD', 1))
)

print(message)
sys.exit(0 if status else 1)

98 changes: 98 additions & 0 deletions infracheck/checks/load-average-auto
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env python3

"""
<sphinx>
load-average-auto
-----------------
Checks if the load average is not more than 100%
Parameters:
- maximum_above (unit: processor cores, default: 0.5 - half of a core)
- timing (default: 15. The load average time: 1, 5, 15)
</sphinx>
"""

import os
import re
import sys


class LoadAverageAuto:
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

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


if __name__ == '__main__':
app = LoadAverageAuto()
status, message = app.main(
timing=os.getenv('TIMING', '15'),
maximum_above=float(os.getenv('MAXIMUM_ABOVE', 0.5))
)

print(message)
sys.exit(0 if status else 1)

0 comments on commit 7ff61d1

Please sign in to comment.