Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
# Usage
```
usage: check_maxscale [-h] --expected-number-of-servers
usage: check_maxscale [-h] [--cli CLI] --expected-number-of-servers
EXPECTED_NUMBER_OF_SERVERS
[--expected-master EXPECTED_MASTER]
[--connections-threshold CONNECTIONS_THRESHOLD]
[--sessions-threshold SESSIONS_THRESHOLD] [--verbose]

Nagios check to monitor the MaxScale SQL proxy.

optional arguments:
-h, --help show this help message and exit
--cli CLI, -i CLI CLI command we should use (maxadmin/maxctrl) (default
maxadmin)
--expected-number-of-servers EXPECTED_NUMBER_OF_SERVERS, -n EXPECTED_NUMBER_OF_SERVERS
Expected number of backend server
--connections-threshold CONNECTIONS_THRESHOLD
--expected-master EXPECTED_MASTER, -m EXPECTED_MASTER
Expected backend master server
--connections-threshold CONNECTIONS_THRESHOLD, -c CONNECTIONS_THRESHOLD
Alert if a server has more connections than this
threshold (default 500)
--sessions-threshold SESSIONS_THRESHOLD
--sessions-threshold SESSIONS_THRESHOLD, -s SESSIONS_THRESHOLD
Alert if there are more sessions than this threshold
(default 1000)
--verbose, -v Print detailed information
Expand Down
68 changes: 53 additions & 15 deletions check_maxscale
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Date: 2018-04-03
# Purpose: Nagios check to monitor the MaxScale SQL proxy.
#
# This script uses the maxadmin CLI to read the status of MaxScale.
# This script uses the maxadmin/maxctrl CLI to read the status of MaxScale.
#
# Usage: see --help
#
Expand All @@ -20,6 +20,7 @@ Server = namedtuple('Server', 'name address port connections status')
Session = namedtuple('Session', 'id client service state')
Monitor = namedtuple('Monitor', 'name status')
Problem = namedtuple('Problem', 'message severity')
cli = {}

OK = 0
WARNING = 1
Expand All @@ -33,6 +34,15 @@ def main(args):
monitors = []
problems = []

cli['name'] = args.cli
if (cli['name'] == 'maxadmin'):
cli['option'] = ''
cli['fieldseparator'] = '|'
elif (cli['name'] == 'maxctrl'):
cli['option'] = '--tsv'
cli['fieldseparator'] = '\t'


try:
servers = maxadmin_list_servers()
sessions = maxadmin_list_sessions()
Expand All @@ -44,7 +54,7 @@ def main(args):
))

problems.extend(
check_servers(servers, args.expected_number_of_servers, args.connections_threshold) + \
check_servers(servers, args.expected_number_of_servers, args.connections_threshold, args.expected_master) + \
check_sessions(sessions, args.sessions_threshold) + \
check_monitors(monitors)
)
Expand Down Expand Up @@ -77,18 +87,18 @@ def main(args):
def maxadmin_list_servers():
"""Return the servers known to MaxScale.

The command 'maxadmin list servers' is used.
The maxscale cli command 'list servers' is used.
"""
servers = []

devnull = open(os.devnull, 'w')
for line in subprocess.check_output(
['maxadmin', 'list', 'servers'],
[cli['name'], 'list', 'servers', cli['option']],
stderr=devnull,
close_fds=True,
).split('\n'):
try:
fields = [field.strip() for field in line.split('|')]
fields = [field.strip() for field in line.split(cli['fieldseparator'])]
servers.append(Server(
name=fields[0],
address=fields[1],
Expand All @@ -106,20 +116,20 @@ def maxadmin_list_servers():
def maxadmin_list_sessions():
"""Return the sessions established to MaxScale.

The command 'maxadmin list sessions' is used.
The maxscale cli command 'list sessions' is used.
"""
sessions = []

devnull = open(os.devnull, 'w')
for line in subprocess.check_output(
['maxadmin', 'list', 'sessions'],
[cli['name'], 'list', 'sessions', cli['option']],
stderr=devnull,
close_fds=True,
).split('\n'):
try:
fields = [field.strip() for field in line.split('|')]
fields = [field.strip() for field in line.split(cli['fieldseparator'])]
sessions.append(Session(
id=int(fields[0]),
id=fields[0],
client=fields[1],
service=fields[2],
state=fields[3],
Expand All @@ -134,18 +144,18 @@ def maxadmin_list_sessions():
def maxadmin_list_monitors():
"""Return the monitors configured in MaxScale.

The command 'maxadmin list monitors' is used.
The maxscale cli command 'list monitors' is used.
"""
monitors = []

devnull = open(os.devnull, 'w')
for line in subprocess.check_output(
['maxadmin', 'list', 'monitors'],
[cli['name'], 'list', 'monitors', cli['option']],
stderr=devnull,
close_fds=True,
).split('\n'):
try:
fields = [field.strip() for field in line.split('|')]
fields = [field.strip() for field in line.split(cli['fieldseparator'])]
# Ignore the header line
if fields[1] != 'Status':
monitors.append(Monitor(
Expand All @@ -159,14 +169,16 @@ def maxadmin_list_monitors():
return monitors


def check_servers(servers, expected_number_of_servers, connections_threshold):
def check_servers(servers, expected_number_of_servers, connections_threshold, expected_master):
problems = []
problems.append(check_servers_count(len(servers), expected_number_of_servers))
problems.append(check_servers_no_master(servers))

for server in servers:
problems.append(check_server_status(server))
problems.append(check_server_connections(server, connections_threshold))
if (expected_master and 'Master' in server.status):
problems.append(check_master(server, expected_master))

return [p for p in problems if p is not None]

Expand Down Expand Up @@ -199,6 +211,17 @@ def check_servers_no_master(servers):
return None


def check_master(server,expected_master):
"""Return a problem if expected master backend server is not the master."""
if (server.name != expected_master):
return Problem(
message='Server {0} is not the expected master {1}'.format(server.name,expected_master),
severity=WARNING,
)

return None


def check_server_status(server):
"""Return a problem if the server status isn't "normal"."""
if 'Maintenance' in server.status:
Expand Down Expand Up @@ -308,6 +331,9 @@ def print_message(problems):
print('OK - No problem detected on MaxScale')


# Default cli command
DEFAULT_CLI_COMMAND = 'maxadmin'

# Those thresholds are just a guess, they are maybe way to low/high...
DEFAULT_CONNECTIONS_THRESHOLD = 500
DEFAULT_SESSIONS_THRESHOLD = 1000
Expand All @@ -317,14 +343,26 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Nagios check to monitor the MaxScale SQL proxy.',
)
parser.add_argument(
'--cli', '-i',
default=DEFAULT_CLI_COMMAND,
help=(
'CLI command we should use (maxadmin/maxctrl) '
'(default {0})'.format(DEFAULT_CLI_COMMAND)
),
)
parser.add_argument(
'--expected-number-of-servers', '-n',
required=True,
type=int,
help='Expected number of backend server',
)
parser.add_argument(
'--connections-threshold',
'--expected-master', '-m',
help='Expected backend master server',
)
parser.add_argument(
'--connections-threshold', '-c',
type=int,
default=DEFAULT_CONNECTIONS_THRESHOLD,
help=(
Expand All @@ -333,7 +371,7 @@ if __name__ == '__main__':
),
)
parser.add_argument(
'--sessions-threshold',
'--sessions-threshold', '-s',
type=int,
default=DEFAULT_SESSIONS_THRESHOLD,
help=(
Expand Down