Refactoring: Changed all check parameters starting with an 'o' to the new rulespec...
[check_mk.git] / checks / inotify
blob5072e7c235654860ed4968665e996dfa65786040
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2016 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 import os
29 # <<<inotify:sep(9)>>>
30 # monitored folder /tmp/noti
31 # monitored file /tmp/noti/test
32 # monitored file /tmp/noti/other
33 # 1465470055 modify /tmp/noti/test 5 1465470055
34 # 1465470055 open /tmp/noti/test 5 1465470055
35 # 1465470055 modify /tmp/noti/test 5 1465470055
36 # 1465470056 modify /tmp/noti/test 5 1465470056
37 # 1465470056 open /tmp/noti/test 5 1465470056
40 def parse_inotify(info):
41 parsed = {
42 "meta": {
43 "warnings": {}
45 "configured": {
46 "file": set([]),
47 "folder": set([])
49 "stats": {}
51 for line in info:
52 if line[0].startswith("warning"):
53 parsed["meta"]["warnings"].setdefault(line[1], 0)
54 parsed["meta"]["warnings"][line[1]] += 1
55 continue
56 elif line[0].startswith("configured"):
57 parsed["configured"][line[1]].add(line[2])
58 continue
60 timestamp, mode, filepath = line[:3]
61 parsed["stats"].setdefault(filepath, [])
62 folderpath = os.path.dirname(filepath)
63 parsed["stats"].setdefault(folderpath, [])
65 file_dict = {}
66 file_dict["timestamp"] = int(timestamp)
67 file_dict["mode"] = mode
68 # Unused
69 if len(line) > 3:
70 file_dict["size"] = line[3]
71 file_dict["mtime"] = line[4]
72 parsed["stats"][filepath].append(file_dict)
73 parsed["stats"][folderpath].append(file_dict)
75 return parsed
78 def inventory_inotify(parsed):
79 for what in ["file", "folder"]:
80 for path in parsed["configured"][what]:
81 yield "%s %s" % (what.title(), path), {}
84 def check_inotify(item, params, parsed):
85 what, path = item.split(" ", 1)
86 if path not in parsed["configured"][what.lower()]:
87 return
89 data = parsed["stats"].get(path, {})
91 last_status = get_item_state(None, default={})
92 for file_dict in data:
93 mode = file_dict["mode"]
94 for key, value in file_dict.items():
95 last_status.setdefault(mode, {})
96 last_status[mode][key] = value
98 set_item_state(None, last_status)
99 now = time.time()
101 def check_levels(what):
102 for mode, warn, crit in params.get("age_last_operation", []):
103 if mode != what:
104 continue
105 timestamp = last_status[what]["timestamp"]
106 if now - timestamp >= crit:
107 return (2, "> %s" % get_age_human_readable(crit))
108 elif now - timestamp >= warn:
109 return (1, "> %s" % get_age_human_readable(warn))
110 return
112 for mode in sorted(last_status.keys()):
113 attr = last_status[mode]
114 levels_info = check_levels(mode)
115 if levels_info:
116 state = levels_info[0]
117 yield state, "Last %s: %s ago (%s)" % (
118 mode.title(), get_age_human_readable(now - attr["timestamp"]), levels_info[1])
119 else:
120 yield 0, "Last %s: %s ago" % (mode.title(),
121 get_age_human_readable(now - attr["timestamp"]))
123 for mode, _warn, _crit in params.get("age_last_operation", []):
124 if mode not in last_status:
125 yield 3, "Last %s unknown" % mode.title()
127 warnings = parsed.get("meta", {}).get("warnings")
128 if warnings:
129 yield 1, "Incomplete data!"
130 for warning, count in warnings.items():
131 yield 1, "%d Warnings: %s" % (count, warning)
133 if not last_status:
134 yield 0, "No data available yet"
137 check_info["inotify"] = {
138 "parse_function": parse_inotify,
139 "inventory_function": inventory_inotify,
140 "check_function": check_inotify,
141 "service_description": "INotify %s",
142 "group": "inotify"