2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
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 # .--output--------------------------------------------------------------.
29 # | ___ _ _| |_ _ __ _ _| |_ |
30 # | / _ \| | | | __| '_ \| | | | __| |
31 # | | (_) | |_| | |_| |_) | |_| | |_ |
32 # | \___/ \__,_|\__| .__/ \__,_|\__| |
34 # '----------------------------------------------------------------------'
36 # Example output from agent:
39 # misses = 27664604758
40 # demand_data_hits = 23694052185
41 # demand_data_misses = 2806853416
42 # demand_metadata_hits = 73187550363
43 # demand_metadata_misses = 1557349557
44 # prefetch_data_hits = 3100882779
45 # prefetch_data_misses = 21062611239
46 # prefetch_metadata_hits = 6277502677
47 # prefetch_metadata_misses = 2237790546
48 # mru_hits = 44007947284
49 # mru_ghost_hits = 2418664836
50 # mfu_hits = 52875478045
51 # mfu_ghost_hits = 1458768458
52 # deleted = 25139978315
53 # recycle_miss = 3965481664
54 # mutex_miss = 323199589
55 # evict_skip = 2543918629307
57 # evict_l2_eligible = 253548767148544
58 # evict_l2_ineligible = 36185885241856
59 # hash_elements = 182514
60 # hash_elements_max = 388216
61 # hash_collisions = 6825894732
70 # data_size = 951095808
71 # other_size = 642656472
81 # l2_writes_hdr_miss = 0
82 # l2_evict_lock_retry = 0
83 # l2_evict_reading = 0
84 # l2_free_on_write = 0
90 # memory_throttle_count = 439874
92 # arc_tempreserve = 0 MB
93 # arc_meta_used = 1322 MB
94 # arc_meta_limit = 80 MB
95 # arc_meta_max = 2077 MB
97 # newer output under solaris 11.3 with old agent
100 # target size (c) = 1027788 MB
101 # target mru_size (p) = 64236 MB
105 # data_size = 43123 MB
106 # other_size = 2988 MB
107 # rawdata_size = 0 MB
108 # meta_used = 3628 MB
111 # memory_throttle_count = 0
113 # arc_tempreserve = 0 MB
114 # mfu_size = 30605 MB
115 # mru_size = 11601 MB
117 # newer output under solaris 11.3 with updated agent
118 # <<<zfs_arc_cache>>>
119 # buf_size = 742832600
121 # c_max = 1077714329600
124 # crtime = 6389056,11403263
125 # data_freed = 2633453157248
126 # data_size = 45014421888
128 # demand_data_hits = 645028929
129 # demand_data_misses = 9656913
130 # demand_metadata_hits = 3819285336
131 # demand_metadata_misses = 1934895
132 # evict_l2_cached = 0
133 # evict_l2_eligible = 0
134 # evict_l2_ineligible = 607708484608
135 # evict_prefetch = 977715200
136 # evicted_mfu = 44603686912
137 # evicted_mru = 563104797696
139 # hash_chains = 70415
140 # hash_collisions = 2812966
141 # hash_elements = 1585475
142 # hash_elements_max = 1810662
144 # l2_abort_lowmem = 0
151 # l2_misses = 7259729
152 # l2_persistence_hits = 0
158 # l2_writes_error = 0
160 # memory_throttle_count = 0
162 # meta_max = 4519225600
163 # meta_used = 3836680704
164 # mfu_ghost_hits = 27965
165 # mfu_hits = 4444241817
167 # mru_ghost_hits = 499269
168 # mru_hits = 47780363
170 # other_size = 3058023880
172 # prefetch_behind_prefetch = 429897
173 # prefetch_data_hits = 1849310
174 # prefetch_joins = 1305700
175 # prefetch_meta_size = 35824224
176 # prefetch_metadata_hits = 858900
177 # prefetch_reads = 3616694
178 # prefetch_size = 9486336
181 # snaptime = 6646791,81811455
185 #misses = 29159034052
186 #demand_data_hits = 21894170403
187 #demand_data_misses = 6555284601
188 #demand_metadata_hits = 67915356653
189 #demand_metadata_misses = 2138181167
190 #prefetch_data_hits = 6162208911
191 #prefetch_data_misses = 19200459846
192 #prefetch_metadata_hits = 1826423014
193 #prefetch_metadata_misses = 1265108438
194 #mru_hits = 32456530155
195 #mru_ghost_hits = 2084134895
196 #mfu_hits = 57357428725
197 #mfu_ghost_hits = 1416265946
198 #deleted = 26434603017
199 #recycle_miss = 2014989945
200 #mutex_miss = 548212067
201 #evict_skip = 1758367956525
203 #evict_l2_eligible = 236579643061760
204 #evict_l2_ineligible = 68829096635392
205 #hash_elements = 235200
206 #hash_elements_max = 441047
207 #hash_collisions = 5893650106
216 #data_size = 998181888
217 #other_size = 664157400
227 #l2_writes_hdr_miss = 0
228 #l2_evict_lock_retry = 0
229 #l2_evict_reading = 0
230 #l2_free_on_write = 0
236 #memory_throttle_count = 1014537
238 #arc_tempreserve = 0 MB
239 #arc_meta_used = 1196 MB
240 #arc_meta_limit = 512 MB
241 #arc_meta_max = 2132 MB
245 # parses agent output in a structure like
246 # {'arc_meta_limit': 80,
247 # 'arc_meta_max': 2077,
248 # 'arc_meta_used': 1322,
253 def parse_zfs_arc_cache(info
):
256 if not (len(line
) >= 3 and line
[1] == "=" and line
[2].isdigit()):
261 if line
[3].lower() == "mb":
263 elif line
[3].lower() == "kb":
265 parsed
[line
[0]] = int(line
[2]) * factor
269 # .--cache---------------------------------------------------------------.
271 # | ___ __ _ ___| |__ ___ |
272 # | / __/ _` |/ __| '_ \ / _ \ |
273 # | | (_| (_| | (__| | | | __/ |
274 # | \___\__,_|\___|_| |_|\___| |
276 # '----------------------------------------------------------------------'
279 def inventory_zfs_arc_cache(parsed
):
280 if parsed
.get("hits") and parsed
.get("misses"):
281 return [(None, None)]
285 def check_zfs_arc_cache(_no_item
, _no_params
, parsed
):
286 # Solaris >= 11.3 do not provide these data pretech_*data
287 for key
in ["", "prefetch_data_", "prefetch_metadata_"]:
288 if "%shits" % key
in parsed
and "%smisses" % key
in parsed
:
289 total_hits_misses
= parsed
["%shits" % key
] + parsed
["%smisses" % key
]
290 human_key
= key
.replace("_", " ")
292 if total_hits_misses
:
293 hit_ratio
= float(parsed
["%shits" % key
]) / total_hits_misses
* 100
294 yield 0, "%sHit Ratio: %0.2f%%" % (human_key
.title(), hit_ratio
), \
295 [("%shit_ratio" % key
, hit_ratio
, None, None, 0, 100)]
298 yield 0, "No %sHits or Misses" % human_key
, \
299 [("%shit_ratio" % key
, 0, None, None, 0, 100)]
302 if "size" in parsed
.keys():
303 size_bytes
= parsed
["size"]
304 size_readable
= get_bytes_human_readable(size_bytes
)
305 yield 0, "Cache size: %s" % size_readable
, \
306 [("size", float(size_bytes
), None, None, 0)]
309 # these values may be missing, this is ok too
310 # in this case just do not report these values
311 if "arc_meta_used" in parsed
.keys() and "arc_meta_limit" in parsed
.keys() and \
312 "arc_meta_max" in parsed
.keys():
313 yield 0, "Arc Meta %s used, Limit %s, Max %s" % \
314 (get_bytes_human_readable(parsed
["arc_meta_used"]),
315 get_bytes_human_readable(parsed
["arc_meta_limit"]),
316 get_bytes_human_readable(parsed
["arc_meta_max"])), \
317 [("arc_meta_used", float(parsed
["arc_meta_used"]), None, None, 0),
318 ("arc_meta_limit", float(parsed
["arc_meta_limit"]), None, None, 0),
319 ("arc_meta_max", float(parsed
["arc_meta_max"]), None, None, 0)]
322 check_info
["zfs_arc_cache"] = {
323 "parse_function": parse_zfs_arc_cache
,
324 "check_function": check_zfs_arc_cache
,
325 "inventory_function": inventory_zfs_arc_cache
,
326 "service_description": "ZFS arc cache",
327 "has_perfdata": True,
331 # .--L2 cache------------------------------------------------------------.
333 # | | | |___ \ ___ __ _ ___| |__ ___ |
334 # | | | __) | / __/ _` |/ __| '_ \ / _ \ |
335 # | | |___ / __/ | (_| (_| | (__| | | | __/ |
336 # | |_____|_____| \___\__,_|\___|_| |_|\___| |
338 # '----------------------------------------------------------------------'
341 def inventory_zfs_arc_cache_l2(parsed
):
342 # if l2_size == 0 there is no l2 cache available at all
343 if "l2_size" in parsed
.keys() and parsed
["l2_size"] > 0:
344 return [(None, None)]
348 def check_zfs_arc_cache_l2(_no_item
, _no_params
, parsed
):
351 message
= "ZFS arc cache L2:"
354 if "l2_hits" in parsed
.keys() and "l2_misses" in parsed
.keys():
355 l2_hit_ratio
= float(parsed
["l2_hits"]) / (parsed
["l2_hits"] + parsed
["l2_misses"]) * 100
356 message
+= " L2 hit ratio: %0.2f%%" % l2_hit_ratio
357 perfdata
.append(("l2_hit_ratio", l2_hit_ratio
, None, None, 0, 100))
360 message
+= " no info about L2 hit ratio available"
361 perfdata
.append(("l2_hit_ratio", 0, None, None, 0, 100))
365 if "l2_size" in parsed
.keys():
366 message
+= ", L2 size: %s" % get_bytes_human_readable(parsed
["l2_size"])
367 perfdata
.append(("l2_size", float(parsed
["l2_size"]), None, None, 0))
369 message
+= ", no info about L2 size available"
370 perfdata
.append(("l2_size", 0, None, None, 0))
373 return status
, message
, perfdata
376 check_info
["zfs_arc_cache.l2"] = {
377 "check_function": check_zfs_arc_cache_l2
,
378 "inventory_function": inventory_zfs_arc_cache_l2
,
379 "service_description": "ZFS arc cache L2",
380 "has_perfdata": True,