-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_redis.py
142 lines (124 loc) · 6.27 KB
/
check_redis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python
#
# Nagios plugin to monitor Redis service
#
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# <mantas@mantas.lt> wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return Mantas Smelevicius
# ----------------------------------------------------------------------------
#
# REQUIREMENTS
# - Python2.6+ or Python3
# - redis-py
#
# Changes
# v0.1 - Initial commit
# v0.2 - Rewrite code for Python2.6+ and Python3
import sys, os, socket, struct
import redis
from optparse import OptionParser
# Constants
EXIT_NAGIOS_OK = 0
EXIT_NAGIOS_WARN = 1
EXIT_NAGIOS_CRITICAL = 2
# Command line options
opt_parser = OptionParser()
opt_parser.add_option("-s", "--server", dest="server", help="Redis server to connect to.")
opt_parser.add_option("-p", "--port", dest="port", default=6379, help="Redis port to connect to. (Default: 6379)")
opt_parser.add_option("-P", "--password", dest="password", default=None, help="Redis password to use. Defaults to unauthenticated.")
opt_parser.add_option("-S", "--ssl", dest="ssl", default=False, action="store_true", help="Enable secure communication. (Default: False)")
opt_parser.add_option("-w", "--warn", dest="warn_threshold", help="Memory utlization (in MB) that triggers a warning status.")
opt_parser.add_option("-c", "--critical", dest="critical_threshold", help="Memory utlization (in MB) that triggers a critical status.")
opt_parser.add_option("-r", "--rss-warn", dest="rss_warn", default=None, help="RSS memory (in MB) that triggers a warning status.")
opt_parser.add_option("-R", "--rss-critical", dest="rss_critical", default=None, help="RSS memory (in MB) that triggers a critical status.")
opt_parser.add_option("-L", "--force-local", dest="force_local", action="store_true", help="Force local checks even if not localhost.")
opt_parser.add_option("-t", "--timeout", dest="timeout", default=10, type=int, help="How many seconds to wait for host to respond.")
args = opt_parser.parse_args()[0]
if args.server is None:
print('A Redis server (--server) must be supplied. Please see --help for more details.')
sys.exit(-1)
# can't check /proc unless on local
# (local routable IP addresses not accounted for)
is_local = args.force_local or (args.server in ['127.0.0.1', 'localhost', '::1'])
# only check RSS
check_fields = ["warn_threshold", "critical_threshold"]
if is_local:
check_fields += ["rss_warn", "rss_critical"]
args_dict = args.__dict__
for option in check_fields:
if args_dict[option] is None:
print('A %s %s must be supplied. Please see --help for more details.' % tuple(option.split("_")))
sys.exit(-1)
try:
value = (args.__dict__[option])
if int(value) < 0:
raise ValueError
else:
globals()[option] = int(value)
except ValueError as e:
print('A %s %s must be a positive integer. Please see --help for more details.' % tuple(option.split("_")))
sys.exit(-1)
# ================
# = Nagios check =
# ================
# Connection
try:
if args.password is not None:
redis_connection = redis.Redis(host=args.server, port=int(args.port), password=args.password, socket_timeout=args.timeout, ssl=args.ssl)
else:
redis_connection = redis.Redis(host=args.server, port=int(args.port), socket_timeout=args.timeout, ssl=args.ssl)
redis_info = redis_connection.info()
except (socket.error, redis.exceptions.ConnectionError, redis.exceptions.ResponseError, redis.exceptions.TimeoutError) as e:
print('CRITICAL: Problem establishing connection to Redis server %s: %s ' % (str(args.server), str(repr(e))))
sys.exit(EXIT_NAGIOS_CRITICAL)
# Redis VM
if redis_info.get("vm_conf_pages", None) is not None and redis_info.get("vm_stats_used_pages", None) is not None and int(redis_info["vm_conf_pages"]) < int(redis_info["vm_stats_used_pages"]):
if (float(redis_info["vm_conf_pages"]) / float(redis_info["vm_stats_used_pages"])) < 0.5:
print('CRITICAL: Redis is using %d VM pages of %d allowed' % (int(redis_info["vm_stats_used_pages"]), int(redis_info["vm_conf_pages"])))
sys.exit(EXIT_NAGIOS_CRITICAL)
else:
print('WARN: Redis is using %d VM pages of %d allowed' % (int(redis_info["vm_stats_used_pages"]), int(redis_info["vm_conf_pages"])))
sys.exit(EXIT_NAGIOS_CRITICAL)
# Redis memory usage
if redis_info["used_memory"] // 1024 // 1024 >= critical_threshold:
print('CRITICAL: Redis is using %dMB of RAM.' % (redis_info["used_memory"] // 1024 // 1024))
sys.exit(EXIT_NAGIOS_CRITICAL)
elif redis_info["used_memory"] // 1024 // 1024 >= warn_threshold:
print('WARN: Redis is using %dMB of RAM.' % (redis_info["used_memory"] // 1024 // 1024))
sys.exit(EXIT_NAGIOS_WARN)
# Redis uptime not available on Azure
if redis_info.get("uptime_in_days") is None:
redis_info["uptime_in_days"] = 'unknown'
# RSS memory usage
if is_local:
try:
pid = redis_info["process_id"]
rss = int(open('/proc/%d/status' % pid).read().split('\n')[15].split()[1]) // 1024
except IOError as e:
print('CRITICAL: can\'t open /proc/%d/status' % pid)
sys.exit(EXIT_NAGIOS_CRITICAL)
if rss >= rss_critical:
print('CRITICAL: Redis is using %dMB of RAM (RSS)' % rss)
sys.exit(EXIT_NAGIOS_CRITICAL)
if rss >= rss_warn:
print('WARN: Redis is using %d MB of RAM (RSS)' % rss)
sys.exit(EXIT_NAGIOS_WARN)
print('OK: Redis is using %dMB of RAM (%s RSS). Days Up: %s Clients: %s Version: %s' % \
( \
redis_info["used_memory"] // 1024 // 1024,
rss,
redis_info["uptime_in_days"],
redis_info["connected_clients"],
redis_info["redis_version"]
))
else:
print('OK: Redis is using %dMB of RAM. Days Up: %s Clients: %s Version: %s' % \
( \
redis_info["used_memory"] // 1024 // 1024,
redis_info["uptime_in_days"],
redis_info["connected_clients"],
redis_info["redis_version"]
))
sys.exit(EXIT_NAGIOS_OK)