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 # In cooperation with Thorsten Bruhns
29 # <<<oracle_instance:sep(124)>>>
30 # TUX2|12.1.0.1.0|OPEN|ALLOWED|STARTED|6735|1297771692|ARCHIVELOG|PRIMARY|NO|TUX2
31 # TUX5|12.1.0.1.1|MOUNTED|ALLOWED|STARTED|82883|1297771692|NOARCHIVELOG|PRIMARY|NO|0|TUX5
33 # <<<oracle_instance:sep(124)>>>$
34 # +ASM|FAILURE|ORA-99999 tnsping failed for +ASM $
36 # ORA-28002: the password will expire within 1 days$
38 factory_settings
["oracle_instance_defaults"] = {
46 def inventory_oracle_instance(info
):
52 # Skip ORA- error messages from broken old oracle agent
53 # <<<oracle_instance:sep(124)>>>
54 # ORA-99999 tnsping failed for +ASM1
55 if not (line
[0].startswith('ORA-') and line
[0][4].isdigit() and len(line
[0]) < 16):
57 # possible multitenant entry?
60 # every pdb has a con_id <> 0
61 # Multitenant use DB_NAME.PDB_NAME as Service
62 if line
[12] == ('TRUE') and line
[13] <> '0':
63 inv_list
.append((("%s.%s" % (line
[0], line
[14])), {}))
66 inv_list
.append((line
[0], {}))
71 def _transform_oracle_instance_params(p
):
72 if "ignore_noarchivelog" in p
:
73 if p
["ignore_noarchivelog"]:
75 del p
["ignore_noarchivelog"]
79 def check_oracle_instance(item
, params
, info
):
80 params
= _transform_oracle_instance_params(params
)
82 def state_marker(state
, infotext
, param
, column
, data
):
83 value
= params
.get(param
)
84 if value
is not None and column
== data
:
85 state
= max(state
, value
)
90 return state
, infotext
102 if line
[12] == ('TRUE') and line
[13] <> '0':
103 itemname
= ("%s.%s" % (line
[0], line
[14]))
107 # In case of a general error (e.g. authentication failed), the second
108 # column contains the word "FAILURE"
109 if line
[1] == 'FAILURE':
110 return 2, " ".join(line
[2:])
114 # Be compatible to old oracle agent plugin output
116 sid
, version
, openmode
, logins
, _unused
, _unused2
= line
118 infotext
= 'Status %s, Version %s, Logins %s' % (openmode
, version
, logins
.lower())
119 state
, infotext
= state_marker(state
, infotext
, 'logins', logins
, 'RESTRICTED')
120 return state
, infotext
122 elif len(line
) == 11:
123 sid
, version
, openmode
, logins
, archiver
, up_seconds
, _dbid
, \
124 log_mode
, database_role
, force_logging
, name
= line
126 elif len(line
) == 12:
127 sid
, version
, openmode
, logins
, archiver
, up_seconds
, _dbid
, \
128 log_mode
, database_role
, force_logging
, name
, _dbcreated
= line
130 elif len(line
) == 22:
131 sid
, version
, openmode
, logins
, archiver
, up_seconds
, _dbid
, \
132 log_mode
, database_role
, force_logging
, name
, _dbcreated
, pluggable
, \
133 _con_id
, pname
, _pdbid
, popenmode
, prestricted
, ptotal_size
, _precovery_status
, \
134 pup_seconds
, _pblock_size
= line
137 return 2, "Database not running, login failed or unvalid data from agent"
140 if prestricted
.lower
== 'no':
141 logins
= 'restricted'
146 up_seconds
= pup_seconds
148 infotext
= "PDB Name %s.%s, Status %s" % \
149 (name
, pname
, popenmode
)
151 if pluggable
.lower() == 'true':
152 infotext
= "CDB Name %s, Status %s" % \
155 infotext
= "Database Name %s, Status %s" % \
158 # Check state for PRIMARY Database. Normaly there are always OPEN
159 if database_role
== 'PRIMARY' and openmode
not in ('OPEN', 'READ ONLY', 'READ WRITE'):
160 state
= params
.get('primarynotopen')
166 infotext
+= ' (allowed by rule)'
169 infotext
+= ", Role %s, Version %s" % (database_role
, version
)
171 # ORACLE is sick and cannot handle timezone changes >:-P
172 up_seconds
= max(0, int(up_seconds
))
173 infotext
+= ", Up since %s (%s)" % (
174 time
.strftime("%F %T", time
.localtime(time
.time() - up_seconds
)), \
175 get_age_human_readable(up_seconds
))
177 if params
.get('uptime_min'):
178 warn
, crit
= params
.get('uptime_min')
182 infotext
+= ' (warn/crit at %s/%s)' % (get_age_human_readable(warn
),
183 get_age_human_readable(crit
))
185 # PDB in mounted state has no uptime information
187 elif up_seconds
<= crit
:
189 infotext
+= '(!!) not long enough up'
190 elif up_seconds
<= warn
:
191 state
= max(state
, 1)
192 infotext
+= '(!) not long enough up'
194 # ASM has no login and archivelog check
195 if database_role
!= 'ASM':
197 # logins are only possible when the database is open
198 if openmode
== 'OPEN':
199 infotext
+= ', Logins %s' % (logins
.lower())
200 state
, infotext
= state_marker(state
, infotext
, 'logins', logins
, 'RESTRICTED')
202 # the new internal database _MGMTDB from 12.1.0.2 is always in NOARCHIVELOG mode
203 if name
!= '_MGMTDB' and sid
!= '-MGMTDB' and pdb
is False:
204 infotext
+= ', Log Mode %s' % (log_mode
.lower())
205 state
, infotext
= state_marker(state
, infotext
, 'archivelog', log_mode
,
207 state
, infotext
= state_marker(state
, infotext
, 'noarchivelog', log_mode
,
210 # archivelog is only valid in non pdb
211 # force logging is only usable when archivelog is enabled
212 if log_mode
== 'ARCHIVELOG':
213 if archiver
!= 'STARTED':
214 infotext
+= '. Archiver %s(!!)' % (archiver
.lower())
217 infotext
+= ', Force Logging %s' % (force_logging
.lower())
218 state
, infotext
= state_marker(state
, infotext
, 'forcelogging',
219 force_logging
, 'YES')
220 state
, infotext
= state_marker(state
, infotext
, 'noforcelogging',
223 perfdata
= [['uptime', up_seconds
]]
226 infotext
+= ', PDB Size %s' % get_bytes_human_readable(int(ptotal_size
))
227 perfdata
.append(('fs_size', int(ptotal_size
)))
229 return state
, infotext
, perfdata
232 # no error from PDB when CDB is down
233 raise MKCounterWrapped("CDB possible down. No results for PDB availible!")
235 return 2, "Database not running or login failed"
238 check_info
['oracle_instance'] = {
239 "check_function": check_oracle_instance
,
240 "inventory_function": inventory_oracle_instance
,
241 "service_description": "ORA %s Instance",
242 "default_levels_variable": "oracle_instance_defaults",
243 "group": "oracle_instance",
244 "has_perfdata": True,