Cleanup config.nodes_of
[check_mk.git] / checks / mem.include
blobe0345b02cc0f0a2b7dcc8ca10ca56b8f71789746
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 memused_default_levels = (150.0, 200.0)
29 factory_settings["memory_default_levels"] = {
30 "levels": memused_default_levels,
34 # Parse /proc/meminfo into the canonical form: into bytes, not kB
35 # This function is also used by the ps check
36 def parse_proc_meminfo_bytes(info):
37 meminfo = {}
38 for line in info:
39 value = int(line[1])
40 if len(line) > 2 and line[2] == 'kB':
41 value *= 1024
42 meminfo[line[0][:-1]] = value
43 return meminfo
46 def check_memory(params, meminfo):
47 swapused_kb = meminfo['SwapTotal'] - meminfo['SwapFree']
48 swapused = swapused_kb * 1024.0
49 memused_kb = meminfo['MemTotal'] - meminfo['MemFree']
50 memused = memused_kb * 1024.0
52 # Buffers and Cached are optional. On Linux both mean basically the same.
53 caches_kb = meminfo.get('Buffers', 0) + meminfo.get('Cached', 0)
54 caches = caches_kb * 1024.0
56 # Size of Pagetable on Linux can be relevant e.g. on ORACLE
57 # servers with much memory, that do not use HugeTables. We account
58 # that for used
59 pagetables_kb = meminfo.get('PageTables', 0)
60 pagetables_mb = pagetables_kb / 1024.0
62 totalused_kb = (swapused_kb + memused_kb - caches_kb + pagetables_kb)
63 totalused_mb = totalused_kb / 1024.0
64 totalused = totalused_kb * 1024.0
65 totalmem_kb = meminfo['MemTotal']
66 totalmem_mb = totalmem_kb / 1024.0
67 totalmem = totalmem_kb * 1024.0
68 totalused_perc = 100 * (float(totalused_kb) / float(totalmem_kb))
69 totalvirt_mb = (meminfo['SwapTotal'] + meminfo['MemTotal']) / 1024.0
71 if isinstance(params, tuple):
72 params = {"levels": params}
73 warn, crit = params["levels"]
75 details = []
76 if swapused:
77 details.append("%s SWAP" % render.fmt_bytes(swapused))
79 if pagetables_kb:
80 details.append("%s Pagetables" % render.fmt_bytes(pagetables_kb * 1024.0))
82 if details:
83 details.insert(0, "%s RAM" % render.fmt_bytes(memused - caches))
84 details_txt = " + ".join(details) + ", "
85 else:
86 details_txt = ""
88 if meminfo["SwapTotal"]:
89 swap_txt = (" + %s SWAP" % render.fmt_bytes(meminfo["SwapTotal"]))
90 else:
91 swap_txt = ""
93 infotext = "%s used (%sthis is %.1f%% of %s RAM%s)" % \
94 (render.fmt_bytes(totalused), details_txt,
95 totalused_perc, render.fmt_bytes(totalmem), swap_txt)
97 # Take into account averaging
98 average_min = params.get("average")
99 if average_min:
100 totalused_mb_avg = get_average(
101 "mem.used.total", time.time(), totalused_mb, average_min, initialize_zero=False)
102 totalused_perc_avg = totalused_mb_avg / totalmem_mb * 100
103 infotext += ", %d min average %.1f%%" % (average_min, totalused_perc_avg)
104 comp_mb = totalused_mb_avg
105 else:
106 comp_mb = totalused_mb
108 # levels may be given either in int -> MB or in float -> percentages. So convert
109 # effective levels to MB now
110 if isinstance(warn, float):
111 warn_mb = int(warn / 100.0 * totalmem_mb)
112 crit_mb = int(crit / 100.0 * totalmem_mb)
113 leveltext = lambda x: "%.1f%%" % x
114 else:
115 warn_mb = warn
116 crit_mb = crit
117 leveltext = lambda x: "%.2f GB" % (x / 1024.0)
119 # Prepare performance data
120 perfdata = [
121 ('ramused', (memused_kb - caches_kb) / 1024, None, None, 0, totalmem_mb),
122 ('swapused', swapused_kb / 1024, None, None, 0, meminfo['SwapTotal'] / 1024),
123 ('memused', totalused_mb, warn_mb, crit_mb, 0, totalvirt_mb),
126 if average_min:
127 perfdata.append(('memusedavg', totalused_mb_avg))
129 # Check levels
130 state = 0
131 if warn_mb > 0: # positive levels - used memory
132 if comp_mb >= crit_mb:
133 state = 2
134 infotext += ", critical at %s used" % leveltext(crit)
135 elif comp_mb >= warn_mb:
136 state = 1
137 infotext += ", warning at %s used" % leveltext(warn)
138 else: # negative levels - free memory
139 freemem_mb = totalvirt_mb - comp_mb
140 if freemem_mb <= -crit_mb:
141 state = 2
142 infotext += ", critical at %s free" % leveltext(-crit)
143 elif freemem_mb <= -warn_mb:
144 state = 1
145 infotext += ", warning at %s free" % leveltext(-warn)
147 # Add additional metrics, provided by Linux.
148 mapped = meminfo.get('Mapped')
149 if mapped:
150 mapped_mb = int(mapped) / 1024
151 committed_as_mb = int(meminfo.get('Committed_AS', 0)) / 1024
152 shared_mb = int(meminfo.get('Shmem', 0)) / 1024
154 perfdata += [
155 ('mapped', mapped_mb),
156 ('committed_as', committed_as_mb),
157 ('pagetables', pagetables_mb),
158 ('shared', shared_mb),
160 infotext += ", %.1f mapped, %.1f committed, %.1f shared" % \
161 (mapped_mb / 1024.0, committed_as_mb / 1024.0, shared_mb / 1024.0)
163 return state, infotext, perfdata