2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2017 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.
28 def size_trend(check
, item
, resource
, levels
, used_mb
, size_mb
, timestamp
=None): # pylint: disable=function-redefined
29 """Trend computation for size related checks of disks, ram, etc.
30 Trends are computed in two steps. In the first step the delta to
31 the last check is computed, using a normal check_mk counter.
32 In the second step an average over that counter is computed to
33 make a long-term prediction.
36 This function is experimental and may change in future releases.
40 check (str): The name of the check, e.g. "df".
41 item (str): The name of the item, e.g. the mountpoint "/" for df.
42 resource (str): The resource in question, e.g. "disk", "ram", "swap".
43 levels (dict): Level parameters for the trend computation. Items:
44 "trend_range" : 24, # interval for the trend in hours
45 "trend_perfdata : True # generate perfomance data for trends
46 "trend_mb" : (10, 20), # MB of change during trend_range
47 "trend_perc" : (1, 2), # percent change during trend_range
48 "trend_timeleft" : (72, 48) # time left in hours until full
49 "trend_showtimeleft: True # display time left in infotext
50 The item "trend_range" is required. All other items are optional.
51 timestamp (float, optional): Time in secs used to calculate the rate
52 and average. Defaults to "None".
53 used_mb (float): Used space in MB.
54 size_mb (float): Max. available space in MB.
57 A tuple of (state, infotext, perfdata) for the trend computation.
58 If a MKCounterWrapped occurs (i.e. there is not enough data
59 present for the trend computation) the tuple (0, '', []) is
63 state
, infotext
, perfdata
, problems
= 0, '', [], []
68 range_hours
= levels
["trend_range"]
69 range_sec
= range_hours
* 3600.0
71 timestamp
= time
.time()
73 # compute current rate in MB/s by computing delta since last check
76 "%s.%s.delta" % (check
, item
), timestamp
, used_mb
, allow_negative
=True, onwrap
=ZERO
)
77 except MKCounterWrapped
:
78 # need more data for computing a trend
81 if levels
.get("trend_perfdata"):
82 perfdata
.append(("growth", rate
* H24
))
84 # average trend in MB/s, initialized with zero
85 rate_avg
= get_average("%s.%s.trend" % (check
, item
), timestamp
, rate
, range_sec
/ 60.0, True)
87 trend
= rate_avg
* range_sec
88 sign
= '+' if trend
> 0 else ""
89 infotext
+= ", trend: %s%s / %g hours" % \
90 (sign
, get_bytes_human_readable(trend
* MB
), range_hours
)
92 # levels for performance data
93 warn_perf
, crit_perf
= None, None
95 # apply levels for absolute growth in MB / interval
96 trend_mb
= levels
.get("trend_mb")
99 warn_perf
, crit_perf
= wa
, cr
101 problems
.append("growing too fast (warn/crit at %s/%s per %.1f h)(!" % (
102 get_bytes_human_readable(wa
* MB
),
103 get_bytes_human_readable(cr
* MB
),
106 state
= max(1, state
)
112 # apply levels for growth relative to filesystem size
113 trend_perc
= levels
.get("trend_perc")
115 wa_perc
, cr_perc
= trend_perc
116 wa
= wa_perc
/ 100.0 * size_mb
117 cr
= cr_perc
/ 100.0 * size_mb
118 if warn_perf
is not None:
119 warn_perf
= min(warn_perf
, wa
)
120 crit_perf
= min(crit_perf
, cr
)
122 warn_perf
, crit_perf
= wa
, cr
124 problems
.append("growing too fast (warn/crit at %.3f%%/%.3f%% per %.1f h)(!" %
125 (wa_perc
, cr_perc
, range_hours
))
126 state
= max(1, state
)
132 # compute time until filesystem is full (only for positive trend, of course)
134 # The start value of hours_left is negative. The pnp graph and the perfometer
135 # will interpret this as inifinite -> not growing
139 def format_hours(hours
):
141 return "more than a year"
142 elif hours
> 90 * 24:
143 return "%0d months" % (hours
/ (30 * 24))
144 elif hours
> 4 * 7 * 24: # 4 weeks
145 return "%0d weeks" % (hours
/ (7 * 24))
146 elif hours
> 7 * 24: # 1 week
147 return "%0.1f weeks" % (hours
/ (7 * 24))
148 elif hours
> 2 * 24: # 2 days
149 return "%0.1f days" % (hours
/ 24)
150 return "%d hours" % hours
152 hours_left
= (size_mb
- used_mb
) / trend
* range_hours
153 hours_txt
= format_hours(hours_left
)
155 timeleft
= levels
.get("trend_timeleft")
160 problems
.append("only %s until %s full(!!)" % (hours_txt
, resource
))
161 elif hours_left
<= wa
:
162 state
= max(state
, 1)
163 problems
.append("only %s until %s full(!)" % (hours_txt
, resource
))
164 elif hours_left
<= wa
* 2 or levels
.get("trend_showtimeleft"):
165 problems
.append("time left until %s full: %s" % (resource
, hours_txt
))
166 elif levels
.get("trend_showtimeleft"):
167 problems
.append("time left until %s full: %s" % (resource
, hours_txt
))
169 if levels
.get("trend_perfdata"):
173 (warn_perf
/ range_sec
* H24
) if warn_perf
is not None else None,
174 (crit_perf
/ range_sec
* H24
) if crit_perf
is not None else None,
176 size_mb
/ range_hours
,
179 if levels
.get("trend_showtimeleft"):
180 perfdata
.append(("trend_hoursleft", hours_left
))
183 infotext
+= " - %s" % ", ".join(problems
)
185 return state
, infotext
, perfdata