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 factory_settings
["veeam_client"] = {
28 "age": (108000, 172800), # 30h/2d
32 def parse_veeam_client(info
):
35 if line
[0] == "Status":
39 # Prevent empty entries
41 elif line
[0] == 'JobName':
45 data
[last_found
]['Status'] = last_status
47 if last_status
and len(line
) == 2:
48 data
[last_found
][line
[0]] = line
[1]
52 def inventory_veeam_client(parsed
):
53 for job
in parsed
.keys():
57 def check_veeam_client(item
, params
, parsed
):
58 # Fallback for old None item version
59 #FIXME Can be remvoed in CMK 2.0
60 if item
is None and len(parsed
) > 0:
61 item
= parsed
.keys()[0]
66 return 3, "Client not found in agent output"
72 # Append current Status to Output
73 if data
['Status'] == 'Warning':
75 if data
['Status'] == 'Failed':
77 infotexts
.append("Status: %s" % data
['Status'])
79 # Only output the Job name
80 if data
.get('JobName'):
81 infotexts
.append("Job: %s" % data
['JobName'])
86 TotalSizeByte
= int(data
['TotalSizeByte'])
87 perfdata
.append(('totalsize', TotalSizeByte
))
88 size_info
.append(get_bytes_human_readable(TotalSizeByte
))
89 size_legend
.append("total")
91 # Output ReadSize and TransferedSize if available
92 if "ReadSizeByte" in data
:
93 ReadSizeByte
= int(data
['ReadSizeByte'])
94 perfdata
.append(('readsize', ReadSizeByte
))
95 size_info
.append(get_bytes_human_readable(ReadSizeByte
))
96 size_legend
.append("read")
98 if "TransferedSizeByte" in data
:
99 TransferedSizeByte
= int(data
['TransferedSizeByte'])
100 perfdata
.append(('transferredsize', TransferedSizeByte
))
101 size_info
.append(get_bytes_human_readable(TransferedSizeByte
))
102 size_legend
.append("transferred")
104 infotexts
.append("Size (%s): %s" % ("/".join(size_legend
), "/ ".join(size_info
)))
106 # Bugged agent plugins were reporting . instead of : as separator for
107 # the time. This has been fixed in the agent, but be compatible to old agent.
109 if "StopTime" in data
and timesep
not in data
['StopTime']:
112 # Check Stop time in any case, that we can catch hanging backups
113 if "StopTime" not in data
:
115 infotexts
.append("No complete Backup(!!)")
116 # If the Backup currently is running, the stop time is strange.
117 elif data
['StopTime'] != "01.01.1900 00" + timesep
+ "00" + timesep
+ "00":
118 stop_time
= time
.mktime(
119 time
.strptime(data
['StopTime'], "%d.%m.%Y %H" + timesep
+ "%M" + timesep
+ "%S"))
121 age
= now
- stop_time
122 warn
, crit
= params
['age']
128 levels
= " (Warn/Crit: %s/%s)" % (get_age_human_readable(warn
),
129 get_age_human_readable(crit
))
131 state
= max(state
, 1)
133 levels
= " (Warn/Crit: %s/%s)" % (get_age_human_readable(warn
),
134 get_age_human_readable(crit
))
135 infotexts
.append("Last backup: %s ago%s%s" % (get_age_human_readable(age
), label
, levels
))
137 # Check duration only if currently not running
138 if data
['Status'] not in ['InProgress', 'Pending']:
139 # Information may missing
140 if data
.get('DurationDDHHMMSS'):
142 days
, hours
, minutes
, seconds
= map(int, data
['DurationDDHHMMSS'].split(':'))
144 duration
+= minutes
* 60
145 duration
+= hours
* 60 * 60
146 duration
+= days
* 60 * 60 * 24
147 infotexts
.append("Duration: %s" % get_age_human_readable(duration
))
148 perfdata
.append(('duration', duration
))
150 AvgSpeedBps
= int(data
['AvgSpeedBps'])
151 perfdata
.append(('avgspeed', AvgSpeedBps
))
152 infotexts
.append(("Average Speed: %s/s" % get_bytes_human_readable(AvgSpeedBps
)))
154 # Append backup server if available
155 if "BackupServer" in data
:
156 infotexts
.append("Backup server: %s" % data
['BackupServer'])
158 return state
, ", ".join(infotexts
), perfdata
161 check_info
["veeam_client"] = {
162 'parse_function': parse_veeam_client
,
163 'check_function': check_veeam_client
,
164 'inventory_function': inventory_veeam_client
,
165 'service_description': 'VEEAM Client %s',
166 'group': 'veeam_backup',
167 'default_levels_variable': 'veeam_client',
168 'has_perfdata': True,