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.
29 # TUX2|COMPLETED|2015-01-02_07:05:59|2015-01-02_07:05:59|DB_INCR|2|335|8485138
33 # TUX2 COMPLETED 2014-07-08_17:27:59 2014-07-08_17:29:35 DB_INCR 32
34 # TUX2 COMPLETED 2014-07-08_17:30:02 2014-07-08_17:30:06 ARCHIVELOG 121
36 # Columns: SID STATUS START END BACKUPTYPE BACKUPAGE
38 # Create DB_INCR_<Level> checks when parameter is True
39 # Set this to False for old behavior. This is required for the service
40 # discovery and can't be set as a inventory parameter.
41 # This will be removed in a later version of Check_MK. Don't use it for new installations!
42 inventory_oracle_rman_incremental_details
= True
45 def parse_oracle_rman(info
):
52 # Check for query errors
53 err
= oracle_handle_ora_errors(line
)
55 continue # ignore ancient agent outputs
56 elif isinstance(err
, tuple):
60 # we leave the llop with break when item is found except for DB_INCR_0
61 # later we need to restore the values for DB_INCR_0 due to possivle
62 # overwrite with new line from info
68 sid
, status
, _start
, _end
, backuptype
, backupage
= line
69 item
= "%s.%s" % (sid
, backuptype
)
75 sid
, status
, _not_used_1
, _end
, backuptype
, backuplevel
, backupage
, backupscn
= line
79 backupscn
= int(backupscn
)
81 if backuptype
== 'DB_INCR':
83 if inventory_oracle_rman_incremental_details
:
84 item
= "%s.%s_%s" % (sid
, backuptype
, backuplevel
)
86 # This is for really old plugins without an information for the backuplevel
87 item
= "%s.%s" % (sid
, backuptype
)
89 item
= "%s.%s" % (sid
, backuptype
)
95 backupage
= int(backupage
)
97 except (ValueError, TypeError):
104 "backuptype": backuptype
,
105 "backuplevel": backuplevel
,
106 "backupage": backupage
,
108 "backupscn": backupscn
,
109 "used_incr_0": False, # True when last incr0 is newer then incr1
112 # take the most current backupage in clustered environments
113 if parsed
[item
]['backupage'] is None or parsed
[item
]['backupage'] > backupage
:
114 parsed
[item
].update({"backupage": backupage
})
116 # some tweaks in aprsed for change in behavior of oracle
117 # correct backupage for INCR_1 when newer INCR_0 is existing
120 # search DB_INCR_1 in parsed
121 if line
.rsplit('.', 1)[1] == 'DB_INCR_1':
124 sid_level0
= "%s0" % (line
[0:-1])
126 if sid_level0
in parsed
and parsed
[sid_level0
]['backupage'] < parsed
[line
]['backupage']:
128 parsed
[line
].update({
129 "backupage": backupage
,
136 def inventory_oracle_rman(parsed
):
140 sid
= parsed
[line
]['sid']
141 backuptype
= parsed
[line
]['backuptype']
142 backuplevel
= parsed
[line
]['backuplevel']
144 if backuptype
in ('ARCHIVELOG', 'DB_FULL', 'DB_INCR', 'CONTROLFILE'):
146 if inventory_oracle_rman_incremental_details
and backuptype
== 'DB_INCR':
147 inventory
.append(("%s.%s_%s" % (sid
, backuptype
, backuplevel
), {}))
151 inventory
.append(("%s.%s" % (sid
, backuptype
), {}))
156 # Cannot use generic decorator @get_parsed_item_data because this check function
157 # needs special treatment
158 def check_oracle_rman(item
, params
, parsed
):
160 rman_backup
= parsed
.get(item
)
166 # some versions of Oracle removes the last Level 1 after a new Level 0
167 # => we have no Level 1 in agent output. level 1 is shown as level 0
169 sid_level0
= "%s0" % (item
[0:-1])
171 if item
[-1] == '1' and sid_level0
in parsed
:
173 # => INCR_1 in item and INCR_0 found
174 # => Switch to INCR_0 + used_incr_0
175 rman_backup
= parsed
.get(sid_level0
)
176 rman_backup
.update({"used_incr_0": True})
180 # In case of missing information we assume that the login into
181 # the database has failed and we simply skip this check. It won't
182 # switch to UNKNOWN, but will get stale.
183 raise MKCounterWrapped("Login into database failed. Working on %s" % item
)
185 status
= rman_backup
['status']
186 backupage
= rman_backup
['backupage']
187 backupscn
= rman_backup
['backupscn']
192 if status
in ('COMPLETED', 'COMPLETED WITH WARNINGS'):
194 if backupage
is None:
195 # backupage in agent was empty. That's only possible with really old agents.
196 return 3, "Unknown backupage in check found. Please update agent."
198 # backupage is time in minutes from agent!
199 backupage
= backupage
* 60
200 infotext
= "Last backup %s ago" % get_age_human_readable(backupage
)
203 if "levels" in params
:
204 warn
, crit
= params
.get("levels")
205 if backupage
>= crit
:
207 elif backupage
>= warn
:
209 infotext
+= " (warn/crit at %s/%s)" % (get_age_human_readable(warn
),
210 get_age_human_readable(crit
))
212 perfdata
= [("age", backupage
, warn
, crit
)]
214 perfdata
= [("age", backupage
)]
217 infotext
+= ", incremental SCN %i" % backupscn
219 if rman_backup
['used_incr_0']:
220 infotext
+= ', Last DB_INCR_0 used'
222 infotext
= "no COMPLETED backup found in last 14 days (very old plugin in use?)"
224 return state
, infotext
, perfdata
227 check_info
['oracle_rman'] = {
228 "check_function": check_oracle_rman
,
229 "parse_function": parse_oracle_rman
,
230 "inventory_function": inventory_oracle_rman
,
231 "service_description": "ORA %s RMAN Backup",
232 "has_perfdata": True,
234 "group": "oracle_rman",
235 "includes": ["oracle.include", "db.include"]