From 3e5a82c0aa5009876e00cad19dbfcc1138269137 Mon Sep 17 00:00:00 2001 From: Fabian Weisshaar Date: Mon, 2 May 2016 11:43:34 +0200 Subject: [PATCH] update check_mk agent and plugins --- README.md | 68 +- defaults/main.yml | 6 +- files/check-mk-agent_1.2.6p16-1_all.deb | Bin 0 -> 18896 bytes files/plugins/apache_status | 38 +- files/plugins/arc_raid_status.sh | 5 - files/plugins/{db2_mem.sh => db2_mem} | 15 +- files/plugins/dmi_sysinfo | 6 - files/plugins/dmraid | 19 - files/plugins/dnsclient | 48 + files/plugins/hpux_lunstats | 91 ++ files/plugins/hpux_statgrab | 46 + files/plugins/j4p_performance | 137 --- files/plugins/jar_signature | 11 +- files/plugins/kaspersky_av | 38 + files/plugins/lnx_quota | 32 + files/plugins/mailman_lists | 26 +- files/plugins/mk_inventory.aix | 69 ++ files/plugins/mk_inventory.linux | 85 ++ files/plugins/mk_inventory.solaris | 71 ++ files/plugins/mk_jolokia | 51 +- files/plugins/{sylo => mk_logins} | 16 +- files/plugins/mk_logwatch | 82 +- files/plugins/mk_logwatch_aix | 13 + files/plugins/mk_mysql | 15 +- files/plugins/mk_oracle | 1083 ++++++++++++++++++++--- files/plugins/mk_oracle.aix | 1026 +++++++++++++++++++++ files/plugins/mk_oracle.solaris | 200 +++++ files/plugins/mk_oracle_asm | 2 +- files/plugins/mk_oracle_crs | 127 +++ files/plugins/mk_postgres | 33 +- files/plugins/mk_sap | 290 +++--- files/plugins/mk_tsm | 29 +- files/plugins/mk_zypper | 24 +- files/plugins/netstat.aix | 31 + files/plugins/netstat.linux | 31 + files/plugins/nfsexports | 36 +- files/plugins/nfsexports.solaris | 57 ++ files/plugins/nginx_status | 146 +++ files/plugins/plesk_backups | 43 +- files/plugins/plesk_domains | 25 +- files/plugins/resolve_hostname | 20 - files/plugins/runas | 84 ++ files/plugins/smart | 79 +- files/plugins/symantec_av | 38 + files/plugins/unitrends_backup | 88 ++ files/plugins/unitrends_replication | 49 + files/plugins/veritas/vxvm_enclosures | 15 - files/plugins/veritas/vxvm_multipath | 15 - files/plugins/veritas/vxvm_objstatus | 30 - files/plugins/vxvm | 50 ++ files/plugins/websphere_mq | 62 ++ tasks/main.yml | 11 +- 52 files changed, 4058 insertions(+), 654 deletions(-) create mode 100644 files/check-mk-agent_1.2.6p16-1_all.deb delete mode 100755 files/plugins/arc_raid_status.sh rename files/plugins/{db2_mem.sh => db2_mem} (84%) delete mode 100755 files/plugins/dmi_sysinfo delete mode 100755 files/plugins/dmraid create mode 100755 files/plugins/dnsclient create mode 100755 files/plugins/hpux_lunstats create mode 100755 files/plugins/hpux_statgrab delete mode 100755 files/plugins/j4p_performance create mode 100755 files/plugins/kaspersky_av create mode 100755 files/plugins/lnx_quota create mode 100755 files/plugins/mk_inventory.aix create mode 100755 files/plugins/mk_inventory.linux create mode 100755 files/plugins/mk_inventory.solaris rename files/plugins/{sylo => mk_logins} (85%) create mode 100755 files/plugins/mk_logwatch_aix create mode 100755 files/plugins/mk_oracle.aix create mode 100755 files/plugins/mk_oracle.solaris create mode 100755 files/plugins/mk_oracle_crs create mode 100755 files/plugins/netstat.aix create mode 100755 files/plugins/netstat.linux create mode 100755 files/plugins/nfsexports.solaris create mode 100755 files/plugins/nginx_status delete mode 100755 files/plugins/resolve_hostname create mode 100755 files/plugins/runas create mode 100755 files/plugins/symantec_av create mode 100755 files/plugins/unitrends_backup create mode 100755 files/plugins/unitrends_replication delete mode 100755 files/plugins/veritas/vxvm_enclosures delete mode 100755 files/plugins/veritas/vxvm_multipath delete mode 100755 files/plugins/veritas/vxvm_objstatus create mode 100755 files/plugins/vxvm create mode 100755 files/plugins/websphere_mq diff --git a/README.md b/README.md index 86ba12c..d0b6f0d 100644 --- a/README.md +++ b/README.md @@ -5,39 +5,53 @@ Installs check mk agent. Run it with xinit or over ssh (default). Get more infor Only testet with Ubuntu and Debian, should run on more platforms. ## Role Variables -* `check_mk_agent_deb_package: check-mk-agent_1.2.4p5-2_all.deb` +* `check_mk_agent_deb_package: check-mk-agent_1.2.6p16-1_all.deb` Path to deb package * `check_mk_agent_over_ssh: True` -* `check_mk_agent_plugins_requirements: ["smartmontools"]` Requirements for extra plugins -* `check_mk_agent_plugins: ["smart", ]` List of extra plugins to install +* `check_mk_agent_plugins_requirements: []` Requirements for extra plugins +* `check_mk_agent_plugins: []` List of extra plugins to install * `check_mk_agent_pubkey_file:` Path to ssh pubkey file ## Included check_mk extra plugins -* apache_status -* arc_raid_status.sh -* db2_mem.sh -* dmi_sysinfo -* dmraid -* j4p_performance -* jar_signature -* mailman_lists -* mk_jolokia -* mk_logwatch -* mk_mysql -* mk_oracle -* mk_oracle_asm -* mk_postgres -* mk_sap -* mk_tsm -* mk_zypper +* apache\_status +* db2\_mem +* dnsclient +* hpux\_lunstats +* hpux\_statgrab +* jar\_signature +* kaspersky\_av +* lnx\_quota +* mailman\_lists +* mk\_inventory.aix +* mk\_inventory.linux +* mk\_inventory.solaris +* mk\_jolokia +* mk\_logins +* mk\_logwatch +* mk\_logwatch\_aix +* mk\_mysql +* mk\_oracle +* mk\_oracle.aix +* mk\_oracle.solaris +* mk\_oracle\_asm +* mk\_oracle\_crs +* mk\_postgres +* mk\_sap +* mk\_tsm +* mk\_zypper +* netstat.aix +* netstat.linux * nfsexports -* plesk_backups -* plesk_domains -* resolve_hostname +* nfsexports.solaris +* nginx\_status +* plesk\_backups +* plesk\_domains +* runas * smart -* sylo -* vxvm_enclosures -* vxvm_multipath -* vxvm_objstatus +* symantec\_av +* unitrends\_backup +* unitrends\_replication +* vxvm +* websphere\_mq ## Dependencies None. diff --git a/defaults/main.yml b/defaults/main.yml index 8de7f7a..fa2242c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,7 +1,7 @@ --- # defaults file for agent -check_mk_agent_deb_package: check-mk-agent_1.2.4p5-2_all.deb +check_mk_agent_deb_package: check-mk-agent_1.2.6p16-1_all.deb check_mk_agent_over_ssh: True -check_mk_agent_plugins_requirements: ["smartmontools"] -check_mk_agent_plugins: ["smart", ] +check_mk_agent_plugins_requirements: [] +check_mk_agent_plugins: [] check_mk_agent_pubkey_file: diff --git a/files/check-mk-agent_1.2.6p16-1_all.deb b/files/check-mk-agent_1.2.6p16-1_all.deb new file mode 100644 index 0000000000000000000000000000000000000000..968f97f8ad0e64a1f98b908da53b339a67b3b97d GIT binary patch literal 18896 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 2.6 +# supports timeout parameter for the urllib2.urlopen method +# but we are on a python 2.5 system here which seem to use the +# default socket timeout. We are local here so set it to 1 second. +socket.setdefaulttimeout(5.0) # None or list of (proto, ipaddress, port) tuples. # proto is 'http' or 'https' @@ -47,7 +76,7 @@ def try_detect_servers(): to_replace = re.compile('^.*/') proc = to_replace.sub('', proc) - procs = [ 'apache2', 'httpd', 'httpd2-prefork', 'httpd2-worker', 'httpd.worker' ] + procs = [ 'apache2', 'httpd', 'httpd2-prefork', 'httpd2-worker', 'httpd.worker', 'fcgi-pm' ] # the pid/proc field length is limited to 19 chars. Thus in case of # long PIDs, the process names are stripped of by that length. # Workaround this problem here @@ -103,7 +132,8 @@ for server in servers: url = '%s://%s:%s/%s?auto' % (proto, address, port, page) # Try to fetch the status page for each server try: - fd = urllib2.urlopen(url) + request = urllib2.Request(url, headers={"Accept" : "text/plain"}) + fd = urllib2.urlopen(request) except urllib2.URLError, e: if 'SSL23_GET_SERVER_HELLO:unknown protocol' in str(e): # HACK: workaround misconfigurations where port 443 is used for diff --git a/files/plugins/arc_raid_status.sh b/files/plugins/arc_raid_status.sh deleted file mode 100755 index fa3a722..0000000 --- a/files/plugins/arc_raid_status.sh +++ /dev/null @@ -1,5 +0,0 @@ -#cli64 can be found at: -# ftp://ftp.areca.com.tw/RaidCards/AP_Drivers/Linux/CLI/ - -echo "<<>>" -cli64 rsf info | tail -n +3 | head -n -2 diff --git a/files/plugins/db2_mem.sh b/files/plugins/db2_mem similarity index 84% rename from files/plugins/db2_mem.sh rename to files/plugins/db2_mem index fe038ca..10b9d1c 100755 --- a/files/plugins/db2_mem.sh +++ b/files/plugins/db2_mem @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # +------------------------------------------------------------------+ # | ____ _ _ __ __ _ __ | # | / ___| |__ ___ ___| | __ | \/ | |/ / | @@ -6,7 +6,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2013 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. @@ -25,9 +25,10 @@ INSTANCES=$(ps -ef | grep db2sysc | awk '{print $1}' | sort -u | grep -v root) -for INSTANCE in $INSTANCES; do +if [ "$INSTANCES" ] ; then echo "<<>>" - echo "Instance $INSTANCE" - su - $INSTANCE -c "db2pd -dbptnmem " | egrep '(Memory Limit|HWM usage)' -done - + for INSTANCE in $INSTANCES; do + echo "Instance $INSTANCE" + su - $INSTANCE -c "db2pd -dbptnmem " | egrep '(Memory Limit|HWM usage)' + done +fi diff --git a/files/plugins/dmi_sysinfo b/files/plugins/dmi_sysinfo deleted file mode 100755 index d0ed1c8..0000000 --- a/files/plugins/dmi_sysinfo +++ /dev/null @@ -1,6 +0,0 @@ -#/bin/sh - -if which dmidecode >/dev/null 2>&1; then - echo "<<>>" - dmidecode -t 1 -q -fi diff --git a/files/plugins/dmraid b/files/plugins/dmraid deleted file mode 100755 index 5bcec9b..0000000 --- a/files/plugins/dmraid +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -echo '<<>>' - -STATUS=$(dmraid -r) -if [ $? != 0 ]; then - exit 1 -fi - -# Name und Status ausgeben -dmraid -s | grep -e ^name -e ^status - -# Diskname der Raidplatten ausgeben -DISKS=$(echo "$STATUS" | cut -f1 -d\:) - -for disk in $DISKS ; do - device=$(cat /sys/block/$(basename $disk)/device/model ) - status=$(echo "$STATUS" | grep ^${disk}) - echo "$status Model: $device" -done diff --git a/files/plugins/dnsclient b/files/plugins/dnsclient new file mode 100755 index 0000000..403a8ce --- /dev/null +++ b/files/plugins/dnsclient @@ -0,0 +1,48 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# This check can be used to test the name resolution of a given host +# address using the local resolver of the system this script is +# running on. + +HOSTADDRESSES=mathias-kettner.de + +if [ -e $MK_CONFDIR/dnsclient.cfg ] ; then + . $MK_CONFDIR/dnsclient.cfg +fi + +echo "<<>>" +for HOSTADDRESS in $HOSTADDRESSES +do + ADDRESSES=`nslookup $HOSTADDRESS | sed -n -e 1,3d -e '/^Address: *\(.*\)$/s//\1/p'` + if [ ! "$ADDRESSES" ] ; then + STATE=2 + OUTPUT="CRIT - $HOSTADDRESS could not be resolved" + else + STATE=0 + OUTPUT="OK - $HOSTADDRESS resolved into $ADDRESSES" + fi + echo Resolve_$HOSTADDRESS $STATE $OUTPUT +done diff --git a/files/plugins/hpux_lunstats b/files/plugins/hpux_lunstats new file mode 100755 index 0000000..a53878a --- /dev/null +++ b/files/plugins/hpux_lunstats @@ -0,0 +1,91 @@ +#!/usr/bin/ksh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Put this file into /usr/lib/check_mk_agent/plugins. Then +# reinventorize your host. +# Actually querying these stats is quite slow since they freshly update +# on each call. If you have a few 1000 luns then this will not work. + +get_stats() +{ + scsimgr get_stat -D $LUN | tr '\=' ':' | grep -e 'STATISTICS FOR LUN' -e 'Bytes' -e 'Total I/Os processed' -e 'I/O failure' -e 'IO failures due +to' + return $? +} + + +# Ex: +#LUN PATH INFORMATION FOR LUN : /dev/pt/pt2 +#World Wide Identifier(WWID) = +#LUN PATH INFORMATION FOR LUN : /dev/rdisk/disk5 +#World Wide Identifier(WWID) = 0x60a98000572d44745634645076556357 +#LUN PATH INFORMATION FOR LUN : /dev/rdisk/disk6 + +get_lun_map() +{ +scsimgr lun_map | egrep '^[[:space:]]*(LUN PATH|World Wide Identifier)' | tr '\=' ':' +} + + +main() +{ +get_lun_map | while read line ; do + descr=$(echo $line | awk -F: '{print $1}') + val=$( echo $line | awk -F: '{print $2}') + case $descr in + LUN*) + if echo $val | grep /dev/rdisk 1>/dev/null; then + DMP=yes + LUN=$val + else + DMP=no + unset LUN + fi + ;; + World*) + if [ $DMP = "yes" ]; then + echo "WWID: $val" + get_stats $LUN + fi + ;; + *) + echo "Fehler:" + echo $line + echo $descr + echo $val + sleep 1 + ;; + esac +done +} + + + +# Verify the system is using new multipath device model. +if [ -d /dev/rdisk ] && [ -d /dev/disk ]; then + echo '<<>>' + main +fi + diff --git a/files/plugins/hpux_statgrab b/files/plugins/hpux_statgrab new file mode 100755 index 0000000..cf5ea5b --- /dev/null +++ b/files/plugins/hpux_statgrab @@ -0,0 +1,46 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# this is for users who compiled statgrab on hp-ux. +# note you'll need a 0.18+ version, from their github page at +# https://github.com/i-scream/libstatgrab +# flags used for compiling - disable documentation, examples and set*id + + +if which statgrab > /dev/null ; then + if statgrab const. cpu. general. mem. page. proc. swap. user. > /tmp/statgrab.$$ 2>/dev/null + then + for s in proc cpu page + do + echo "<<>>" + cat /tmp/statgrab.$$ | grep "^$s\." | cut -d. -f2-99 | sed 's/ *= */ /' + done + + echo '<<>>' + cat /tmp/statgrab.$$ | egrep "^(swap|mem)\." | sed 's/ *= */ /' + + fi + [ -f /tmp/statgrab.$$ ] && rm -f /tmp/statgrab.$$ +fi diff --git a/files/plugins/j4p_performance b/files/plugins/j4p_performance deleted file mode 100755 index 070c528..0000000 --- a/files/plugins/j4p_performance +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/python - -# WARNING: This pluin is deprecated and will be removed soon. -# Please use mk_jolokia instead - -import urllib2, sys, os - -server = "localhost" -port = 8080 -user = "monitoring" -password = "foobar" -mode = "digest" -suburi = "jolokia" -instance = None - -vars = [ - ( "java.lang:type=Memory/NonHeapMemoryUsage/used", "NonHeapMemoryUsage" ), - ( "java.lang:type=Memory/HeapMemoryUsage/used", "HeapMemoryUsage" ), - ( "java.lang:type=Threading/ThreadCount", "ThreadCount" ), - ( "java.lang:type=Threading/DaemonThreadCount", "DeamonThreadCount" ), - ( "java.lang:type=Threading/PeakThreadCount", "PeakThreadCount" ), - ( "java.lang:type=Threading/TotalStartedThreadCount", "TotalStartedThreadCount" ), - ( "java.lang:type=Runtime/Uptime", "Uptime" ), -] - -app_vars = [ - ('*:j2eeType=WebModule,name=/--/localhost/-/%(app)s,*/state', 'Running'), - ('*:path=/-/%(app)s,type=Manager,*/activeSessions', 'Sessions'), -] - -servlet_vars = [ - ('*:j2eeType=Servlet,WebModule=/--/localhost/-/%(app)s,name=%(servlet)s,*/requestCount', 'Requests') -] - -# The servlets dictionary keys represent an application (webmodule) which holds a -# list of servlets which are available within this application -servlets = {} - -conffile = os.getenv("MK_CONFDIR", "/etc/check_mk") + "/j4p.conf" - -if instance == None: - instance = str(port) - -if os.path.exists(conffile): - execfile(conffile) - -# We have to deal with socket timeouts. Python > 2.6 -# supports timeout parameter for the urllib2.urlopen method -# but we are on a python 2.5 system here which seem to use the -# default socket timeout. We are local here so set it to 1 second. -import socket -socket.setdefaulttimeout(1.0) - -# Convert servlet config definitions and append it to the vars definitions -for app, servlets in servlets.iteritems(): - # Add application specific vars - for var in app_vars: - vars.append(((app, None), var[0] % {'app': app}, var[1])) - - # Add servlet specific checks - for servlet in servlets: - for var in servlet_vars: - vars.append(((app, servlet), var[0] % {'app': app, 'servlet': servlet}, var[1])) - - -def init_auth(): - if user and password: - passwdmngr = urllib2.HTTPPasswordMgrWithDefaultRealm() - passwdmngr.add_password(None, "http://%s:%d/" % (server, port), user, password) - if mode == 'digest': - authhandler = urllib2.HTTPDigestAuthHandler(passwdmngr) - else: - authhandler = urllib2.HTTPBasicAuthHandler(passwdmngr) - opener = urllib2.build_opener(authhandler) - urllib2.install_opener(opener) - - -def fetch_var(server, port, path, suburi): - url = "http://%s:%d/%s/read/%s" % (server, port, suburi, path) - json = urllib2.urlopen(url).read() - - try: - obj = eval(json) - except Exception, e: - sys.stderr.write('ERROR: Invalid json code (%s)\n' % e) - sys.stderr.write(' Response %s\n' % json) - return None - - if obj.get('status', 200) == 404: - sys.stderr.write('ERROR: Invalid response when fetching url %s\n' % url) - sys.stderr.write(' Response: %s\n' % json) - - # Only take the value of the object. If the value is an object - # take the first items first value. - # {'Catalina:host=localhost,path=\\/test,type=Manager': {'activeSessions': 0}} - val = obj.get('value', None) - if isinstance(val, dict): - item = val[val.keys()[0]] - return item[item.keys()[0]] - else: - return val - - -init_auth() - -# Fetch the general information first -first = True -for var in vars: - app, servlet = None, None - if len(var) == 2: - path, title = var - else: - (app, servlet), path, title = var - - if servlet: - item = [instance, app, servlet] - elif app: - item = [instance, app] - else: - item = [instance] - - try: - value = fetch_var(server, port, path, suburi) - except IOError: - sys.exit(1) - except socket.timeout: - sys.exit(1) - except: - # Simply ignore exceptions. Need to be removed for debugging - continue - - if first: - first = False - sys.stdout.write("<<>>\n") - - sys.stdout.write("%s %s %s\n" % (','.join(item), title, value)) -sys.exit(0) diff --git a/files/plugins/jar_signature b/files/plugins/jar_signature index 7309923..42a06b8 100755 --- a/files/plugins/jar_signature +++ b/files/plugins/jar_signature @@ -6,7 +6,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2013 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. @@ -26,12 +26,17 @@ # This agent uses the program "jarsigner" to read ssl certificate # information of jar files and outputs the information to stdout # for the Check_MK check. -# We assume that all files in the jar archive are signed with the +# We assume that all files in the jar archive are signed with the # same certificate. So we only deal with the last signed file here. JAVA_HOME=/home/oracle/bin/jdk_latest_version JAR_PATH=/home/oracle/fmw/11gR2/as_1/forms/java/*.jar +# Let user override these defaults in a configuration file +if [ -e $MK_CONFDIR/jar_signature.cfg ] ; then + . $MK_CONFDIR/jar_signature.cfg +fi + PATH=$JAVA_HOME/bin:$PATH echo "<<>>" @@ -41,7 +46,7 @@ for JAR in $JAR_PATH; do OUTPUT=$(jarsigner -verify -verbose -certs "$JAR") LINE=$(echo "$OUTPUT" | grep -n ^s | tail -n1 | cut -d: -f1) echo "$(echo "$OUTPUT" | tail -n +$LINE)" - echo + echo fi done diff --git a/files/plugins/kaspersky_av b/files/plugins/kaspersky_av new file mode 100755 index 0000000..8ffc0c4 --- /dev/null +++ b/files/plugins/kaspersky_av @@ -0,0 +1,38 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +if [ -f /opt/kaspersky/kav4fs/bin/kav4fs-control ] +then + echo "<<>>" + /opt/kaspersky/kav4fs/bin/kav4fs-control --get-stat Update + + echo "<<>>" + /opt/kaspersky/kav4fs/bin/kav4fs-control -Q --get-stat + + echo "<<>>" + /opt/kaspersky/kav4fs/bin/kav4fs-control --get-task-list + +fi + diff --git a/files/plugins/lnx_quota b/files/plugins/lnx_quota new file mode 100755 index 0000000..cd0c307 --- /dev/null +++ b/files/plugins/lnx_quota @@ -0,0 +1,32 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +if type repquota >/dev/null ; then + echo "<<>>" + for VOL in $(grep usrjquota /etc/fstab | cut -d' ' -f2); do + echo "[[[$VOL]]]" + repquota -up $VOL + done +fi diff --git a/files/plugins/mailman_lists b/files/plugins/mailman_lists index 9371082..f41a779 100755 --- a/files/plugins/mailman_lists +++ b/files/plugins/mailman_lists @@ -1,5 +1,29 @@ #!/usr/bin/python -# encoding: utf-8 +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + # This Check_MK-Agent plugin gathers information about mailinglists hosted # by the local mailman instance. diff --git a/files/plugins/mk_inventory.aix b/files/plugins/mk_inventory.aix new file mode 100755 index 0000000..f2c8529 --- /dev/null +++ b/files/plugins/mk_inventory.aix @@ -0,0 +1,69 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Run and *send* only once every 4 hours +INTERVAL=14400 + +FLAGFILE=$MK_CONFDIR/mk_inventory.last.$REMOTE +NOW=$(date +%s) +UNTIL=$((NOW + INTERVAL + 600)) + +#check if flagfile exits +if [ -e "$FLAGFILE" ]; then + LAST_RUN=$(cat $FLAGFILE) +else + #First run of the script + LAST_RUN=0 +fi + +if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ] +then + echo $NOW > $FLAGFILE + + # List of installed AIX packages + if type lslpp >/dev/null; then + echo "<<>>" + lslpp -c -L + fi + + if type oslevel > /dev/null; then + # base level of the system + echo "<<>>" + oslevel + + # list the known service packs on a system + echo "<<>>" + oslevel -s + fi + + # If you run the prtconf command without any flags, it displays the system model, machine serial, + # processor type, number of processors, processor clock speed, cpu type, total memory size, network information, filesystem + # information, paging space information, and devices information. + if type prtconf >/dev/null ; then + echo "<<>>" + prtconf + fi +fi + diff --git a/files/plugins/mk_inventory.linux b/files/plugins/mk_inventory.linux new file mode 100755 index 0000000..9d5b3d2 --- /dev/null +++ b/files/plugins/mk_inventory.linux @@ -0,0 +1,85 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Run and *send* only once every __ seconds +. $MK_CONFDIR/mk_inventory.cfg 2>/dev/null || true + +# Default to four hours +INTERVAL=${INVENTORY_INTERVAL:-14400} + +FLAGFILE=$MK_VARDIR/mk_inventory.last.$REMOTE +LAST_RUN=$(stat -c %Y $FLAGFILE) +NOW=$(date +%s) +UNTIL=$((NOW + INTERVAL + 600)) + +if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ] +then + touch $FLAGFILE + + # List of DEB packages + if type dpkg-query >/dev/null; then + echo "<<>>" + dpkg-query --show --showformat='${Package}|${Version}|${Architecture}|deb|${Summary}|${Status}\n' + fi + + # List of RPM packages in same format + if type rpm >/dev/null; then + echo "<<>>" + rpm -qa --qf '%{NAME}\t%{VERSION}\t%{ARCH}\trpm\t%{SUMMARY}\t-\n' + fi + + # Information about distribution + echo "<<>>" + for f in /etc/{debian_version,lsb-release,redhat-release,SuSE-release} ; do + if [ -e $f ] ; then + echo -n "$f|" ; tr \\n \| < $f | sed 's/|$//' ; echo + fi + done + + # CPU Information. We need just the first one + if [ -e /proc/cpuinfo ] ; then + echo "<<>>" + sed 's/[[:space:]]*:[[:space:]]*/:/' < /proc/cpuinfo + fi + + # Information about main board, memory, etc. + if type dmidecode >/dev/null ; then + echo "<<>>" + dmidecode -q | sed 's/\t/:/g' + fi + + # Information about kernel architecture + if type uname >/dev/null ; then + echo "<<>>" + uname -m + uname -r + fi + if type lspci > /dev/null ; then + echo "<<>>" + lspci -v -s $(lspci | grep VGA | cut -d" " -f 1) + fi + +fi + diff --git a/files/plugins/mk_inventory.solaris b/files/plugins/mk_inventory.solaris new file mode 100755 index 0000000..14d423a --- /dev/null +++ b/files/plugins/mk_inventory.solaris @@ -0,0 +1,71 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + + +# Run and *send* only once every 4 hours +INTERVAL=14400 + +FLAGFILE=$MK_VARDIR/mk_inventory.last.$REMOTE +NOW=$(truss /usr/bin/date 2>&1 | grep ^time | awk -F"= " '{print $2}') +UNTIL=$((NOW + INTERVAL + 600)) + +#check if flagfile exits +if [ -e "$FLAGFILE" ]; then + LAST_RUN=$(cat $FLAGFILE) +else + #First run of the script + LAST_RUN=0 +fi + +if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ] +then + echo $NOW > $FLAGFILE + + echo "<<>>" + uname -X + + if type prtdiag > /dev/null; then + echo "<<>>" + serial=`sneep -t serial`;echo "SerialNumber: $serial" + prtdiag -v + fi + + if type psrinfo > /dev/null; then + echo "<<>>" + psrinfo -p -v + fi + + if type prtpicl > /dev/null; then + echo "<<>>" + prtpicl -v + fi + + + if type pkginfo >/dev/null ; then + echo "<<>>" + pkginfo -l + fi +fi + diff --git a/files/plugins/mk_jolokia b/files/plugins/mk_jolokia index 74afb61..40553ad 100755 --- a/files/plugins/mk_jolokia +++ b/files/plugins/mk_jolokia @@ -1,4 +1,28 @@ #!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. import urllib2, sys, os, socket, pprint @@ -31,7 +55,7 @@ def fetch_var(server, port, path, suburi, itemspec): # Only take the value of the object. If the value is an object # take the first items first value. # {'Catalina:host=localhost,path=\\/test,type=Manager': {'activeSessions': 0}} - if 'value' not in obj: + if 'value' not in obj: if opt_debug: sys.stderr.write("ERROR: not found: %s\n" % path) return [] @@ -103,11 +127,14 @@ def query_instance(inst): # Determine type of server server_info = fetch_var(inst["server"], inst["port"], "", inst["suburi"], "") + sys.stdout.write('<<>>\n') if server_info: d = dict(server_info) version = d.get(('info', 'version'), "unknown") product = d.get(('info', 'product'), "unknown") + if inst.has_key("product"): + product = inst["product"] agentversion = d.get(('agent',), "unknown") sys.stdout.write("%s %s %s %s\n" % (inst["instance"], product, version, agentversion)) else: @@ -136,6 +163,9 @@ def query_instance(inst): print "INTERNAL ERROR: %s" % value continue + if "threadStatus" in subinstance or "threadParam" in subinstance: + continue + if len(subinstance) > 1: item = ",".join((inst["instance"],) + subinstance[:-1]) else: @@ -170,6 +200,8 @@ global_vars = [ ( "java.lang:type=Threading/PeakThreadCount", "PeakThreadCount", [] ), ( "java.lang:type=Threading/TotalStartedThreadCount", "TotalStartedThreadCount", [] ), ( "java.lang:type=Runtime/Uptime", "Uptime", [] ), + ( "java.lang:type=GarbageCollector,name=*/CollectionCount", "", [] ), + ( "java.lang:type=GarbageCollector,name=*/CollectionTime", "", [] ), ] @@ -189,7 +221,9 @@ specific_vars = { ( "*:j2eeType=Servlet,name=default,*/stateName", None, [ "WebModule" ] ), # Check not yet working ( "*:j2eeType=Servlet,name=default,*/requestCount", None, [ "WebModule" ]), - + ( "*:name=*,type=ThreadPool/maxThreads", None, []), + ( "*:name=*,type=ThreadPool/currentThreadCount", None, []), + ( "*:name=*,type=ThreadPool/currentThreadsBusy", None, []), # too wide location for addressing the right info # ( "*:j2eeType=Servlet,*/requestCount", None, [ "WebModule" ] ), @@ -229,12 +263,12 @@ socket.setdefaulttimeout(1.0) # of dicts). for inst in instances: for varname, value in [ - ( "server", server ), - ( "port", port ), - ( "user", user ), + ( "server", server ), + ( "port", port ), + ( "user", user ), ( "password", password ), - ( "mode", mode ), - ( "suburi", suburi ), + ( "mode", mode ), + ( "suburi", suburi ), ( "instance", instance )]: if varname not in inst: inst[varname] = value @@ -243,6 +277,3 @@ for inst in instances: inst["instance"] = inst["instance"].replace(" ", "_") query_instance(inst) - - - diff --git a/files/plugins/sylo b/files/plugins/mk_logins similarity index 85% rename from files/plugins/sylo rename to files/plugins/mk_logins index 70fe5a4..2005529 100755 --- a/files/plugins/sylo +++ b/files/plugins/mk_logins @@ -6,12 +6,12 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2010 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ -# +# # This file is part of Check_MK. # The official homepage is at http://mathias-kettner.de/check_mk. -# +# # check_mk is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. check_mk is distributed @@ -23,11 +23,7 @@ # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA. -BASE_PATH=/var/spool/sylo - -if [ -f "$BASE_PATH/silo.hint" ]; then - echo "<<>>" - stat --printf "%Y " "$BASE_PATH/silo.hint" - cat "$BASE_PATH/silo.hint" - echo +if type who >/dev/null; then + echo "<<>>" + who | wc -l fi diff --git a/files/plugins/mk_logwatch b/files/plugins/mk_logwatch index 3dbca32..2933d8e 100755 --- a/files/plugins/mk_logwatch +++ b/files/plugins/mk_logwatch @@ -7,7 +7,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2010 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. @@ -26,8 +26,7 @@ # Call with -d for debug mode: colored output, no saving of status -import sys, os, re, time -import glob +import sys, os, re, time, glob if '-d' in sys.argv[1:] or '--debug' in sys.argv[1:]: tty_red = '\033[1;31m' @@ -50,16 +49,18 @@ else: # If that is not set either, the current directory ist # used. logwatch_dir = os.getenv("LOGWATCH_DIR") -if not logwatch_dir: - logwatch_dir = os.getenv("MK_CONFDIR") - if not logwatch_dir: - logwatch_dir = "." +if logwatch_dir: + mk_confdir = logwatch_dir + mk_vardir = logwatch_dir +else: + mk_confdir = os.getenv("MK_CONFDIR") or "." + mk_vardir = os.getenv("MK_VARDIR") or "." print "<<>>" -config_filename = logwatch_dir + "/logwatch.cfg" -status_filename = logwatch_dir + "/logwatch.state" -config_dir = logwatch_dir + "/logwatch.d/*.cfg" +config_filename = mk_confdir + "/logwatch.cfg" +config_dir = mk_confdir + "/logwatch.d/*.cfg" +status_filename = mk_vardir + "/logwatch.state" def is_not_comment(line): if line.lstrip().startswith('#') or \ @@ -118,7 +119,7 @@ def parse_cont_pattern(pattern): except: if debug: raise - raise Exception("Invalid regular expression in line '%s'" % pattern) + raise Exception("Invalid regular expression in line '%s'" % pattern) # structure of statusfile # # LOGFILE OFFSET INODE @@ -155,7 +156,7 @@ def save_status(status): f.write("%s|%d|%d\n" % (filename, offset, inode)) pushed_back_line = None -def next_line(f): +def next_line(file_handle): global pushed_back_line if pushed_back_line != None: line = pushed_back_line @@ -163,7 +164,7 @@ def next_line(f): return line else: try: - line = f.next() + line = file_handle.next() return line except: return None @@ -177,8 +178,8 @@ def process_logfile(logfile, patterns): # before, we set the offset to -1 offset, prev_inode = status.get(logfile, (-1, -1)) try: - fl = os.open(logfile, os.O_RDONLY) - inode = os.fstat(fl)[1] # 1 = st_ino + file_desc = os.open(logfile, os.O_RDONLY) + inode = os.fstat(file_desc)[1] # 1 = st_ino except: if debug: raise @@ -188,9 +189,9 @@ def process_logfile(logfile, patterns): print "[[[%s]]]" % logfile # Seek to the current end in order to determine file size - current_end = os.lseek(fl, 0, 2) # os.SEEK_END not available in Python 2.4 + current_end = os.lseek(file_desc, 0, 2) # os.SEEK_END not available in Python 2.4 status[logfile] = current_end, inode - + # If we have never seen this file before, we just set the # current pointer to the file end. We do not want to make # a fuss about ancient log messages... @@ -199,7 +200,7 @@ def process_logfile(logfile, patterns): return else: offset = 0 - + # If the inode of the logfile has changed it has appearently # been started from new (logfile rotation). At least we must @@ -221,25 +222,29 @@ def process_logfile(logfile, patterns): offset = 0 # now seek to offset where interesting data begins - os.lseek(fl, offset, 0) # os.SEEK_SET not available in Python 2.4 - f = os.fdopen(fl) + os.lseek(file_desc, offset, 0) # os.SEEK_SET not available in Python 2.4 + file_handle = os.fdopen(file_desc) worst = -1 outputtxt = "" lines_parsed = 0 start_time = time.time() while True: - line = next_line(f) + line = next_line(file_handle) if line == None: break # End of file + # Handle option maxlinesize + if opt_maxlinesize != None and len(line) > opt_maxlinesize: + line = line[:opt_maxlinesize] + "[TRUNCATED]\n" + lines_parsed += 1 # Check if maximum number of new log messages is exceeded if opt_maxlines != None and lines_parsed > opt_maxlines: outputtxt += "%s Maximum number (%d) of new log messages exceeded.\n" % ( opt_overflow, opt_maxlines) worst = max(worst, opt_overflow_level) - os.lseek(fl, 0, 2) # Seek to end of file, skip all other messages + os.lseek(file_desc, 0, 2) # Seek to end of file, skip all other messages break # Check if maximum processing time (per file) is exceeded. Check only @@ -249,7 +254,7 @@ def process_logfile(logfile, patterns): outputtxt += "%s Maximum parsing time (%.1f sec) of this log file exceeded.\n" % ( opt_overflow, opt_maxtime) worst = max(worst, opt_overflow_level) - os.lseek(fl, 0, 2) # Seek to end of file, skip all other messages + os.lseek(file_desc, 0, 2) # Seek to end of file, skip all other messages break level = "." @@ -264,25 +269,25 @@ def process_logfile(logfile, patterns): for cont_pattern in cont_patterns: if type(cont_pattern) == int: # add that many lines for x in range(cont_pattern): - cont_line = next_line(f) + cont_line = next_line(file_handle) if cont_line == None: # end of file break - line = line[:-1] + "\1" + cont_line + line = line[:-1] + "\1" + cont_line else: # pattern is regex while True: - cont_line = next_line(f) + cont_line = next_line(file_handle) if cont_line == None: # end of file break elif cont_pattern.search(cont_line[:-1]): - line = line[:-1] + "\1" + cont_line + line = line[:-1] + "\1" + cont_line else: pushed_back_line = cont_line # sorry for stealing this line break # Replacement for replace in replacements: - line = replace.replace('\\0', line) + "\n" + line = replace.replace('\\0', line.rstrip()) + "\n" for nr, group in enumerate(matches.groups()): line = line.replace('\\%d' % (nr+1), group) @@ -297,7 +302,7 @@ def process_logfile(logfile, patterns): continue outputtxt += "%s%s %s%s\n" % (color, level, line[:-1], tty_normal) - new_offset = os.lseek(fl, 0, 1) # os.SEEK_CUR not available in Python 2.4 + new_offset = os.lseek(file_desc, 0, 1) # os.SEEK_CUR not available in Python 2.4 status[logfile] = new_offset, inode # output all lines if at least one warning, error or ok has been found @@ -305,6 +310,11 @@ def process_logfile(logfile, patterns): sys.stdout.write(outputtxt) sys.stdout.flush() + # Handle option maxfilesize, regardless of warning or errors that have happened + if opt_maxfilesize != None and offset <= opt_maxfilesize and new_offset > opt_maxfilesize: + sys.stdout.write("%sW Maximum allowed logfile size (%d bytes) exceeded.%s\n" % (tty_yellow, opt_maxfilesize, tty_normal)) + + try: config = read_config() except Exception, e: @@ -327,6 +337,8 @@ for filenames, patterns in config: # Initialize options with default values opt_maxlines = None opt_maxtime = None + opt_maxlinesize = None + opt_maxfilesize = None opt_regex = None opt_overflow = 'C' opt_overflow_level = 2 @@ -338,6 +350,10 @@ for filenames, patterns in config: opt_maxlines = int(value) elif key == 'maxtime': opt_maxtime = float(value) + elif key == 'maxlinesize': + opt_maxlinesize = int(value) + elif key == 'maxfilesize': + opt_maxfilesize = int(value) elif key == 'overflow': if value not in [ 'C', 'I', 'W', 'O' ]: raise Exception("Invalid value %s for overflow. Allowed are C, I, O and W" % value) @@ -358,14 +374,14 @@ for filenames, patterns in config: sys.exit(1) - for glob in filenames: - if '=' in glob: + for glob_pattern in filenames: + if '=' in glob_pattern: continue - logfiles = [ l.strip() for l in os.popen("ls %s 2>/dev/null" % glob).readlines() ] + logfiles = glob.glob(glob_pattern) if opt_regex: logfiles = [ f for f in logfiles if opt_regex.search(f) ] if len(logfiles) == 0: - print '[[[%s:missing]]]' % glob + print '[[[%s:missing]]]' % glob_pattern else: for logfile in logfiles: process_logfile(logfile, patterns) diff --git a/files/plugins/mk_logwatch_aix b/files/plugins/mk_logwatch_aix new file mode 100755 index 0000000..ed9daf5 --- /dev/null +++ b/files/plugins/mk_logwatch_aix @@ -0,0 +1,13 @@ +#!/usr/bin/ksh +# Beware: This Plugin clears the errors after each run, +# but it creates an detailed backup in /var/log/errpt_TIMESTAMP.log + +echo "<<>>" +echo "[[[errorlog]]]" +OUT=$(errpt | awk 'NR>1 { printf "C %s\n", $0 }') +if [[ $OUT != '' ]];then + echo $OUT + errpt -a > /var/log/errpt_$(date +%s).log + errclear 0 +fi + diff --git a/files/plugins/mk_mysql b/files/plugins/mk_mysql index de28d4c..5d4be2d 100755 --- a/files/plugins/mk_mysql +++ b/files/plugins/mk_mysql @@ -1,5 +1,4 @@ #!/bin/bash -# -*- encoding: utf-8; py-indent-offset: 4 -*- # +------------------------------------------------------------------+ # | ____ _ _ __ __ _ __ | # | / ___| |__ ___ ___| | __ | \/ | |/ / | @@ -7,7 +6,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2012 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. @@ -24,12 +23,20 @@ # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA. -if which mysqladmin > /dev/null +if which mysqladmin >/dev/null then # Check if mysqld is running and root password setup echo "<<>>" mysqladmin --defaults-extra-file=$MK_CONFDIR/mysql.cfg ping 2>&1 mysql --defaults-extra-file=$MK_CONFDIR/mysql.cfg -sN \ - -e "select '<<>>' ; show global status; show global variables; select '<<>>' ; SELECT table_schema, sum( data_length + index_length ), sum( data_free ) FROM information_schema.TABLES GROUP BY table_schema;" + -e "select '<<>>' ; + show global status ; show global variables ; + + select '<<>>' ; + SELECT table_schema, sum(data_length + index_length), sum(data_free) + FROM information_schema.TABLES GROUP BY table_schema" + + mysql --defaults-extra-file=$MK_CONFDIR/mysql.cfg -s \ + -e "SELECT '<<>>' ; show slave status\G" fi diff --git a/files/plugins/mk_oracle b/files/plugins/mk_oracle index 98a3604..cada4a2 100755 --- a/files/plugins/mk_oracle +++ b/files/plugins/mk_oracle @@ -6,7 +6,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2010 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. @@ -24,38 +24,71 @@ # Boston, MA 02110-1301 USA. # Check_MK agent plugin for monitoring ORACLE databases +# This plugin is a result of the common work of Thorsten Bruhns +# and Mathias Kettner. Thorsten is responsible for the ORACLE +# stuff, Mathias for the shell hacking... -# Get list of all running databases -SIDS=$(UNIX95=true ps ax -o args | sed -n '/^\(ora\|xe\)_pmon_\([^ ]*\)/s//\2/p') -if [ -z "$SIDS" ] ; then - # If on this system we've already found a database - if [ -e "$MK_CONFDIR/mk_oracle.found" ] ; then - echo '<<>>' - echo '<<>>' - echo '<<>>' - echo '<<>>' - fi - exit 0 -fi +# Example for mk_oracle.cfg +# DBUSER=:::: +# ASMUSER=:::: +# +# SYSDBA or SYSASM is optional but needed for a mounted instance +# HOSTNAME is optional - Default is localhost +# PORT is optional - Default is 1521 -touch $MK_CONFDIR/mk_oracle.found +while test $# -gt 0 +do + if [ "${1}" = '-d' ] ; then + set -xv ; DEBUG=1 + elif [ "${1}" = '-t' ] ; then + DEBUGCONNECT=1 + fi + shift +done -# Recreate data if cachefile is older than 120 seconds. -# If you set this to 0, then the cache file will be created -# as often as possible. If the database queries last longer -# then your check interval, caching will be active nevertheless. -CACHE_MAXAGE=120 +if [ ! "$MK_CONFDIR" ] ; then + echo "MK_CONFDIR not set!" >&2 + exit 1 +fi -# Source the optional configuration file for this agent plugin -if [ -e "$MK_CONFDIR/mk_oracle.cfg" ] -then - . $MK_CONFDIR/mk_oracle.cfg +if [ ! "$MK_VARDIR" ] ; then + export MK_VARDIR=$MK_CONFDIR fi + +# .--Config--------------------------------------------------------------. +# | ____ __ _ | +# | / ___|___ _ __ / _(_) __ _ | +# | | | / _ \| '_ \| |_| |/ _` | | +# | | |__| (_) | | | | _| | (_| | | +# | \____\___/|_| |_|_| |_|\__, | | +# | |___/ | +# +----------------------------------------------------------------------+ +# | The user can override and set variables in mk_oracle.cfg | +# '----------------------------------------------------------------------' + +# Sections that run fast and do no caching +SYNC_SECTIONS="instance sessions logswitches undostat recovery_area processes recovery_status longactivesessions dataguard_stats performance" + +# Sections that are run in the background and at a larger interval. +# Note: sections not listed in SYNC_SECTIONS or ASYNC_SECTIONS will not be +# executed at all! +ASYNC_SECTIONS="tablespaces rman jobs ts_quotas resumable locks" + +# Sections that are run in the background and at a larger interval. +# Note: _ASM_ sections are only executed when SID starts with '+' +# sections listed in SYNC_SECTIONS or ASYNC_SECTIONS are not +# executed for ASM. +SYNC_ASM_SECTIONS="instance" +ASYNC_ASM_SECTIONS="asm_diskgroup" + +# Interval for running async checks (in seconds) +CACHE_MAXAGE=600 + # You can specify a list of SIDs to monitor. Those databases will -# only be handled, if they are found running, though! +# only be handled, if they are found running, though! # -# ONLY_SIDS="XE HIRN SEPP" +# ONLY_SIDS="XE ORCL FOO BAR" # # It is possible to filter SIDS negatively. Just add the following to # the mk_oracle.cfg file: @@ -73,38 +106,879 @@ fi # # EXCLUDE_mysid="sessions logswitches" # -# -# This check uses a cache file to prevent problems with long running -# SQL queries. It starts building a cache when -# a) no cache is present or the cache is too old and -# b) the cache is not currently being built -# The cache is used for $CACHE_MAXAGE seconds. The CACHE_MAXAGE -# option is pre-set to 120 seconds but can be changed in mk_oracle.cfg. +# Source the optional configuration file for this agent plugin +if [ -e "$MK_CONFDIR/mk_oracle.cfg" ] +then + . $MK_CONFDIR/mk_oracle.cfg +fi + +#. +# .--SQL Queries---------------------------------------------------------. +# | ____ ___ _ ___ _ | +# | / ___| / _ \| | / _ \ _ _ ___ _ __(_) ___ ___ | +# | \___ \| | | | | | | | | | | |/ _ \ '__| |/ _ \/ __| | +# | ___) | |_| | |___ | |_| | |_| | __/ | | | __/\__ \ | +# | |____/ \__\_\_____| \__\_\\__,_|\___|_| |_|\___||___/ | +# | | +# +----------------------------------------------------------------------+ +# | The following functions create SQL queries for ORACLE and output | +# | them to stdout. All queries output the database name or the instane | +# | name as first column. | +# '----------------------------------------------------------------------' + +sql_performance() +{ + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "select upper(i.INSTANCE_NAME) + ||'|'|| 'sys_time_model' + ||'|'|| S.STAT_NAME + ||'|'|| Round(s.value/1000000) + from v\$instance i, + v\$sys_time_model s + where s.stat_name in('DB time', 'DB CPU') + order by s.stat_name; + select upper(i.INSTANCE_NAME) + ||'|'|| 'buffer_pool_statistics' + ||'|'|| b.name + ||'|'|| b.db_block_gets + ||'|'|| b.db_block_change + ||'|'|| b.consistent_gets + ||'|'|| b.physical_reads + ||'|'|| b.physical_writes + ||'|'|| b.FREE_BUFFER_WAIT + ||'|'|| b.BUFFER_BUSY_WAIT + from v\$instance i, V\$BUFFER_POOL_STATISTICS b; + select upper(i.INSTANCE_NAME) + ||'|'|| 'librarycache' + ||'|'|| b.namespace + ||'|'|| b.gets + ||'|'|| b.gethits + ||'|'|| b.pins + ||'|'|| b.pinhits + ||'|'|| b.reloads + ||'|'|| b.invalidations + from v\$instance i, V\$librarycache b;" + fi +} + +sql_tablespaces() +{ + echo 'PROMPT <<>>' + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + + echo "select upper(d.NAME) || '|' || file_name ||'|'|| tablespace_name ||'|'|| fstatus ||'|'|| AUTOEXTENSIBLE + ||'|'|| blocks ||'|'|| maxblocks ||'|'|| USER_BLOCKS ||'|'|| INCREMENT_BY + ||'|'|| ONLINE_STATUS ||'|'|| BLOCK_SIZE + ||'|'|| decode(tstatus,'READ ONLY', 'READONLY', tstatus) || '|' || free_blocks + ||'|'|| contents + from v\$database d , ( + select f.file_name, f.tablespace_name, f.status fstatus, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, + f.ONLINE_STATUS, t.BLOCK_SIZE, t.status tstatus, nvl(sum(fs.blocks),0) free_blocks, t.contents + from dba_data_files f, dba_tablespaces t, dba_free_space fs + where f.tablespace_name = t.tablespace_name + and f.file_id = fs.file_id(+) + group by f.file_name, f.tablespace_name, f.status, f.autoextensible, + f.blocks, f.maxblocks, f.user_blocks, f.increment_by, f.online_status, + t.block_size, t.status, t.contents + UNION + select f.file_name, f.tablespace_name, f.status, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, 'TEMP', + t.BLOCK_SIZE, t.status, sum(sh.blocks_free) free_blocks, 'TEMPORARY' + from v\$thread th, dba_temp_files f, dba_tablespaces t, v\$temp_space_header sh + WHERE f.tablespace_name = t.tablespace_name and f.file_id = sh.file_id + GROUP BY th.instance, f.file_name, f.tablespace_name, f.status, + f.autoextensible, f.blocks, f.maxblocks, f.user_blocks, f.increment_by, + 'TEMP', t.block_size, t.status); + " + elif [ "$AT_LEAST_ORACLE_92" = 'yes' ] ; then + + echo "select upper(d.NAME) || '|' || file_name ||'|'|| tablespace_name ||'|'|| fstatus ||'|'|| AUTOEXTENSIBLE + ||'|'|| blocks ||'|'|| maxblocks ||'|'|| USER_BLOCKS ||'|'|| INCREMENT_BY + ||'|'|| ONLINE_STATUS ||'|'|| BLOCK_SIZE + ||'|'|| decode(tstatus,'READ ONLY', 'READONLY', tstatus) || '|' || free_blocks + ||'|'|| contents + from v\$database d , ( + select f.file_name, f.tablespace_name, f.status fstatus, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, + 'ONLINE' ONLINE_STATUS, t.BLOCK_SIZE, t.status tstatus, nvl(sum(fs.blocks),0) free_blocks, t.contents + from dba_data_files f, dba_tablespaces t, dba_free_space fs + where f.tablespace_name = t.tablespace_name + and f.file_id = fs.file_id(+) + group by f.file_name, f.tablespace_name, f.status, f.autoextensible, + f.blocks, f.maxblocks, f.user_blocks, f.increment_by, 'ONLINE', + t.block_size, t.status, t.contents + UNION + select f.file_name, f.tablespace_name, 'ONLINE' status, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, 'TEMP', + t.BLOCK_SIZE, 'TEMP' status, sum(sh.blocks_free) free_blocks, 'TEMPORARY' + from v\$thread th, dba_temp_files f, dba_tablespaces t, v\$temp_space_header sh + WHERE f.tablespace_name = t.tablespace_name and f.file_id = sh.file_id + GROUP BY th.instance, f.file_name, f.tablespace_name, 'ONLINE', + f.autoextensible, f.blocks, f.maxblocks, f.user_blocks, f.increment_by, + 'TEMP', t.block_size, t.status); + " + fi +} + +sql_dataguard_stats() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "SELECT upper(d.NAME) + ||'|'|| upper(d.DB_UNIQUE_NAME) + ||'|'|| d.DATABASE_ROLE + ||'|'|| ds.name + ||'|'|| ds.value + FROM v\$database d + JOIN v\$parameter vp on 1=1 + left outer join V\$dataguard_stats ds on 1=1 + WHERE vp.name = 'log_archive_config' + AND vp.value is not null + ORDER BY 1; + " + fi +} + +sql_recovery_status() +{ + echo 'PROMPT <<>>' + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo "SELECT upper(d.NAME) + ||'|'|| d.DB_UNIQUE_NAME + ||'|'|| d.DATABASE_ROLE + ||'|'|| d.open_mode + ||'|'|| dh.file# + ||'|'|| round((dh.CHECKPOINT_TIME-to_date('01.01.1970','dd.mm.yyyy'))*24*60*60) + ||'|'|| round((sysdate-dh.CHECKPOINT_TIME)*24*60*60) + ||'|'|| dh.STATUS + ||'|'|| dh.RECOVER + ||'|'|| dh.FUZZY + ||'|'|| dh.CHECKPOINT_CHANGE# + FROM V\$datafile_header dh, v\$database d, v\$instance i + ORDER BY dh.file#; + " + elif [ "$AT_LEAST_ORACLE_92" = 'yes' ] ; then + echo "SELECT upper(d.NAME) + ||'|'|| d.NAME + ||'|'|| d.DATABASE_ROLE + ||'|'|| d.open_mode + ||'|'|| dh.file# + ||'|'|| round((dh.CHECKPOINT_TIME-to_date('01.01.1970','dd.mm.yyyy'))*24*60*60) + ||'|'|| round((sysdate-dh.CHECKPOINT_TIME)*24*60*60) + ||'|'|| dh.STATUS + ||'|'|| dh.RECOVER + ||'|'|| dh.FUZZY + ||'|'|| dh.CHECKPOINT_CHANGE# + FROM V\$datafile_header dh, v\$database d, v\$instance i + ORDER BY dh.file#; + " + fi +} + +sql_rman() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "SELECT upper(d.NAME) + ||'|'|| a.STATUS + ||'|'|| to_char(a.START_TIME, 'YYYY-mm-dd_HH24:MI:SS') + ||'|'|| to_char(a.END_TIME, 'YYYY-mm-dd_HH24:MI:SS') + ||'|'|| replace(b.INPUT_TYPE, ' ', '_') + ||'|'|| round(((sysdate - END_TIME) * 24 * 60),0) + FROM V\$RMAN_BACKUP_JOB_DETAILS a, v\$database d, + (SELECT input_type, max(command_id) as command_id + FROM V\$RMAN_BACKUP_JOB_DETAILS + WHERE START_TIME > sysdate-14 + and input_type != 'ARCHIVELOG' + and STATUS<>'RUNNING' GROUP BY input_type) b + WHERE a.COMMAND_ID = b.COMMAND_ID + UNION ALL + select name + || '|COMPLETED' + || '|'|| to_char(sysdate, 'YYYY-mm-dd_HH24:MI:SS') + || '|'|| to_char(completed, 'YYYY-mm-dd_HH24:MI:SS') + || '|ARCHIVELOG|' + || round((sysdate - completed)*24*60,0) + from ( + select d.name + , max(a.completion_time) completed + , case when a.backup_count > 0 then 1 else 0 end + from v\$archived_log a, v\$database d + where a.backup_count > 0 + and a.dest_id in + (select b.dest_id + from v\$archive_dest b + where b.target = 'PRIMARY' + and b.SCHEDULE = 'ACTIVE' + ) + group by d.name, case when a.backup_count > 0 then 1 else 0 end);" + fi +} + +sql_recovery_area() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "select upper(d.NAME) + ||' '|| round((SPACE_USED-SPACE_RECLAIMABLE)/ + (CASE NVL(SPACE_LIMIT,1) WHEN 0 THEN 1 ELSE SPACE_LIMIT END)*100) + ||' '|| round(SPACE_LIMIT/1024/1024) + ||' '|| round(SPACE_USED/1024/1024) + ||' '|| round(SPACE_RECLAIMABLE/1024/1024) + from V\$RECOVERY_FILE_DEST, v\$database d; + " + fi +} + +sql_undostat() +{ + echo 'PROMPT <<>>' + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo "select upper(i.INSTANCE_NAME) + ||'|'|| ACTIVEBLKS + ||'|'|| MAXCONCURRENCY + ||'|'|| TUNED_UNDORETENTION + ||'|'|| maxquerylen + ||'|'|| NOSPACEERRCNT + from v\$instance i, + (select * from (select * + from v\$undostat order by end_time desc + ) + where rownum = 1 + and TUNED_UNDORETENTION > 0 + ); + " + elif [ "$AT_LEAST_ORACLE_92" = 'yes' ] ; then + # TUNED_UNDORETENTION and ACTIVEBLKS are not availibe in Oracle <=9.2! + # we sent a -1 for filtering in check_undostat + echo "select upper(i.INSTANCE_NAME) + ||'|-1' + ||'|'|| MAXCONCURRENCY + ||'|-1' + ||'|'|| maxquerylen + ||'|'|| NOSPACEERRCNT + from v\$instance i, + (select * from (select * + from v\$undostat order by end_time desc + ) + where rownum = 1 + ); + " + fi +} + +sql_resumable() +{ + echo 'PROMPT <<>>' + echo "select upper(i.INSTANCE_NAME) + ||'|'|| u.username + ||'|'|| a.SESSION_ID + ||'|'|| a.status + ||'|'|| a.TIMEOUT + ||'|'|| round((sysdate-to_date(a.SUSPEND_TIME,'mm/dd/yy hh24:mi:ss'))*24*60*60) + ||'|'|| a.ERROR_NUMBER + ||'|'|| to_char(to_date(a.SUSPEND_TIME, 'mm/dd/yy hh24:mi:ss'),'mm/dd/yy_hh24:mi:ss') + ||'|'|| a.RESUME_TIME + ||'|'|| a.ERROR_MSG + from dba_resumable a, v\$instance i, dba_users u + where a.INSTANCE_ID = i.INSTANCE_NUMBER + and u.user_id = a.user_id + and a.SUSPEND_TIME is not null + union all + select upper(i.INSTANCE_NAME) + || '|||||||||' + from v\$instance i +; + " +} + +sql_jobs() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "SELECT upper(d.NAME) + ||'|'|| j.OWNER + ||'|'|| j.JOB_NAME + ||'|'|| j.STATE + ||'|'|| ROUND((TRUNC(sysdate) + j.LAST_RUN_DURATION - TRUNC(sysdate)) * 86400) + ||'|'|| j.RUN_COUNT + ||'|'|| j.ENABLED + ||'|'|| NVL(j.NEXT_RUN_DATE, to_date('1970-01-01', 'YYYY-mm-dd')) + ||'|'|| NVL(j.SCHEDULE_NAME, '-') + ||'|'|| d.STATUS + FROM dba_scheduler_jobs j, dba_scheduler_job_run_details d, v\$database d + WHERE d.owner=j.OWNER AND d.JOB_NAME=j.JOB_NAME + AND d.LOG_ID=(SELECT max(LOG_ID) FROM dba_scheduler_job_run_details dd + WHERE dd.owner=j.OWNER and dd.JOB_NAME=j.JOB_NAME + ); + " + fi +} + +sql_ts_quotas() +{ + echo 'PROMPT <<>>' + echo "select upper(d.NAME) + ||'|'|| Q.USERNAME + ||'|'|| Q.TABLESPACE_NAME + ||'|'|| Q.BYTES + ||'|'|| Q.MAX_BYTES + from dba_ts_quotas Q, v\$database d + where max_bytes > 0 + union all + select upper(d.NAME) + ||'|||' + from v\$database d + order by 1; + " +} + +sql_version() +{ + echo 'PROMPT <<>>' + echo "select upper(i.INSTANCE_NAME) + || ' ' || banner + from v\$version, v\$instance i + where banner like 'Oracle%';" +} + +sql_instance() +{ + echo 'prompt <<>>' + if [ ${ORACLE_SID:0:1} = '+' ] ; then + # ASM + echo "select upper(i.instance_name) + || '|' || i.VERSION + || '|' || i.STATUS + || '|' || i.LOGINS + || '|' || i.ARCHIVER + || '|' || round((sysdate - i.startup_time) * 24*60*60) + || '|' || '0' + || '|' || 'NO' + || '|' || 'ASM' + || '|' || 'NO' + || '|' || i.instance_name + from v\$instance i; + " + else + # normal Instance + echo "select upper(i.instance_name) + || '|' || i.VERSION + || '|' || i.STATUS + || '|' || i.LOGINS + || '|' || i.ARCHIVER + || '|' || round((sysdate - i.startup_time) * 24*60*60) + || '|' || DBID + || '|' || LOG_MODE + || '|' || DATABASE_ROLE + || '|' || FORCE_LOGGING + || '|' || d.name + from v\$instance i, v\$database d; + " + fi +} + +sql_sessions() +{ + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || ' ' || CURRENT_UTILIZATION + from v\$resource_limit, v\$instance i + where RESOURCE_NAME = 'sessions'; + " +} + +sql_processes() +{ + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || ' ' || CURRENT_UTILIZATION + || ' ' || ltrim(rtrim(LIMIT_VALUE)) + from v\$resource_limit, v\$instance i + where RESOURCE_NAME = 'processes'; + " +} + +sql_logswitches() +{ + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || ' ' || logswitches + from v\$instance i , + (select count(1) logswitches + from v\$loghist + where first_time > sysdate - 1/24 + ); + " +} + +sql_locks() +{ + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo 'prompt <<>>' + echo "SET SERVEROUTPUT ON feedback off +DECLARE + type x is table of varchar2(20000) index by pls_integer; + xx x; +begin + begin + execute immediate 'select upper(i.instance_name) + || ''|'' || a.sid + || ''|'' || b.serial# + || ''|'' || b.machine + || ''|'' || b.program + || ''|'' || b.process + || ''|'' || b.osuser + || ''|'' || a.ctime + || ''|'' || decode(c.owner,NULL,''NULL'',c.owner) + || ''|'' || decode(c.object_name,NULL,''NULL'',c.object_name) + from V\$LOCK a, v\$session b, dba_objects c, v\$instance i + where (a.id1, a.id2, a.type) + IN (SELECT id1, id2, type + FROM GV\$LOCK + WHERE request>0 + ) + and request=0 + and a.sid = b.sid + and a.id1 = c.object_id (+) + union all + select upper(i.instance_name) || ''|||||||||'' + from v\$instance i' + bulk collect into xx; + if xx.count >= 1 then + for i in 1 .. xx.count loop + dbms_output.put_line(xx(i)); + end loop; + end if; + exception + when others then + for cur1 in (select upper(i.instance_name) instance_name from v\$instance i) loop + dbms_output.put_line(cur1.instance_name || '|||||||||'||sqlerrm); + end loop; + end; +END; +/ +set serverout off +" + fi +} + +sql_longactivesessions() +{ + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || '|' || s.sid + || '|' || s.serial# + || '|' || s.machine + || '|' || s.process + || '|' || s.osuser + || '|' || s.program + || '|' || s.last_call_et + || '|' || s.sql_id + from v\$session s, v\$instance i + where s.status = 'ACTIVE' + and type != 'BACKGROUND' + and s.username is not null + and s.username not in('PUBLIC') + and s.last_call_et > 60*60 + union all + select upper(i.instance_name) + || '||||||||' + from v\$instance i; + " + fi +} + +sql_asm_diskgroup() +{ + echo 'prompt <<>>' + if [ "$AT_LEAST_ORACLE_112" = 'yes' ] ; then + echo "select STATE + || ' ' || TYPE + || ' ' || 'N' + || ' ' || sector_size + || ' ' || block_size + || ' ' || allocation_unit_size + || ' ' || total_mb + || ' ' || free_mb + || ' ' || required_mirror_free_mb + || ' ' || usable_file_mb + || ' ' || offline_disks + || ' ' || voting_files + || ' ' || name || '/' + from v\$asm_diskgroup; + " + elif [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo "select STATE + || ' ' || TYPE + || ' ' || 'N' + || ' ' || sector_size + || ' ' || block_size + || ' ' || allocation_unit_size + || ' ' || total_mb + || ' ' || free_mb + || ' ' || required_mirror_free_mb + || ' ' || usable_file_mb + || ' ' || offline_disks + || ' ' || 'N' + || ' ' || name || '/' + from v\$asm_diskgroup; + " + fi +} + +#. +# .--oraenv--------------------------------------------------------------. +# | | +# | ___ _ __ __ _ ___ _ ____ __ | +# | / _ \| '__/ _` |/ _ \ '_ \ \ / / | +# | | (_) | | | (_| | __/ | | \ V / | +# | \___/|_| \__,_|\___|_| |_|\_/ | +# | | +# +----------------------------------------------------------------------+ +# | Functions for getting the Oracle environment | +# '----------------------------------------------------------------------' + +function set_oraenv () { + ORACLE_SID=${1} + + test -f /etc/oratab && ORATAB=/etc/oratab + # /var/opt/oracle/oratab is needed for Oracle Solaris + test -f /var/opt/oracle/oratab && ORATAB=/var/opt/oracle/oratab + test -f ${ORATAB:-""} || echo "ORA-99999 oratab not found" + test -f ${ORATAB:-""} || exit 1 + + ORACLE_HOME=$(cat ${ORATAB} | grep "^"${ORACLE_SID}":" | cut -d":" -f2) + if [ -z $ORACLE_HOME ] ; then + # cut last number from SID for Oracle RAC to find entry in oratab + ORACLE_SID_SHORT=$(echo $ORACLE_SID | sed "s/[0-9]$//") + ORACLE_HOME=$(cat ${ORATAB} | grep "^"${ORACLE_SID_SHORT}":" | cut -d":" -f2) + fi + + if [ ! -d ${ORACLE_HOME:-"not_found"} ] ; then + echo "ORA-99999 ORACLE_HOME for ORACLE_SID="$ORACLE_SID" not found or not existing!" + exit 1 + fi + + TNS_ADMIN=${TNS_ADMIN:-$MK_CONFDIR} + + test -f ${TNS_ADMIN}/sqlnet.ora || ( echo "ORA-99998 Couldn't find "${TNS_ADMIN}/sqlnet.ora ; exit 1) + + export ORACLE_HOME TNS_ADMIN ORACLE_SID +} + +function get_oraversion () { + set_oraenv ${1} + ORACLE_VERSION=$($ORACLE_HOME/bin/sqlplus -V | grep ^SQL | cut -d" " -f3 | cut -d"." -f-2) + + # remove possible existing variables + unset AT_LEAST_ORACLE_121 AT_LEAST_ORACLE_112 AT_LEAST_ORACLE_111 AT_LEAST_ORACLE_102 AT_LEAST_ORACLE_101 AT_LEAST_ORACLE_92 + + if [ "$ORACLE_VERSION" = '12.1' ] ; then + AT_LEAST_ORACLE_121=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' ] ; then + AT_LEAST_ORACLE_112=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' ] ; then + AT_LEAST_ORACLE_111=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' -o "$ORACLE_VERSION" = '10.2' ] ; then + AT_LEAST_ORACLE_102=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' -o "$ORACLE_VERSION" = '10.2' \ + -o "$ORACLE_VERSION" = '10.1' ] ; then + AT_LEAST_ORACLE_101=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' -o "$ORACLE_VERSION" = '10.2' \ + -o "$ORACLE_VERSION" = '10.1' -o "$ORACLE_VERSION" = '9.2' ] ; then + AT_LEAST_ORACLE_92=yes + fi +} + +#. +# .--Functions-----------------------------------------------------------. +# | _____ _ _ | +# | | ___| _ _ __ ___| |_(_) ___ _ __ ___ | +# | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \/ __| | +# | | _|| |_| | | | | (__| |_| | (_) | | | \__ \ | +# | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/ | +# | | +# +----------------------------------------------------------------------+ +# | Helper functions | +# '----------------------------------------------------------------------' + +function sqlplus_internal() { + loc_stdin=$(cat) + set_oraenv $SID + + # reload mk_oracle.cfg for run_cached. Otherwise some variables are missing + if [ -e "$MK_CONFDIR/mk_oracle.cfg" ] + then + . $MK_CONFDIR/mk_oracle.cfg + fi + + # mk_oracle_dbusers.conf is for compatibility. Do not use it anymore + ORACLE_USERCONF=${MK_CONFDIR}/mk_oracle_dbuser.conf + + TNSPINGOK=no + if [ -f ${TNS_ADMIN}/tnsnames.ora ] ; then + if "${ORACLE_HOME}"/bin/tnsping "${ORACLE_SID}" >/dev/null 2>&1 ; then + TNSALIAS=$ORACLE_SID + TNSPINGOK=yes + fi + fi + + ORADBUSER="" + DBPASSWORD="" + + # ASM use '+' as 1st character in SID! + if [ ${ORACLE_SID:0:1} = '+' ] ; then + ORACFGLINE=${ASMUSER} + else + # use an individuel user or the default DBUSER from mk_oracle.cfg + dummy="DBUSER_"${ORACLE_SID} + ORACFGLINE=${!dummy} + if [ "$ORACFGLINE" = '' ] ; then + ORACFGLINE=${DBUSER} + fi + fi + + if [ -f ${ORACLE_USERCONF} -a "${ORACFGLINE}" = '' ] ; then + # mk_oracle_dbuser.conf + ORACFGLINE=$(cat ${ORACLE_USERCONF} | grep "^"${ORACLE_SID}":") + # mk_oracle_dbuser has ORACLE_SID as 1. parameter. we need an offset for all values + offset=1 + else + # mk_oracle.cfg + offset=0 + fi + + ORADBUSER=$(echo ${ORACFGLINE} | cut -d":" -f$[1+offset]) + DBPASSWORD=$(echo ${ORACFGLINE} | cut -d":" -f$[2+offset]) + DBSYSCONNECT=$(echo ${ORACFGLINE} | cut -d":" -f$[3+offset]) + DBHOST=$(echo ${ORACFGLINE} | cut -d":" -f$[4+offset]) + DBPORT=$(echo ${ORACFGLINE} | cut -d":" -f$[5+offset]) + + if [ ! "${ORACFGLINE}" ] ; then + # no configuration found + # => use the wallet with tnsnames.ora or EZCONNECT + TNSALIAS=${TNSALIAS:-"localhost:1521/${ORACLE_SID}"} + else + if [ ${DBSYSCONNECT} ] ; then + assysdbaconnect=" as "${DBSYSCONNECT} + fi + TNSALIAS=${TNSALIAS:-"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=${DBHOST:-"localhost"})(PORT=${DBPORT:-1521}))(CONNECT_DATA=(SID=${ORACLE_SID})(SERVER=DEDICATED)(UR=A)))"} + + # ORADBUSER = '/'? => ignore DBPASSWORD and use the wallet + if [ "${ORADBUSER}" = '/' ] ; then + # connect with / and wallet + ORADBUSER="" + DBPASSWORD="" + if [ "$TNSPINGOK" = 'no' ] ; then + # create an EZCONNECT string when no tnsnames.ora is usable + # defaults to localhost:1521/ + TNSALIAS="${DBHOST:-"localhost"}:${DBPORT:-1521}/${ORACLE_SID}" + fi + fi + fi + + DBCONNECT="${ORADBUSER}/${DBPASSWORD}@${TNSALIAS}${assysdbaconnect}" + + SQLPLUS=${ORACLE_HOME}/bin/sqlplus + if [ ! -x ${SQLPLUS} ] ; then + echo "sqlplus not found or ORACLE_HOME wrong! " + echo "SQLPLUS="${SQLPLUS} + return 1 + fi + + echo "$loc_stdin" | ${SQLPLUS} -L -s ${DBCONNECT} + if [ $? -ne 0 ] ; then + if [ "$DEBUGCONNECT" ] ; then + echo "Logindetails: ${DBCONNECT}" >&2 + fi + return 1 + fi +} + +# Helper function that calls an SQL statement with a clean output +# Usage: echo "..." | sqlplus SID function sqlplus () { - if OUTPUT=$({ echo 'set pages 0' ; echo 'whenever sqlerror exit 1'; echo 'set lines 8000' ; echo 'set feedback off'; cat ; } | $MK_CONFDIR/sqlplus.sh $1) + local SID=$1 + loc_stdin=$(cat) + + # use sqlplus_internal when no sqlplus.sh is found + SQLPLUS="$MK_CONFDIR"/sqlplus.sh + test -f "$SQLPLUS" || SQLPLUS=sqlplus_internal + + if OUTPUT=$({ echo 'set pages 0 trimspool on feedback off lines 8000' ; echo 'whenever sqlerror exit 1'; echo "$loc_stdin" ; } | "$SQLPLUS" $SID) then - echo "${OUTPUT}" | sed -e 's/[[:space:]]\+/ /g' -e '/^[[:space:]]*$/d' -e "s/^/$1 /" + echo "$OUTPUT" else - echo "${OUTPUT}" | sed "s/^/$1 FAILURE /" + echo '<<>>' + local SID_UPPER=$(echo "$SID" | tr '[:lower:]' '[:upper:]') + echo "$OUTPUT" | grep -v "^ERROR at line" | tr '\n' ' ' | sed "s/^/$SID_UPPER|FAILURE|/" ; echo + return 1 + fi +} + +function remove_excluded_sections () +{ + local sections="$1" + local excluded="$2" + local result="" + for section in $sections + do + local skip= + for exclude in $excluded + do + if [ "$exclude" = "$section" ] ; then + local skip=yes + break + fi + done + if [ "$skip" != yes ] ; then + result="$result $section" + fi + done + echo "$result" +} + + +# Create one SQL statements for several sections and run +# these with sqlplus. The exitcode is preserved. +function do_sync_checks () +{ + local SID=$1 + local SECTIONS="$2" + for section in $SECTIONS + do + eval "sql_$section" + done | sqlplus $SID +} + +function do_async_checks () +{ + local SID=$1 + echo "$ASYNC_SQL" | sqlplus $SID +} + +# Make sure that the new shell that is being run by run_cached inherits +# our functions +export -f sqlplus +export -f sqlplus_internal +export -f do_async_checks +export -f set_oraenv + +function run_cached_local () { + local section= + if [ "$1" = -s ] ; then local section="echo '<<<$2>>>' ; " ; shift ; fi + local NAME=$1 + local MAXAGE=$2 + shift 2 + local CMDLINE="$section$@" + + if [ ! -d $MK_VARDIR/cache ]; then mkdir -p $MK_VARDIR/cache ; fi + CACHEFILE="$MK_VARDIR/cache/$NAME.cache" + + # Check if the creation of the cache takes suspiciously long and return + # nothing if the age (access time) of $CACHEFILE.new is twice the MAXAGE + local NOW=$(date +%s) + if [ -e "$CACHEFILE.new" ] ; then + local CF_ATIME=$(stat -c %X "$CACHEFILE.new") + if [ $((NOW - CF_ATIME)) -ge $((MAXAGE * 2)) ] ; then + return + fi + fi + + # Check if cache file exists and is recent enough + if [ -s "$CACHEFILE" ] ; then + local MTIME=$(stat -c %Y "$CACHEFILE") + if [ $((NOW - MTIME)) -le $MAXAGE ] ; then local USE_CACHEFILE=1 ; fi + # Output the file in any case, even if it is + # outdated. The new file will not yet be available + cat "$CACHEFILE" + fi + + # Cache file outdated and new job not yet running? Start it + if [ -z "$USE_CACHEFILE" -a ! -e "$CACHEFILE.new" ] ; then + if [ "$DEBUG" ] ; then + echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | bash + else + echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup bash 2>/dev/null & + fi fi } +#. +# .--Main----------------------------------------------------------------. +# | __ __ _ | +# | | \/ | __ _(_)_ __ | +# | | |\/| |/ _` | | '_ \ | +# | | | | | (_| | | | | | | +# | |_| |_|\__,_|_|_| |_| | +# | | +# +----------------------------------------------------------------------+ +# | Iterate over all instances and execute sync and async sections. | +# '----------------------------------------------------------------------' + +# Get list of all running databases +# Do not work on ASM in this plugin. => Ignore a running ASM-Instance! +SIDS=$(UNIX95=true ps -ef | awk '{print $NF}' | grep -E '^asm_pmon_|^ora_pmon_|^xe_pmon_XE' | cut -d"_" -f3-) + +# If we do not have found any running database instance, then either +# no ORACLE is present on this system or it's just currently not running. +# In the later case we ouput empty agent sections so that Check_MK will be +# happy and execute the actual check functions. +if [ -z "$SIDS" -a ! -e "$MK_VARDIR/mk_oracle.found" ] ; then + exit +fi + +# From now on we expect databases on this system (for ever) +touch $MK_VARDIR/mk_oracle.found + +# Make sure that always all sections are present, even +# in case of an error. Note: the section <<>> +# section shows the general state of a database instance. If +# that section fails for an instance then all other sections +# do not contain valid data anyway. +for section in $SYNC_SECTIONS $ASYNC_SECTIONS $SYNC_ASM_SECTIONS $ASYNC_ASM_SECTIONS +do + echo "<<>>" +done + +for SID in $SIDS +do + # We need the SID in uppercase at later time + SID_UPPER=$(echo $SID | tr '[:lower:]' '[:upper:]') -for SID in $SIDS; do # Check if SID is listed in ONLY_SIDS if this is used if [ "$ONLY_SIDS" ] ; then SKIP=yes for S in $ONLY_SIDS ; do if [ "$S" = "$SID" ] ; then - SKIP= - break - fi + SKIP= + break + fi done - if [ "$SKIP" ] ; then continue ; fi + if [ "$SKIP" ] ; then continue ; fi fi - + + # Handle explicit exclusion of instances EXCLUDE=EXCLUDE_$SID EXCLUDE=${!EXCLUDE} # SID filtered totally? @@ -112,112 +986,39 @@ for SID in $SIDS; do continue fi - # Do Version-Check (use as a general login check) without caching - if [ "$EXCLUDE" = "${EXCLUDE/version/}" ]; then - echo '<<>>' - echo "select banner from v\$version where banner like 'Oracle%';" | sqlplus "$SID" + if [ ${SID:0:1} = '+' ] ; then + DO_ASYNC_SECTIONS=${ASYNC_ASM_SECTIONS} + DO_SYNC_SECTIONS=${SYNC_ASM_SECTIONS} + else + # switch sections to ASM + DO_SYNC_SECTIONS=${SYNC_SECTIONS} + DO_ASYNC_SECTIONS=${ASYNC_SECTIONS} fi - CACHE_FILE=$MK_CONFDIR/oracle_$SID.cache - - # Check if file exists and recent enough - CACHE_FILE_UPTODATE= - if [ -s $CACHE_FILE ]; then - NOW=$(date +%s) - MTIME=$(stat -c %Y $CACHE_FILE) - if [ $(($NOW - $MTIME)) -le $CACHE_MAXAGE ]; then - CACHE_FILE_UPTODATE=1 - fi - fi + get_oraversion $SID - # If the cache file exists, output it, regardless of its age. If it's outdated - # then it will be recreated *asynchronously*. It's new contents will not - # be available here anyway. - if [ -s "$CACHE_FILE" ] ; then cat "$CACHE_FILE" ; fi + # Do sync checks + EXCLUDED=$(eval 'echo $EXCLUDE'"_$SID") + SECTIONS=$(remove_excluded_sections "$DO_SYNC_SECTIONS" "$EXCLUDED") - # When the cache file is not valid, we recreated it, but only if there is not - # yet a background process from a previous check still doing this! We see this - # because of the existance of the .new file - # When the cache is old and there is no *new file present, then start a query - # to update the information for this instance. - if [ -z "$CACHE_FILE_UPTODATE" -a ! -e "$CACHE_FILE.new" ] - then - setsid bash -c " - set -o noclobber - function sqlplus () - { - if OUTPUT=\$({ echo 'set pages 0' ; echo 'whenever sqlerror exit 1'; echo 'set lines 8000' ; echo 'set feedback off'; cat ; } | $MK_CONFDIR/sqlplus.sh \$1) - then - echo \"\${OUTPUT}\" | sed -e 's/[[:space:]]\+/ /g' -e '/^[[:space:]]*$/d' -e \"s/^/\$1 /\" - else - echo \"\${OUTPUT}\" | sed \"s/^/\$1 FAILURE /\" - fi - } - - { - # Only execute checks when not filtered - if [ '$EXCLUDE' = '${EXCLUDE/sessions/}' ]; then - echo '<<>>' - echo \"select count(1) from v\\\$session where status = 'ACTIVE';\" | sqlplus \"$SID\" - fi + # Do async checks + ASECTIONS=$(remove_excluded_sections "$DO_ASYNC_SECTIONS" "$EXCLUDED") + ASYNC_SQL=$(for section in $ASECTIONS ; do eval "sql_$section" ; done) + export ASYNC_SQL - if [ '$EXCLUDE' = '${EXCLUDE/logswitches/}' ]; then - echo '<<>>' - echo \"select count(1) from v\\\$loghist where first_time > sysdate - 1/24;\" | sqlplus \"$SID\" - fi + if [ "$DEBUGCONNECT" ] ; then + echo "-----------------------------------------------" + echo "Logincheck to Instance: "$SID" Version: "$ORACLE_VERSION + echo "select 'Login ok User: ' || user || ' on ' || host_name + from v\$instance;" | sqlplus $SID + echo "SYNC_SECTIONS=$SECTIONS" + echo "ASYNC_SECTIONS=$ASECTIONS" + # do not execute any check + continue + fi - if [ '$EXCLUDE' = '${EXCLUDE/jobs/}' ]; then - echo '<<>>' - sqlplus "$SID" <>>' - sqlplus "$SID" <'RUNNING' GROUP BY input_type) b - WHERE a.COMMAND_ID = b.COMMAND_ID; -EOF - fi + run_cached_local oracle_$SID $CACHE_MAXAGE do_async_checks $SID - if [ '$EXCLUDE' = '${EXCLUDE/tablespaces/}' ]; then - echo '<<>>' - sqlplus "$SID" < $CACHE_FILE.new && mv $CACHE_FILE.new $CACHE_FILE || rm -f $CACHE_FILE* - " - fi done diff --git a/files/plugins/mk_oracle.aix b/files/plugins/mk_oracle.aix new file mode 100755 index 0000000..9151657 --- /dev/null +++ b/files/plugins/mk_oracle.aix @@ -0,0 +1,1026 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Check_MK agent plugin for monitoring ORACLE databases +# This plugin is a result of the common work of Thorsten Bruhns +# and Mathias Kettner. Thorsten is responsible for the ORACLE +# stuff, Mathias for the shell hacking... + +# Example for mk_oracle.cfg +# DBUSER=:::: +# ASMUSER=:::: +# +# SYSDBA or SYSASM is optional but needed for a mounted instance +# HOSTNAME is optional - Default is localhost +# PORT is optional - Default is 1521 + +while test $# -gt 0 +do + if [ "${1}" = '-d' ] ; then + set -xv ; DEBUG=1 + elif [ "${1}" = '-t' ] ; then + DEBUGCONNECT=1 + fi + shift +done + +if [ ! "$MK_CONFDIR" ] ; then + echo "MK_CONFDIR not set!" >&2 + exit 1 +fi + +if [ ! "$MK_VARDIR" ] ; then + export MK_VARDIR=$MK_CONFDIR +fi + + +# .--Config--------------------------------------------------------------. +# | ____ __ _ | +# | / ___|___ _ __ / _(_) __ _ | +# | | | / _ \| '_ \| |_| |/ _` | | +# | | |__| (_) | | | | _| | (_| | | +# | \____\___/|_| |_|_| |_|\__, | | +# | |___/ | +# +----------------------------------------------------------------------+ +# | The user can override and set variables in mk_oracle.cfg | +# '----------------------------------------------------------------------' + +# Sections that run fast and do no caching +SYNC_SECTIONS="instance sessions logswitches undostat recovery_area processes recovery_status longactivesessions dataguard_stats performance" + +# Sections that are run in the background and at a larger interval. +# Note: sections not listed in SYNC_SECTIONS or ASYNC_SECTIONS will not be +# executed at all! +ASYNC_SECTIONS="tablespaces rman jobs ts_quotas resumable locks" + +# Sections that are run in the background and at a larger interval. +# Note: _ASM_ sections are only executed when SID starts with '+' +# sections listed in SYNC_SECTIONS or ASYNC_SECTIONS are not +# executed for ASM. +SYNC_ASM_SECTIONS="instance" +ASYNC_ASM_SECTIONS="asm_diskgroup" + +# Interval for running async checks (in seconds) +CACHE_MAXAGE=600 + +# You can specify a list of SIDs to monitor. Those databases will +# only be handled, if they are found running, though! +# +# ONLY_SIDS="XE ORCL FOO BAR" +# +# It is possible to filter SIDS negatively. Just add the following to +# the mk_oracle.cfg file: +# +# EXCLUDE_="ALL" +# +# Another option is to filter single checks for SIDS. Just add +# lines as follows to the mk_oracle.cfg file. One service per +# line: +# +# EXCLUDE_="" +# +# For example skip oracle_sessions and oracle_logswitches checks +# for the instance "mysid". +# +# EXCLUDE_mysid="sessions logswitches" +# + +# Source the optional configuration file for this agent plugin +if [ -e "$MK_CONFDIR/mk_oracle.cfg" ] +then + . $MK_CONFDIR/mk_oracle.cfg +fi + +#. +# .--SQL Queries---------------------------------------------------------. +# | ____ ___ _ ___ _ | +# | / ___| / _ \| | / _ \ _ _ ___ _ __(_) ___ ___ | +# | \___ \| | | | | | | | | | | |/ _ \ '__| |/ _ \/ __| | +# | ___) | |_| | |___ | |_| | |_| | __/ | | | __/\__ \ | +# | |____/ \__\_\_____| \__\_\\__,_|\___|_| |_|\___||___/ | +# | | +# +----------------------------------------------------------------------+ +# | The following functions create SQL queries for ORACLE and output | +# | them to stdout. All queries output the database name or the instane | +# | name as first column. | +# '----------------------------------------------------------------------' + +sql_performance() +{ + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "select upper(i.INSTANCE_NAME) + ||'|'|| 'sys_time_model' + ||'|'|| S.STAT_NAME + ||'|'|| Round(s.value/1000000) + from v\$instance i, + v\$sys_time_model s + where s.stat_name in('DB time', 'DB CPU') + order by s.stat_name; + select upper(i.INSTANCE_NAME) + ||'|'|| 'buffer_pool_statistics' + ||'|'|| b.name + ||'|'|| b.db_block_gets + ||'|'|| b.db_block_change + ||'|'|| b.consistent_gets + ||'|'|| b.physical_reads + ||'|'|| b.physical_writes + ||'|'|| b.FREE_BUFFER_WAIT + ||'|'|| b.BUFFER_BUSY_WAIT + from v\$instance i, V\$BUFFER_POOL_STATISTICS b; + select upper(i.INSTANCE_NAME) + ||'|'|| 'librarycache' + ||'|'|| b.namespace + ||'|'|| b.gets + ||'|'|| b.gethits + ||'|'|| b.pins + ||'|'|| b.pinhits + ||'|'|| b.reloads + ||'|'|| b.invalidations + from v\$instance i, V\$librarycache b;" + fi +} + +sql_tablespaces() +{ + echo 'PROMPT <<>>' + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + + echo "select upper(d.NAME) || '|' || file_name ||'|'|| tablespace_name ||'|'|| fstatus ||'|'|| AUTOEXTENSIBLE + ||'|'|| blocks ||'|'|| maxblocks ||'|'|| USER_BLOCKS ||'|'|| INCREMENT_BY + ||'|'|| ONLINE_STATUS ||'|'|| BLOCK_SIZE + ||'|'|| decode(tstatus,'READ ONLY', 'READONLY', tstatus) || '|' || free_blocks + ||'|'|| contents + from v\$database d , ( + select f.file_name, f.tablespace_name, f.status fstatus, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, + f.ONLINE_STATUS, t.BLOCK_SIZE, t.status tstatus, nvl(sum(fs.blocks),0) free_blocks, t.contents + from dba_data_files f, dba_tablespaces t, dba_free_space fs + where f.tablespace_name = t.tablespace_name + and f.file_id = fs.file_id(+) + group by f.file_name, f.tablespace_name, f.status, f.autoextensible, + f.blocks, f.maxblocks, f.user_blocks, f.increment_by, f.online_status, + t.block_size, t.status, t.contents + UNION + select f.file_name, f.tablespace_name, f.status, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, 'TEMP', + t.BLOCK_SIZE, t.status, sum(sh.blocks_free) free_blocks, 'TEMPORARY' + from v\$thread th, dba_temp_files f, dba_tablespaces t, v\$temp_space_header sh + WHERE f.tablespace_name = t.tablespace_name and f.file_id = sh.file_id + GROUP BY th.instance, f.file_name, f.tablespace_name, f.status, + f.autoextensible, f.blocks, f.maxblocks, f.user_blocks, f.increment_by, + 'TEMP', t.block_size, t.status); + " + elif [ "$AT_LEAST_ORACLE_92" = 'yes' ] ; then + + echo "select upper(d.NAME) || '|' || file_name ||'|'|| tablespace_name ||'|'|| fstatus ||'|'|| AUTOEXTENSIBLE + ||'|'|| blocks ||'|'|| maxblocks ||'|'|| USER_BLOCKS ||'|'|| INCREMENT_BY + ||'|'|| ONLINE_STATUS ||'|'|| BLOCK_SIZE + ||'|'|| decode(tstatus,'READ ONLY', 'READONLY', tstatus) || '|' || free_blocks + ||'|'|| contents + from v\$database d , ( + select f.file_name, f.tablespace_name, f.status fstatus, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, + 'ONLINE' ONLINE_STATUS, t.BLOCK_SIZE, t.status tstatus, nvl(sum(fs.blocks),0) free_blocks, t.contents + from dba_data_files f, dba_tablespaces t, dba_free_space fs + where f.tablespace_name = t.tablespace_name + and f.file_id = fs.file_id(+) + group by f.file_name, f.tablespace_name, f.status, f.autoextensible, + f.blocks, f.maxblocks, f.user_blocks, f.increment_by, 'ONLINE', + t.block_size, t.status, t.contents + UNION + select f.file_name, f.tablespace_name, 'ONLINE' status, f.AUTOEXTENSIBLE, + f.blocks, f.maxblocks, f.USER_BLOCKS, f.INCREMENT_BY, 'TEMP', + t.BLOCK_SIZE, 'TEMP' status, sum(sh.blocks_free) free_blocks, 'TEMPORARY' + from v\$thread th, dba_temp_files f, dba_tablespaces t, v\$temp_space_header sh + WHERE f.tablespace_name = t.tablespace_name and f.file_id = sh.file_id + GROUP BY th.instance, f.file_name, f.tablespace_name, 'ONLINE', + f.autoextensible, f.blocks, f.maxblocks, f.user_blocks, f.increment_by, + 'TEMP', t.block_size, t.status); + " + fi +} + +sql_dataguard_stats() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "SELECT upper(d.NAME) + ||'|'|| upper(d.DB_UNIQUE_NAME) + ||'|'|| d.DATABASE_ROLE + ||'|'|| ds.name + ||'|'|| ds.value + FROM v\$database d + JOIN v\$parameter vp on 1=1 + left outer join V\$dataguard_stats ds on 1=1 + WHERE vp.name = 'log_archive_config' + AND vp.value is not null + ORDER BY 1; + " + fi +} + +sql_recovery_status() +{ + echo 'PROMPT <<>>' + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo "SELECT upper(d.NAME) + ||'|'|| d.DB_UNIQUE_NAME + ||'|'|| d.DATABASE_ROLE + ||'|'|| d.open_mode + ||'|'|| dh.file# + ||'|'|| round((dh.CHECKPOINT_TIME-to_date('01.01.1970','dd.mm.yyyy'))*24*60*60) + ||'|'|| round((sysdate-dh.CHECKPOINT_TIME)*24*60*60) + ||'|'|| dh.STATUS + ||'|'|| dh.RECOVER + ||'|'|| dh.FUZZY + ||'|'|| dh.CHECKPOINT_CHANGE# + FROM V\$datafile_header dh, v\$database d, v\$instance i + ORDER BY dh.file#; + " + elif [ "$AT_LEAST_ORACLE_92" = 'yes' ] ; then + echo "SELECT upper(d.NAME) + ||'|'|| d.NAME + ||'|'|| d.DATABASE_ROLE + ||'|'|| d.open_mode + ||'|'|| dh.file# + ||'|'|| round((dh.CHECKPOINT_TIME-to_date('01.01.1970','dd.mm.yyyy'))*24*60*60) + ||'|'|| round((sysdate-dh.CHECKPOINT_TIME)*24*60*60) + ||'|'|| dh.STATUS + ||'|'|| dh.RECOVER + ||'|'|| dh.FUZZY + ||'|'|| dh.CHECKPOINT_CHANGE# + FROM V\$datafile_header dh, v\$database d, v\$instance i + ORDER BY dh.file#; + " + fi +} + +sql_rman() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "SELECT upper(d.NAME) + ||'|'|| a.STATUS + ||'|'|| to_char(a.START_TIME, 'YYYY-mm-dd_HH24:MI:SS') + ||'|'|| to_char(a.END_TIME, 'YYYY-mm-dd_HH24:MI:SS') + ||'|'|| replace(b.INPUT_TYPE, ' ', '_') + ||'|'|| round(((sysdate - END_TIME) * 24 * 60),0) + FROM V\$RMAN_BACKUP_JOB_DETAILS a, v\$database d, + (SELECT input_type, max(command_id) as command_id + FROM V\$RMAN_BACKUP_JOB_DETAILS + WHERE START_TIME > sysdate-14 + and input_type != 'ARCHIVELOG' + and STATUS<>'RUNNING' GROUP BY input_type) b + WHERE a.COMMAND_ID = b.COMMAND_ID + UNION ALL + select name + || '|COMPLETED' + || '|'|| to_char(sysdate, 'YYYY-mm-dd_HH24:MI:SS') + || '|'|| to_char(completed, 'YYYY-mm-dd_HH24:MI:SS') + || '|ARCHIVELOG|' + || round((sysdate - completed)*24*60,0) + from ( + select d.name + , max(a.completion_time) completed + , case when a.backup_count > 0 then 1 else 0 end + from v\$archived_log a, v\$database d + where a.backup_count > 0 + and a.dest_id in + (select b.dest_id + from v\$archive_dest b + where b.target = 'PRIMARY' + and b.SCHEDULE = 'ACTIVE' + ) + group by d.name, case when a.backup_count > 0 then 1 else 0 end);" + fi +} + +sql_recovery_area() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "select upper(d.NAME) + ||' '|| round((SPACE_USED-SPACE_RECLAIMABLE)/ + (CASE NVL(SPACE_LIMIT,1) WHEN 0 THEN 1 ELSE SPACE_LIMIT END)*100) + ||' '|| round(SPACE_LIMIT/1024/1024) + ||' '|| round(SPACE_USED/1024/1024) + ||' '|| round(SPACE_RECLAIMABLE/1024/1024) + from V\$RECOVERY_FILE_DEST, v\$database d; + " + fi +} + +sql_undostat() +{ + echo 'PROMPT <<>>' + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo "select upper(i.INSTANCE_NAME) + ||'|'|| ACTIVEBLKS + ||'|'|| MAXCONCURRENCY + ||'|'|| TUNED_UNDORETENTION + ||'|'|| maxquerylen + ||'|'|| NOSPACEERRCNT + from v\$instance i, + (select * from (select * + from v\$undostat order by end_time desc + ) + where rownum = 1 + and TUNED_UNDORETENTION > 0 + ); + " + elif [ "$AT_LEAST_ORACLE_92" = 'yes' ] ; then + # TUNED_UNDORETENTION and ACTIVEBLKS are not availibe in Oracle <=9.2! + # we sent a -1 for filtering in check_undostat + echo "select upper(i.INSTANCE_NAME) + ||'|-1' + ||'|'|| MAXCONCURRENCY + ||'|-1' + ||'|'|| maxquerylen + ||'|'|| NOSPACEERRCNT + from v\$instance i, + (select * from (select * + from v\$undostat order by end_time desc + ) + where rownum = 1 + ); + " + fi +} + +sql_resumable() +{ + echo 'PROMPT <<>>' + echo "select upper(i.INSTANCE_NAME) + ||'|'|| u.username + ||'|'|| a.SESSION_ID + ||'|'|| a.status + ||'|'|| a.TIMEOUT + ||'|'|| round((sysdate-to_date(a.SUSPEND_TIME,'mm/dd/yy hh24:mi:ss'))*24*60*60) + ||'|'|| a.ERROR_NUMBER + ||'|'|| to_char(to_date(a.SUSPEND_TIME, 'mm/dd/yy hh24:mi:ss'),'mm/dd/yy_hh24:mi:ss') + ||'|'|| a.RESUME_TIME + ||'|'|| a.ERROR_MSG + from dba_resumable a, v\$instance i, dba_users u + where a.INSTANCE_ID = i.INSTANCE_NUMBER + and u.user_id = a.user_id + and a.SUSPEND_TIME is not null + union all + select upper(i.INSTANCE_NAME) + || '|||||||||' + from v\$instance i +; + " +} + +sql_jobs() +{ + if [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo 'PROMPT <<>>' + echo "SELECT upper(d.NAME) + ||'|'|| j.OWNER + ||'|'|| j.JOB_NAME + ||'|'|| j.STATE + ||'|'|| ROUND((TRUNC(sysdate) + j.LAST_RUN_DURATION - TRUNC(sysdate)) * 86400) + ||'|'|| j.RUN_COUNT + ||'|'|| j.ENABLED + ||'|'|| NVL(j.NEXT_RUN_DATE, to_date('1970-01-01', 'YYYY-mm-dd')) + ||'|'|| NVL(j.SCHEDULE_NAME, '-') + ||'|'|| d.STATUS + FROM dba_scheduler_jobs j, dba_scheduler_job_run_details d, v\$database d + WHERE d.owner=j.OWNER AND d.JOB_NAME=j.JOB_NAME + AND d.LOG_ID=(SELECT max(LOG_ID) FROM dba_scheduler_job_run_details dd + WHERE dd.owner=j.OWNER and dd.JOB_NAME=j.JOB_NAME + ); + " + fi +} + +sql_ts_quotas() +{ + echo 'PROMPT <<>>' + echo "select upper(d.NAME) + ||'|'|| Q.USERNAME + ||'|'|| Q.TABLESPACE_NAME + ||'|'|| Q.BYTES + ||'|'|| Q.MAX_BYTES + from dba_ts_quotas Q, v\$database d + where max_bytes > 0 + union all + select upper(d.NAME) + ||'|||' + from v\$database d + order by 1; + " +} + +sql_version() +{ + echo 'PROMPT <<>>' + echo "select upper(i.INSTANCE_NAME) + || ' ' || banner + from v\$version, v\$instance i + where banner like 'Oracle%';" +} + +sql_instance() +{ + echo 'prompt <<>>' + if [ ${ORACLE_SID:0:1} = '+' ] ; then + # ASM + echo "select upper(i.instance_name) + || '|' || i.VERSION + || '|' || i.STATUS + || '|' || i.LOGINS + || '|' || i.ARCHIVER + || '|' || round((sysdate - i.startup_time) * 24*60*60) + || '|' || '0' + || '|' || 'NO' + || '|' || 'ASM' + || '|' || 'NO' + || '|' || i.instance_name + from v\$instance i; + " + else + # normal Instance + echo "select upper(i.instance_name) + || '|' || i.VERSION + || '|' || i.STATUS + || '|' || i.LOGINS + || '|' || i.ARCHIVER + || '|' || round((sysdate - i.startup_time) * 24*60*60) + || '|' || DBID + || '|' || LOG_MODE + || '|' || DATABASE_ROLE + || '|' || FORCE_LOGGING + || '|' || d.name + from v\$instance i, v\$database d; + " + fi +} + +sql_sessions() +{ + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || ' ' || CURRENT_UTILIZATION + from v\$resource_limit, v\$instance i + where RESOURCE_NAME = 'sessions'; + " +} + +sql_processes() +{ + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || ' ' || CURRENT_UTILIZATION + || ' ' || ltrim(rtrim(LIMIT_VALUE)) + from v\$resource_limit, v\$instance i + where RESOURCE_NAME = 'processes'; + " +} + +sql_logswitches() +{ + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || ' ' || logswitches + from v\$instance i , + (select count(1) logswitches + from v\$loghist + where first_time > sysdate - 1/24 + ); + " +} + +sql_locks() +{ + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo 'prompt <<>>' + echo "SET SERVEROUTPUT ON feedback off +DECLARE + type x is table of varchar2(20000) index by pls_integer; + xx x; +begin + begin + execute immediate 'select upper(i.instance_name) + || ''|'' || a.sid + || ''|'' || b.serial# + || ''|'' || b.machine + || ''|'' || b.program + || ''|'' || b.process + || ''|'' || b.osuser + || ''|'' || a.ctime + || ''|'' || decode(c.owner,NULL,''NULL'',c.owner) + || ''|'' || decode(c.object_name,NULL,''NULL'',c.object_name) + from V\$LOCK a, v\$session b, dba_objects c, v\$instance i + where (a.id1, a.id2, a.type) + IN (SELECT id1, id2, type + FROM GV\$LOCK + WHERE request>0 + ) + and request=0 + and a.sid = b.sid + and a.id1 = c.object_id (+) + union all + select upper(i.instance_name) || ''|||||||||'' + from v\$instance i' + bulk collect into xx; + if xx.count >= 1 then + for i in 1 .. xx.count loop + dbms_output.put_line(xx(i)); + end loop; + end if; + exception + when others then + for cur1 in (select upper(i.instance_name) instance_name from v\$instance i) loop + dbms_output.put_line(cur1.instance_name || '|||||||||'||sqlerrm); + end loop; + end; +END; +/ +set serverout off +" + fi +} + +sql_longactivesessions() +{ + if [ "$AT_LEAST_ORACLE_101" = 'yes' ] ; then + echo 'prompt <<>>' + echo "select upper(i.instance_name) + || '|' || s.sid + || '|' || s.serial# + || '|' || s.machine + || '|' || s.process + || '|' || s.osuser + || '|' || s.program + || '|' || s.last_call_et + || '|' || s.sql_id + from v\$session s, v\$instance i + where s.status = 'ACTIVE' + and type != 'BACKGROUND' + and s.username is not null + and s.username not in('PUBLIC') + and s.last_call_et > 60*60 + union all + select upper(i.instance_name) + || '||||||||' + from v\$instance i; + " + fi +} + +sql_asm_diskgroup() +{ + echo 'prompt <<>>' + if [ "$AT_LEAST_ORACLE_112" = 'yes' ] ; then + echo "select STATE + || ' ' || TYPE + || ' ' || 'N' + || ' ' || sector_size + || ' ' || block_size + || ' ' || allocation_unit_size + || ' ' || total_mb + || ' ' || free_mb + || ' ' || required_mirror_free_mb + || ' ' || usable_file_mb + || ' ' || offline_disks + || ' ' || voting_files + || ' ' || name || '/' + from v\$asm_diskgroup; + " + elif [ "$AT_LEAST_ORACLE_102" = 'yes' ] ; then + echo "select STATE + || ' ' || TYPE + || ' ' || 'N' + || ' ' || sector_size + || ' ' || block_size + || ' ' || allocation_unit_size + || ' ' || total_mb + || ' ' || free_mb + || ' ' || required_mirror_free_mb + || ' ' || usable_file_mb + || ' ' || offline_disks + || ' ' || 'N' + || ' ' || name || '/' + from v\$asm_diskgroup; + " + fi +} + +# .--oraenv--------------------------------------------------------------. +# | | +# | ___ _ __ __ _ ___ _ ____ __ | +# | / _ \| '__/ _` |/ _ \ '_ \ \ / / | +# | | (_) | | | (_| | __/ | | \ V / | +# | \___/|_| \__,_|\___|_| |_|\_/ | +# | | +# +----------------------------------------------------------------------+ +# | Functions for getting the Oracle environment | +# '----------------------------------------------------------------------' + +function set_oraenv () { + ORACLE_SID=${1} + + test -f /etc/oratab && ORATAB=/etc/oratab + # /var/opt/oracle/oratab is needed for Oracle Solaris + test -f /var/opt/oracle/oratab && ORATAB=/var/opt/oracle/oratab + test -f ${ORATAB:-""} || echo "ORA-99999 oratab not found" + test -f ${ORATAB:-""} || exit 1 + + ORACLE_HOME=$(cat ${ORATAB} | grep "^"${ORACLE_SID}":" | cut -d":" -f2) + if [ -z $ORACLE_HOME ] ; then + # cut last number from SID for Oracle RAC to find entry in oratab + ORACLE_SID_SHORT=$(echo $ORACLE_SID | sed "s/[0-9]$//") + ORACLE_HOME=$(cat ${ORATAB} | grep "^"${ORACLE_SID_SHORT}":" | cut -d":" -f2) + fi + + if [ ! -d ${ORACLE_HOME:-"not_found"} ] ; then + echo "ORA-99999 ORACLE_HOME for ORACLE_SID="$ORACLE_SID" not found or not existing!" + exit 1 + fi + + TNS_ADMIN=${TNS_ADMIN:-$MK_CONFDIR} + + test -f ${TNS_ADMIN}/sqlnet.ora || ( echo "ORA-99998 Couldn't find "${TNS_ADMIN}/sqlnet.ora ; exit 1) + + export ORACLE_HOME TNS_ADMIN ORACLE_SID +} + +function get_oraversion () { + set_oraenv ${1} + ORACLE_VERSION=$($ORACLE_HOME/bin/sqlplus -V | grep ^SQL | cut -d" " -f3 | cut -d"." -f-2) + + # remove possible existing variables + unset AT_LEAST_ORACLE_121 AT_LEAST_ORACLE_112 AT_LEAST_ORACLE_111 AT_LEAST_ORACLE_102 AT_LEAST_ORACLE_101 AT_LEAST_ORACLE_92 + + if [ "$ORACLE_VERSION" = '12.1' ] ; then + AT_LEAST_ORACLE_121=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' ] ; then + AT_LEAST_ORACLE_112=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' ] ; then + AT_LEAST_ORACLE_111=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' -o "$ORACLE_VERSION" = '10.2' ] ; then + AT_LEAST_ORACLE_102=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' -o "$ORACLE_VERSION" = '10.2' \ + -o "$ORACLE_VERSION" = '10.1' ] ; then + AT_LEAST_ORACLE_101=yes + fi + + if [ "$ORACLE_VERSION" = '12.1' -o "$ORACLE_VERSION" = '11.2' \ + -o "$ORACLE_VERSION" = '11.1' -o "$ORACLE_VERSION" = '10.2' \ + -o "$ORACLE_VERSION" = '10.1' -o "$ORACLE_VERSION" = '9.2' ] ; then + AT_LEAST_ORACLE_92=yes + fi +} + +# +# .--Functions-----------------------------------------------------------. +# | _____ _ _ | +# | | ___| _ _ __ ___| |_(_) ___ _ __ ___ | +# | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \/ __| | +# | | _|| |_| | | | | (__| |_| | (_) | | | \__ \ | +# | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/ | +# | | +# +----------------------------------------------------------------------+ +# | Helper functions | +# '----------------------------------------------------------------------' + +function sqlplus_internal() { + loc_stdin=$(cat) + set_oraenv $SID + + # reload mk_oracle.cfg for run_cached. Otherwise some variables are missing + if [ -e "$MK_CONFDIR/mk_oracle.cfg" ] + then + . $MK_CONFDIR/mk_oracle.cfg + fi + + # mk_oracle_dbusers.conf is for compatibility. Do not use it anymore + ORACLE_USERCONF=${MK_CONFDIR}/mk_oracle_dbuser.conf + + TNSPINGOK=no + if [ -f ${TNS_ADMIN}/tnsnames.ora ] ; then + if "${ORACLE_HOME}"/bin/tnsping "${ORACLE_SID}" >/dev/null 2>&1 ; then + TNSALIAS=$ORACLE_SID + TNSPINGOK=yes + fi + fi + + ORADBUSER="" + DBPASSWORD="" + + # ASM use '+' as 1st character in SID! + if [ ${ORACLE_SID:0:1} = '+' ] ; then + ORACFGLINE=${ASMUSER} + else + # use an individuel user or the default DBUSER from mk_oracle.cfg + dummy="DBUSER_"${ORACLE_SID} + ORACFGLINE=${!dummy} + if [ "$ORACFGLINE" = '' ] ; then + ORACFGLINE=${DBUSER} + fi + fi + + if [ -f ${ORACLE_USERCONF} -a "${ORACFGLINE}" = '' ] ; then + # mk_oracle_dbuser.conf + ORACFGLINE=$(cat ${ORACLE_USERCONF} | grep "^"${ORACLE_SID}":") + # mk_oracle_dbuser has ORACLE_SID as 1. parameter. we need an offset for all values + offset=1 + else + # mk_oracle.cfg + offset=0 + fi + + ORADBUSER=$(echo ${ORACFGLINE} | cut -d":" -f$[1+offset]) + DBPASSWORD=$(echo ${ORACFGLINE} | cut -d":" -f$[2+offset]) + DBSYSCONNECT=$(echo ${ORACFGLINE} | cut -d":" -f$[3+offset]) + DBHOST=$(echo ${ORACFGLINE} | cut -d":" -f$[4+offset]) + DBPORT=$(echo ${ORACFGLINE} | cut -d":" -f$[5+offset]) + + if [ ! "${ORACFGLINE}" ] ; then + # no configuration found + # => use the wallet with tnsnames.ora or EZCONNECT + TNSALIAS=${TNSALIAS:-"localhost:1521/${ORACLE_SID}"} + else + if [ ${DBSYSCONNECT} ] ; then + assysdbaconnect=" as "${DBSYSCONNECT} + fi + TNSALIAS=${TNSALIAS:-"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=${DBHOST:-"localhost"})(PORT=${DBPORT:-1521}))(CONNECT_DATA=(SID=${ORACLE_SID})(SERVER=DEDICATED)(UR=A)))"} + + # ORADBUSER = '/'? => ignore DBPASSWORD and use the wallet + if [ "${ORADBUSER}" = '/' ] ; then + # connect with / and wallet + ORADBUSER="" + DBPASSWORD="" + if [ "$TNSPINGOK" = 'no' ] ; then + # create an EZCONNECT string when no tnsnames.ora is usable + # defaults to localhost:1521/ + TNSALIAS="${DBHOST:-"localhost"}:${DBPORT:-1521}/${ORACLE_SID}" + fi + fi + fi + + DBCONNECT="${ORADBUSER}/${DBPASSWORD}@${TNSALIAS}${assysdbaconnect}" + + SQLPLUS=${ORACLE_HOME}/bin/sqlplus + if [ ! -x ${SQLPLUS} ] ; then + echo "sqlplus not found or ORACLE_HOME wrong! " + echo "SQLPLUS="${SQLPLUS} + return 1 + fi + + echo "$loc_stdin" | ${SQLPLUS} -L -s ${DBCONNECT} + if [ $? -ne 0 ] ; then + if [ "$DEBUGCONNECT" ] ; then + echo "Logindetails: ${DBCONNECT}" >&2 + fi + return 1 + fi +} + +# Helper function that calls an SQL statement with a clean output +# Usage: echo "..." | sqlplus SID +function sqlplus () +{ + local SID=$1 + loc_stdin=$(cat) + + # use sqlplus_internal when no sqlplus.sh is found + SQLPLUS="$MK_CONFDIR"/sqlplus.sh + test -f "$SQLPLUS" || SQLPLUS=sqlplus_internal + + if OUTPUT=$({ echo 'set pages 0 trimspool on feedback off lines 8000' ; echo 'whenever sqlerror exit 1'; echo "$loc_stdin" ; } | "$SQLPLUS" $SID) + then + echo "$OUTPUT" + else + echo '<<>>' + local SID_UPPER=$(echo "$SID" | tr '[:lower:]' '[:upper:]') + echo "$OUTPUT" | grep -v "^ERROR at line" | tr '\n' ' ' | sed "s/^/$SID_UPPER|FAILURE|/" ; echo + return 1 + fi +} + +function remove_excluded_sections () +{ + local sections="$1" + local excluded="$2" + local result="" + for section in $sections + do + local skip= + for exclude in $excluded + do + if [ "$exclude" = "$section" ] ; then + local skip=yes + break + fi + done + if [ "$skip" != yes ] ; then + result="$result $section" + fi + done + echo "$result" +} + + +# Create one SQL statements for several sections and run +# these with sqlplus. The exitcode is preserved. +function do_sync_checks () +{ + local SID=$1 + local SECTIONS="$2" + for section in $SECTIONS + do + eval "sql_$section" + done | sqlplus $SID +} + +function do_async_checks () +{ + local SID=$1 + echo "$ASYNC_SQL" | sqlplus $SID +} + +# Make sure that the new shell that is being run by run_cached inherits +# our functions +export -f sqlplus +export -f sqlplus_internal +export -f do_async_checks +export -f set_oraenv + +function file_age() { + /usr/bin/perl -e 'if (! -f $ARGV[0]){die "0000000"};$mtime=(stat($ARGV[0]))[9];print ($^T-$mtime);' "$1" +} + +function run_cached_local () { + local section= + if [ "$1" = -s ] ; then local section="echo '<<<$2>>>' ; " ; shift ; fi + local NAME=$1 + local MAXAGE=$2 + shift 2 + local CMDLINE="$section$@" + + if [ ! -d $MK_VARDIR/cache ]; then mkdir -p $MK_VARDIR/cache ; fi + CACHEFILE="$MK_VARDIR/cache/$NAME.cache" + + # Check if the creation of the cache takes suspiciously long and return + # nothing if the age (access time) of $CACHEFILE.new is twice the MAXAGE + if [ -e "$CACHEFILE.new" ] ; then + AGE=$(file_age "$CACHEFILE.new") + if [ $AGE -ge $((MAXAGE * 2)) ] ; then + return + fi + fi + + # Check if cache file exists and is recent enough + if [ -s "$CACHEFILE" ] ; then + AGE=$(file_age "$CACHEFILE") + if [ $AGE -le $MAXAGE ] ; then local USE_CACHEFILE=1 ; fi + # Output the file in any case, even if it is + # outdated. The new file will not yet be available + cat "$CACHEFILE" + fi + + # Cache file outdated and new job not yet running? Start it + if [ -z "$USE_CACHEFILE" -a ! -e "$CACHEFILE.new" ] ; then + if [ "$DEBUG" ] ; then + echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | bash + else + echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup bash 2>/dev/null & + fi + fi +} + +#. +# .--Main----------------------------------------------------------------. +# | __ __ _ | +# | | \/ | __ _(_)_ __ | +# | | |\/| |/ _` | | '_ \ | +# | | | | | (_| | | | | | | +# | |_| |_|\__,_|_|_| |_| | +# | | +# +----------------------------------------------------------------------+ +# | Iterate over all instances and execute sync and async sections. | +# '----------------------------------------------------------------------' + +# Get list of all running databases +# Do not work on ASM in this plugin. => Ignore a running ASM-Instance! +SIDS=$(UNIX95=true ps -ef | awk '{print $NF}' | grep -E '^asm_pmon_|^ora_pmon_|^xe_pmon_XE' | cut -d"_" -f3-) + +# If we do not have found any running database instance, then either +# no ORACLE is present on this system or it's just currently not running. +# In the later case we ouput empty agent sections so that Check_MK will be +# happy and execute the actual check functions. +if [ -z "$SIDS" -a ! -e "$MK_CONFDIR/mk_oracle.found" ] ; then + exit +fi + +# From now on we expect databases on this system (for ever) +touch $MK_CONFDIR/mk_oracle.found + +# Make sure that always all sections are present, even +# in case of an error. Note: the section <<>> +# section shows the general state of a database instance. If +# that section fails for an instance then all other sections +# do not contain valid data anyway. +for section in $SYNC_SECTIONS $ASYNC_SECTIONS $SYNC_ASM_SECTIONS $ASYNC_ASM_SECTIONS +do + echo "<<>>" +done + +for SID in $SIDS +do + # We need the SID in uppercase at later time + SID_UPPER=$(echo $SID | tr '[:lower:]' '[:upper:]') + + # Check if SID is listed in ONLY_SIDS if this is used + if [ "$ONLY_SIDS" ] ; then + SKIP=yes + for S in $ONLY_SIDS ; do + if [ "$S" = "$SID" ] ; then + SKIP= + break + fi + done + if [ "$SKIP" ] ; then continue ; fi + fi + + # Handle explicit exclusion of instances + EXCLUDE=EXCLUDE_$SID + EXCLUDE=${!EXCLUDE} + # SID filtered totally? + if [ "$EXCLUDE" = "ALL" ]; then + continue + fi + + if [ ${SID:0:1} = '+' ] ; then + DO_ASYNC_SECTIONS=${ASYNC_ASM_SECTIONS} + DO_SYNC_SECTIONS=${SYNC_ASM_SECTIONS} + else + # switch sections to ASM + DO_SYNC_SECTIONS=${SYNC_SECTIONS} + DO_ASYNC_SECTIONS=${ASYNC_SECTIONS} + fi + + get_oraversion $SID + + # Do sync checks + EXCLUDED=$(eval 'echo $EXCLUDE'"_$SID") + SECTIONS=$(remove_excluded_sections "$DO_SYNC_SECTIONS" "$EXCLUDED") + + # Do async checks + ASECTIONS=$(remove_excluded_sections "$DO_ASYNC_SECTIONS" "$EXCLUDED") + ASYNC_SQL=$(for section in $ASECTIONS ; do eval "sql_$section" ; done) + export ASYNC_SQL + + if [ "$DEBUGCONNECT" ] ; then + echo "-----------------------------------------------" + echo "Logincheck to Instance: "$SID" Version: "$ORACLE_VERSION + echo "select 'Login ok User: ' || user || ' on ' || host_name + from v\$instance;" | sqlplus $SID + echo "SYNC_SECTIONS=$SECTIONS" + echo "ASYNC_SECTIONS=$ASECTIONS" + # do not execute any check + continue + fi + + do_sync_checks $SID "$SECTIONS" + + run_cached_local oracle_$SID $CACHE_MAXAGE do_async_checks $SID + +done diff --git a/files/plugins/mk_oracle.solaris b/files/plugins/mk_oracle.solaris new file mode 100755 index 0000000..868b862 --- /dev/null +++ b/files/plugins/mk_oracle.solaris @@ -0,0 +1,200 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Check_MK agent plugin for monitoring ORACLE databases + +# This plugin is a port of the linux agent plugin. It has been +# tested with solaris 10. + +# Get list of all running databases +SIDS=$(UNIX95=true ps -ef -o args | sed -n '/^ora_pmon_/p;/^xe_pmon_/p' | sed -n '/^[a-z]*_pmon_\([^ ]*\)/s//\1/p') +if [ -z "$SIDS" ] ; then + # If on this system we've already found a database + if [ -e "$MK_VARDIR/mk_oracle.found" ] ; then + echo '<<>>' + echo '<<>>' + echo '<<>>' + echo '<<>>' + fi + exit 0 +fi + +touch $MK_VARDIR/mk_oracle.found + +# Recreate data if cachefile is older than 120 seconds. +# If you set this to 0, then the cache file will be created +# as often as possible. If the database queries last longer +# then your check interval, caching will be active nevertheless. +CACHE_MAXAGE=120 + +# Source the optional configuration file for this agent plugin +if [ -e "$MK_CONFDIR/mk_oracle.cfg" ] +then + . $MK_CONFDIR/mk_oracle.cfg +fi + +# You can specify a list of SIDs to monitor. Those databases will +# only be handled, if they are found running, though! +# +# ONLY_SIDS="XE HIRN SEPP" +# +# It is possible to filter SIDS negatively. Just add the following to +# the mk_oracle.cfg file: +# +# EXCLUDE_="ALL" +# +# Another option is to filter single checks for SIDS. Just add +# lines as follows to the mk_oracle.cfg file. One service per +# line: +# +# EXCLUDE_="" +# +# For example skip oracle_sessions and oracle_logswitches checks +# for the instance "mysid". +# +# EXCLUDE_mysid="sessions logswitches" +# +# +# This check uses a cache file to prevent problems with long running +# SQL queries. It starts building a cache when +# a) no cache is present or the cache is too old and +# b) the cache is not currently being built +# The cache is used for $CACHE_MAXAGE seconds. The CACHE_MAXAGE +# option is pre-set to 120 seconds but can be changed in mk_oracle.cfg. + +function sqlplus () +{ + if OUTPUT=$({ echo 'set pages 0' ; echo 'whenever sqlerror exit 1'; echo 'set lines 8000' ; echo 'set feedback off'; cat ; } | $MK_CONFDIR/sqlplus.sh $1) + then + echo "${OUTPUT}" | sed -e 's/[[:space:]]\+/ /g' -e '/^[[:space:]]*$/d' -e "s/^/$1 /" + else + echo "${OUTPUT}" | sed "s/^/$1 FAILURE /" + fi +} + + +for SID in $SIDS; do + # Check if SID is listed in ONLY_SIDS if this is used + if [ "$ONLY_SIDS" ] ; then + SKIP=yes + for S in $ONLY_SIDS ; do + if [ "$S" = "$SID" ] ; then + SKIP= + break + fi + done + if [ "$SKIP" ] ; then continue ; fi + fi + + EXCLUDE=EXCLUDE_$SID + EXCLUDE=${!EXCLUDE} + # SID filtered totally? + if [ "$EXCLUDE" = "ALL" ]; then + continue + fi + + # Do Version-Check (use as a general login check) without caching + if [ "$EXCLUDE" = "${EXCLUDE/version/}" ]; then + echo '<<>>' + echo "select banner from v\$version where banner like 'Oracle%';" | sqlplus "$SID" + fi + + CACHE_FILE=$MK_VARDIR/oracle_$SID.cache + + # Check if file exists and recent enough + CACHE_FILE_UPTODATE= + if [ -s $CACHE_FILE ]; then + NOW=$(perl -le "print time()") + + MTIME=$(perl -MPOSIX -le 'print mktime(localtime((lstat($ARGV[0]))[9]))' $CACHE_FILE) + if [ $(($NOW - $MTIME)) -le $CACHE_MAXAGE ]; then + CACHE_FILE_UPTODATE=1 + fi + fi + + # If the cache file exists, output it, regardless of its age. If it's outdated + # then it will be recreated *asynchronously*. It's new contents will not + # be available here anyway. + if [ -s "$CACHE_FILE" ] ; then cat "$CACHE_FILE" ; fi + + # When the cache file is not valid, we recreated it, but only if there is not + # yet a background process from a previous check still doing this! We see this + # because of the existance of the .new file + # When the cache is old and there is no *new file present, then start a query + # to update the information for this instance. + if [ -z "$CACHE_FILE_UPTODATE" -a ! -e "$CACHE_FILE.new" ] + then + nohup bash -c " + set -o noclobber + function sqlplus () + { + if OUTPUT=\$({ echo 'set pages 0' ; echo 'whenever sqlerror exit 1'; echo 'set lines 8000' ; echo 'set feedback off'; cat ; } | $MK_CONFDIR/sqlplus.sh \$1) + then + echo \"\${OUTPUT}\" | sed -e 's/[[:space:]]\+/ /g' -e '/^[[:space:]]*$/d' -e \"s/^/\$1 /\" + else + echo \"\${OUTPUT}\" | sed \"s/^/\$1 FAILURE /\" + fi + } + + { + # Only execute checks when not filtered + if [ '$EXCLUDE' = '${EXCLUDE/sessions/}' ]; then + echo '<<>>' + echo \"select count(1) from v\\\$session where status = 'ACTIVE';\" | sqlplus \"$SID\" + fi + + if [ '$EXCLUDE' = '${EXCLUDE/logswitches/}' ]; then + echo '<<>>' + echo \"select count(1) from v\\\$loghist where first_time > sysdate - 1/24;\" | sqlplus \"$SID\" + fi + + if [ '$EXCLUDE' = '${EXCLUDE/tablespaces/}' ]; then + echo '<<>>' + sqlplus "$SID" < $CACHE_FILE.new && mv $CACHE_FILE.new $CACHE_FILE || rm -f $CACHE_FILE* + " + fi +done diff --git a/files/plugins/mk_oracle_asm b/files/plugins/mk_oracle_asm index 1b02bd5..3f370e9 100755 --- a/files/plugins/mk_oracle_asm +++ b/files/plugins/mk_oracle_asm @@ -6,7 +6,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2010 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. diff --git a/files/plugins/mk_oracle_crs b/files/plugins/mk_oracle_crs new file mode 100755 index 0000000..5bf2da2 --- /dev/null +++ b/files/plugins/mk_oracle_crs @@ -0,0 +1,127 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Developed by Thorsten Bruhns from OPITZ CONSULTING Deutschland GmbH + +set -f + +ocrcfgfile=/etc/oracle/ocr.loc +olrcfgfile=/etc/oracle/olr.loc +resourcefilter="^NAME=|^TYPE=|^STATE=|^TARGET=|^ENABLED=" + +# .--Functions-----------------------------------------------------------. +# | _____ _ _ | +# | | ___| _ _ __ ___| |_(_) ___ _ __ ___ | +# | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \/ __| | +# | | _|| |_| | | | | (__| |_| | (_) | | | \__ \ | +# | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/ | +# | | +# +----------------------------------------------------------------------+ +# | | +# '----------------------------------------------------------------------' + +function set_has_env(){ + test -f ${ocrcfgfile} || exit 0 + local_has_type=$(cat $ocrcfgfile | grep "^local_only=" | cut -d"=" -f2 | tr '[:lower:]' '[:upper:]') + local_has_type=${local_has_type:-"FALSE"} + + if [ -f ${olrcfgfile} ] ; then + has_ORACLE_HOME=$(cat $olrcfgfile | grep "^crs_home=" | cut -d"=" -f2) + else + # There is no olr.cfg in 10.2 and 11.1 + # we try to get the ORA_CRS_HOME from /etc/init.d/init.cssd + local_has_type=FALSE + INITCSSD=/etc/init.d/init.cssd + if [ ! -f ${INITCSSD} ] ; then + exit 0 + else + has_ORACLE_HOME=$(grep "^ORA_CRS_HOME=" ${INITCSSD} | cut -d"=" -f2-) + fi + fi + + CRSCTL=${has_ORACLE_HOME}/bin/crsctl + OLSNODES=${has_ORACLE_HOME}/bin/olsnodes + CRS_STAT=${has_ORACLE_HOME}/bin/crs_stat +} + +function printhasdata() { + ps -e | grep cssd.bin > /dev/null || exit 0 + + echo "<<>>" + $CRSCTL query has releaseversion + + echo "<<>>" + $CRSCTL stat res -f | grep -E $resourcefilter +} + +function printcrsdata() { + ps -e | grep -e ohasd.bin -e crsd.bin > /dev/null || exit 0 + + echo "<<>>" + crs_version=$($CRSCTL query crs releaseversion) + crs_version_short=$(echo $crs_version | cut -d"[" -f2- | cut -d"." -f-2) + echo $crs_version + + echo "<<>>" + $CRSCTL query css votedisk | grep "^ [0-9]" + + ps -e | grep crsd.bin > /dev/null || exit 0 + echo "<<>>" + OLS_NODENAME=$($OLSNODES -l) + + echo "nodename|"$OLS_NODENAME + + if [ $crs_version_short = '11.2' ] ; then + $CRSCTL stat res -v -n $OLS_NODENAME -init | grep -E $resourcefilter | sed "s/^/csslocal\|/" + for nodelist in $($OLSNODES) + do + $CRSCTL stat res -v -n $nodelist | grep -E $resourcefilter | sed "s/^/$nodelist\|/" + done + else + $CRS_STAT -f -c $OLS_NODENAME | grep -E $resourcefilter | sed "s/^/$OLS_NODENAME\|/" + fi +} + +# .--Main----------------------------------------------------------------. +# | __ __ _ | +# | | \/ | __ _(_)_ __ | +# | | |\/| |/ _` | | '_ \ | +# | | | | | (_| | | | | | | +# | |_| |_|\__,_|_|_| |_| | +# | | +# +----------------------------------------------------------------------+ +# | | +# '----------------------------------------------------------------------' + +set_has_env +echo "<<>>" +echo "<<>>" +echo "<<>>" +if [ $local_has_type = 'FALSE' ] ; then + printcrsdata +else + printhasdata +fi + diff --git a/files/plugins/mk_postgres b/files/plugins/mk_postgres index dc92a20..8333eee 100755 --- a/files/plugins/mk_postgres +++ b/files/plugins/mk_postgres @@ -1,4 +1,27 @@ #!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. # Try to detect the postgres user if id pgsql >/dev/null 2>&1; then @@ -11,11 +34,11 @@ fi echo '<<>>' # Postgres 9.2 uses 'query' instead of 'current_query' -for name in query current_query -do - OUTPUT="$(echo "select $name = '', count(*) from pg_stat_activity group by ($name = '');" |\ - su - $USER -c "psql --variable ON_ERROR_STOP=1 -d postgres -A -t -F' '" 2>/dev/null)" && break -done +QNAME="$(echo "select column_name from information_schema.columns where table_name='pg_stat_activity' and column_name in ('query','current_query');" |\ + su - $USER -c "psql -d postgres -t -A -F';'")" +OUTPUT="$(echo "select $QNAME = '', count(*) from pg_stat_activity group by ($QNAME = '');" |\ + su - $USER -c "psql --variable ON_ERROR_STOP=1 -d postgres -A -t -F' '" 2>/dev/null)" + echo "$OUTPUT" # line with number of idle sessions is sometimes missing on Postgre 8.x. This can lead # to an altogether empty section and thus the check disappearing. diff --git a/files/plugins/mk_sap b/files/plugins/mk_sap index c762daf..7303dac 100755 --- a/files/plugins/mk_sap +++ b/files/plugins/mk_sap @@ -1,5 +1,5 @@ #!/usr/bin/python -# encoding: utf-8 +# -*- encoding: utf-8; py-indent-offset: 4 -*- # +------------------------------------------------------------------+ # | ____ _ _ __ __ _ __ | # | / ___| |__ ___ ___| | __ | \/ | |/ / | @@ -7,7 +7,7 @@ # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | -# | Copyright Mathias Kettner 2013 mk@mathias-kettner.de | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. @@ -23,7 +23,7 @@ # License along with GNU Make; see the file COPYING. If not, write # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA. -# + # This agent plugin has been built to collect information from SAP R/3 systems # using RFC calls. It needs the python module sapnwrfc (available in Check_MK # git at agents/sap/sapnwrfc) and the nwrfcsdk (can be downloaded from SAP @@ -38,7 +38,7 @@ # # During development the "CCMS_Doku.pdf" was really helpful. -import os, sys +import os, sys, fcntl import time, datetime # sapnwrfc needs to know where the libs are located. During @@ -56,6 +56,9 @@ except ImportError, e: '"/usr/sap/nwrfcsdk/lib" and run "ldconfig" afterwards.\n' ) sys.exit(1) + elif 'No module named sapnwrfc' in str(e): + sys.stderr.write("Missing the Python module sapnwfrc.\n") + sys.exit(1) else: raise @@ -105,12 +108,16 @@ SKIP_MTCLASSES = [ MTE_LONG_TXT, ] -STATE_FILE = '/etc/check_mk/sap.state' +MK_CONFDIR = os.getenv("MK_CONFDIR") or "/etc/check_mk" +MK_VARDIR = os.getenv("MK_VARDIR") or "/var/lib/check_mk_agent" + +STATE_FILE = MK_VARDIR + '/sap.state' +state_file_changed = False # ############################################################################# # Settings to be used to connect to the SAP R/3 host. -cfg = { +local_cfg = { 'ashost': 'localhost', 'sysnr': '00', 'client': '100', @@ -136,10 +143,15 @@ monitor_paths = [ 'SAP CCMS Monitor Templates/Dialog Overview/*', ] monitor_types = [] +config_file = MK_CONFDIR + '/sap.cfg' -config_file = os.getenv('MK_CONFDIR', '/etc/check_mk') + '/sap.cfg' +cfg = {} if os.path.exists(config_file): execfile(config_file) + if type(cfg) == dict: + cfg = [ cfg ] +else: + cfg = [ local_cfg ] # Load the state file into memory try: @@ -147,6 +159,10 @@ try: except IOError: states = {} +# index of all logfiles which have been found in a run. This is used to +# remove logfiles which are not available anymore from the states dict. +logfiles = [] + # ############################################################################# # @@ -212,7 +228,7 @@ def logout(): 'INTERFACE': 'XAL', }) -def mon_list(): +def mon_list(cfg): f = query("BAPI_SYSTEM_MON_GETLIST", { 'EXTERNAL_USER_NAME': cfg['user'], }) @@ -221,16 +237,16 @@ def mon_list(): l.append((mon["MS_NAME"].rstrip(), mon["MONI_NAME"].rstrip())) return l -def ms_list(): - f = query("BAPI_SYSTEM_MS_GETLIST", { - 'EXTERNAL_USER_NAME': cfg['user'], - }) - l = [] - for ms in f.MONITOR_SETS.value: - l.append(ms['NAME'].rstrip()) - return l +#def ms_list( cfg ): +# f = query("BAPI_SYSTEM_MS_GETLIST", { +# 'EXTERNAL_USER_NAME': cfg['user'], +# }) +# l = [] +# for ms in f.MONITOR_SETS.value: +# l.append(ms['NAME'].rstrip()) +# return l -def mon_tree(ms_name, mon_name): +def mon_tree(cfg, ms_name, mon_name): f = query("BAPI_SYSTEM_MON_GETTREE", { 'EXTERNAL_USER_NAME': cfg['user'], 'MONITOR_NAME': {"MS_NAME": ms_name, "MONI_NAME": mon_name}, @@ -251,7 +267,7 @@ def tid(node): 'EXTINDEX': node['EXTINDEX'].strip(), } -def mon_perfdata(node): +def mon_perfdata(cfg, node): f = query('BAPI_SYSTEM_MTE_GETPERFCURVAL', { 'EXTERNAL_USER_NAME': cfg['user'], 'TID': tid(node), @@ -262,11 +278,13 @@ def mon_perfdata(node): 'EXTERNAL_USER_NAME': cfg['user'], 'TID': tid(node), }) + if f.PROPERTIES.value['DECIMALS'] != 0: + value = (value + 0.0) / 10**f.PROPERTIES.value['DECIMALS'] uom = f.PROPERTIES.value['VALUNIT'].strip() return value, uom -def mon_msg(node): +def mon_msg(cfg, node): f = query('BAPI_SYSTEM_MTE_GETSMVALUE', { 'EXTERNAL_USER_NAME': cfg['user'], 'TID': tid(node), @@ -281,9 +299,9 @@ def parse_dt(d, t): if not d or not t: return None else: - return datetime.datetime(*time.strptime(d + t, '%Y%m%d%H%M%S')[:6]) + return datetime.datetime(*time.strptime(d + t, '%Y%m%d%H%M%S')[:6]) -def mon_alerts(node): +def mon_alerts(cfg, node): f = query('BAPI_SYSTEM_MTE_GETALERTS', { 'EXTERNAL_USER_NAME': cfg['user'], 'TID': tid(node), @@ -300,7 +318,7 @@ def aid(alert): "ALERTTIME": alert["ALERTTIME"], } -def alert_details(alert): +def alert_details(cfg, alert): f = query('BAPI_SYSTEM_ALERT_GETDETAILS', { 'EXTERNAL_USER_NAME': cfg['user'], 'AID': aid(alert), @@ -310,8 +328,9 @@ def alert_details(alert): msg = f.XMI_EXT_MSG.value['MSG'].strip() return state, msg -def process_alerts(ms_name, mon_name, node, alerts): - global logs +def process_alerts(cfg, logs, ms_name, mon_name, node, alerts): + global state_file_changed + sid = node["MTSYSID"].strip() or 'Other' context = node["MTMCNAME"].strip() or 'Other' path = node["PATH"] @@ -320,6 +339,8 @@ def process_alerts(ms_name, mon_name, node, alerts): hostname = sid logfile = context + "/" + path + logfiles.append((hostname, logfile)) + logs.setdefault(sid, {}) logs[hostname][logfile] = [] newest_log_dt = None @@ -332,7 +353,7 @@ def process_alerts(ms_name, mon_name, node, alerts): if not newest_log_dt or dt > newest_log_dt: newest_log_dt = dt # store the newest log of this run - alert_state, alert_msg = alert_details(alert) + alert_state, alert_msg = alert_details(cfg, alert) # Format lines to "logwatch" format logs[hostname][logfile].append('%s %s %s' % (STATE_LOGWATCH_MAP[alert_state['VALUE']], dt.strftime("%Y-%m-%d %H:%M:%S"), alert_msg)) @@ -340,104 +361,139 @@ def process_alerts(ms_name, mon_name, node, alerts): if newest_log_dt: # Write newest log age to cache to prevent double processing of logs states[(hostname, logfile)] = newest_log_dt - file(STATE_FILE, 'w').write(repr(states)) + state_file_changed = True + return logs -try: - conn = sapnwrfc.base.rfc_connect(cfg) -except sapnwrfc.RFCCommunicationError, e: - sys.stderr.write('ERROR: Unable to connect (%s)\n' % e) - sys.exit(1) -#print "connection attributes: ", conn.connection_attributes() -login() - -logs = {} -sap_data = {} +def check(cfg): + global conn + conn = sapnwrfc.base.rfc_connect(cfg) + login() -# This loop is used to collect all information from SAP -for ms_name, mon_name in mon_list(): - path = ms_name + SEPARATOR + mon_name - if not to_be_monitored(path, True): - continue + logs = {} + sap_data = {} - tree = mon_tree(ms_name, mon_name) - for node in tree: - if not to_be_monitored(node['PATH']): + # This loop is used to collect all information from SAP + for ms_name, mon_name in mon_list(cfg): + path = ms_name + SEPARATOR + mon_name + if not to_be_monitored(path, True): continue - #print node["PATH"] - - status_details = '' - perfvalue = '-' - uom = '-' - - # Use precalculated states - state = { - 'VALUE': node['ACTUALVAL'], - 'SEVERITY': node['ACTUALSEV'], - } - - if state['VALUE'] not in STATE_VALUE_MAP: - print 'UNHANDLED STATE VALUE' - sys.exit(1) - - # - # Handle different object classes individually - # to get details about them - # - - if monitor_types and node['MTCLASS'] not in monitor_types: - continue # Skip unwanted classes if class filtering is enabled - - if node['MTCLASS'] == MTE_PERFORMANCE: - perfvalue, this_uom = mon_perfdata(node) - uom = this_uom and this_uom or uom - - elif node['MTCLASS'] == MTE_SINGLE_MSG: - status_details = "%s: %s" % mon_msg(node) - - elif node['MTCLASS'] == MTE_MSG_CONTAINER: - alerts = mon_alerts(node) - process_alerts(ms_name, mon_name, node, alerts) - if len(alerts) > 0: - last_alert = alerts[-1] - dt = parse_dt(last_alert["ALERTDATE"], last_alert["ALERTTIME"]) - alert_state, alert_msg = alert_details(last_alert) - last_msg = '%s: %s - %s' % (dt, STATE_VALUE_MAP[alert_state['VALUE']][1], alert_msg) - - status_details = '%d Messages, Last: %s' % (len(alerts), last_msg) - else: - status_details = 'The log is empty' - - elif node['MTCLASS'] not in SKIP_MTCLASSES: - # Add an error to output on unhandled classes - status_details = "UNHANDLED MTCLASS", node['MTCLASS'] - - if node['MTCLASS'] not in SKIP_MTCLASSES: - sid = node["MTSYSID"].strip() or 'Other' - context = node["MTMCNAME"].strip() or 'Other' - path = node["PATH"] - - sap_data.setdefault(sid, []) - sap_data[sid].append("%s\t%d\t%3d\t%s\t%s\t%s\t%s" % (context, state['VALUE'], - state['SEVERITY'], path, perfvalue, uom, status_details)) - - -for host, host_sap in sap_data.items(): - sys.stdout.write('<<<<%s>>>>\n' % host) - sys.stdout.write('<<>>\n') - print '\n'.join(host_sap) -sys.stdout.write('<<<<>>>>\n') - -for host, host_logs in logs.items(): - sys.stdout.write('<<<<%s>>>>\n' % host) - sys.stdout.write('<<>>\n') - for log, lines in host_logs.items(): - sys.stdout.write('[[[%s]]]\n' % log) - if lines: - sys.stdout.write('\n'.join(lines) + '\n') + + tree = mon_tree(cfg, ms_name, mon_name) + for node in tree: + if not to_be_monitored(node['PATH']): + continue + #print node["PATH"] + + status_details = '' + perfvalue = '-' + uom = '-' + + # Use precalculated states + state = { + 'VALUE': node['ACTUALVAL'], + 'SEVERITY': node['ACTUALSEV'], + } + + if state['VALUE'] not in STATE_VALUE_MAP: + print 'UNHANDLED STATE VALUE' + sys.exit(1) + + # + # Handle different object classes individually + # to get details about them + # + + if monitor_types and node['MTCLASS'] not in monitor_types: + continue # Skip unwanted classes if class filtering is enabled + + if node['MTCLASS'] == MTE_PERFORMANCE: + perfvalue, this_uom = mon_perfdata(cfg, node) + uom = this_uom and this_uom or uom + + elif node['MTCLASS'] == MTE_SINGLE_MSG: + status_details = "%s: %s" % mon_msg(cfg, node) + + elif node['MTCLASS'] == MTE_MSG_CONTAINER: + + alerts = mon_alerts(cfg, node) + logs = process_alerts(cfg, logs, ms_name, mon_name, node, alerts) + if len(alerts) > 0: + last_alert = alerts[-1] + dt = parse_dt(last_alert["ALERTDATE"], last_alert["ALERTTIME"]) + alert_state, alert_msg = alert_details(cfg, last_alert) + last_msg = '%s: %s - %s' % (dt, STATE_VALUE_MAP[alert_state['VALUE']][1], alert_msg) + + status_details = '%d Messages, Last: %s' % (len(alerts), last_msg) + else: + status_details = 'The log is empty' + + elif node['MTCLASS'] not in SKIP_MTCLASSES: + # Add an error to output on unhandled classes + status_details = "UNHANDLED MTCLASS", node['MTCLASS'] + + if node['MTCLASS'] not in SKIP_MTCLASSES: + sid = node["MTSYSID"].strip() or 'Other' + context = node["MTMCNAME"].strip() or 'Other' + path = node["PATH"] + + sap_data.setdefault(sid, []) + sap_data[sid].append("%s\t%d\t%3d\t%s\t%s\t%s\t%s" % (context, state['VALUE'], + state['SEVERITY'], path, perfvalue, uom, status_details)) + + + for host, host_sap in sap_data.items(): + sys.stdout.write('<<<<%s>>>>\n' % host) + sys.stdout.write('<<>>\n') + print '\n'.join(host_sap) sys.stdout.write('<<<<>>>>\n') -logout() -conn.close() + for host, host_logs in logs.items(): + sys.stdout.write('<<<<%s>>>>\n' % host) + sys.stdout.write('<<>>\n') + for log, lines in host_logs.items(): + sys.stdout.write('[[[%s]]]\n' % log) + if lines: + sys.stdout.write('\n'.join(lines) + '\n') + sys.stdout.write('<<<<>>>>\n') + + logout() + conn.close() + +# It is possible to configure multiple SAP instances to monitor. Loop them all, but +# do not terminate when one connection failed +processed_all = True +try: + for entry in cfg: + try: + check(entry) + except sapnwrfc.RFCCommunicationError, e: + sys.stderr.write('ERROR: Unable to connect (%s)\n' % e) + processed_all = False + except Exception, e: + sys.stderr.write('ERROR: Unhandled exception (%s)\n' % e) + processed_all = False + + # Now check whether or not an old logfile needs to be removed. This can only + # be done this way, when all hosts have been reached. Otherwise the cleanup + # is skipped. + if processed_all: + for key in states.keys(): + if key not in logfiles: + state_file_changed = True + del states[key] + + # Only write the state file once per run. And only when it has been changed + if state_file_changed: + new_file = STATE_FILE + '.new' + fd = os.open(new_file, os.O_WRONLY | os.O_CREAT) + fcntl.flock(fd, fcntl.LOCK_EX) + os.write(fd, repr(states)) + os.close(fd) + os.rename(STATE_FILE+'.new', STATE_FILE) + +except Exception, e: + sys.stderr.write('ERROR: Unhandled exception (%s)\n' % e) + sys.exit(0) diff --git a/files/plugins/mk_tsm b/files/plugins/mk_tsm index 89e8d87..f22fc72 100755 --- a/files/plugins/mk_tsm +++ b/files/plugins/mk_tsm @@ -1,4 +1,27 @@ #!/usr/bin/ksh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. # Agent for Linux/UNIX for Tivoli Storage Manager (TSM) @@ -20,7 +43,7 @@ fi do_tsm_checks () { - INST=${DSMSERV_DIR##*/} + INST=${DSMSERV_DIR##*/} # If we have no instance name, we take 'default' if [ -z "$INST" ] ; then INST=default ; fi @@ -44,11 +67,11 @@ EOF $dsmcmd < /dev/null ; then if grep -q '^VERSION = 10' < /etc/SuSE-release then ZYPPER='waitmax 10 zypper --no-gpg-checks --non-interactive --terse' - $ZYPPER refresh > /dev/null - { $ZYPPER pchk || [ $? = 100 -o $? = 101 ] && $ZYPPER lu ; } \ - | egrep '(patches needed|\|)' | egrep -v '^(#|Repository |Catalog )' + REFRESH=`$ZYPPER refresh 2>&1` + if [ "$REFRESH" ] + then + echo "ERROR: $REFRESH" + else + { $ZYPPER pchk || [ $? = 100 -o $? = 101 ] && $ZYPPER lu ; } \ + | egrep '(patches needed|\|)' | egrep -v '^(#|Repository |Catalog )' + fi else ZYPPER='waitmax 10 zypper --no-gpg-checks --non-interactive --quiet' - $ZYPPER refresh > /dev/null - { { $ZYPPER pchk || [ $? = 100 -o $? = 101 ] && $ZYPPER lp ; } ; $ZYPPER ll ; } \ - | egrep '(patches needed|\|)' | egrep -v '^(#|Repository)' + REFRESH=`$ZYPPER refresh 2>&1` + if [ "$REFRESH" ] + then + echo "ERROR: $REFRESH" + else + { { $ZYPPER pchk || [ $? = 100 -o $? = 101 ] && $ZYPPER lp ; } ; $ZYPPER ll ; } \ + | egrep '(patches needed|\|)' | egrep -v '^(#|Repository)' + fi fi fi diff --git a/files/plugins/netstat.aix b/files/plugins/netstat.aix new file mode 100755 index 0000000..1dd59e6 --- /dev/null +++ b/files/plugins/netstat.aix @@ -0,0 +1,31 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# This is not part of the standard agent since it can produce much +# output data of the table is large. This plugin is just needed for +# checking if certain known TCP connections are established. + +echo '<<>>' +netstat -n -f inet | fgrep -v '*.*' | egrep '^(tcp|udp)' diff --git a/files/plugins/netstat.linux b/files/plugins/netstat.linux new file mode 100755 index 0000000..a80cbbe --- /dev/null +++ b/files/plugins/netstat.linux @@ -0,0 +1,31 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# This is not part of the standard agent since it can take very +# long to run if your TCP/UDP table is large. Netstat seems to +# have an execution time complexity of at least O(n^2) on Linux. + +echo '<<>>' +netstat -ntu | egrep '^(tcp|udp)' diff --git a/files/plugins/nfsexports b/files/plugins/nfsexports index 39ba2bc..168f5c2 100755 --- a/files/plugins/nfsexports +++ b/files/plugins/nfsexports @@ -1,18 +1,38 @@ -#!/bin/sh +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. # this check will only run if we have a working nfs environment or SHOULD have one. # not tested for nfs3 # verify if there are exports defined in your local /etc/exports -if [ -r /etc/exports ]; then +if [ -r /etc/exports ]; then EXPORTS=$(grep -v -e ^# -e ^$ /etc/exports) fi -pgrep '(portmap|rpcbind)' >/dev/null && pgrep rpc.mountd >/dev/null && DAEMONS="ok" -# any exports or have running daemons? then look for registered exports -if [[ $EXPORTS ]]; then +if [ "$EXPORTS" ] && pgrep '(portmap|rpcbind)' >/dev/null && pgrep rpc.mountd >/dev/null +then echo "<<>>" - if [[ $DAEMONS ]]; then - waitmax 3 showmount --no-headers -e - fi + waitmax 3 showmount --no-headers -e fi diff --git a/files/plugins/nfsexports.solaris b/files/plugins/nfsexports.solaris new file mode 100755 index 0000000..c172d2a --- /dev/null +++ b/files/plugins/nfsexports.solaris @@ -0,0 +1,57 @@ +#!/usr/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Check_MK agent plugin for monitoring nfsexports on Solaris. This plugin +# has been tested with solaris 10 in a standalone and cluster setting. + +clusterconfigdir="/etc/cluster/ccr/global/directory" +if [ -r $clusterconfigdir ]; then + # is a clustered nfs server + nfsconfig=/etc/cluster/ccr/global/`grep rgm $clusterconfigdir | grep nfs | grep rg_` + if [ -r $nsconfig ]; then + Pathprefix=`grep Pathprefix $nfsconfig | awk {'print $2'}`/SUNW.nfs + dfstabfile=$Pathprefix/dfstab.`grep -v FilesystemMountPoints $nfsconfig | grep SUNW.nfs | \ + awk {'print $1'} | sed -e 's/RS_//'` + if [ -r $dfstabfile ]; then + EXPORTS=`grep -v ^# $dfstabfile | grep -v ^$` + ps -aef | grep nfsd | grep $Pathprefix >/dev/null && DAEMONS="ok" + fi + fi +else + # is a standalone nfs server + dfstabfile="/etc/dfs/dfstab" + if [ -r $dfstabfile ]; then + EXPORTS=`grep -v ^# $dfstabfile | grep -v ^$` + svcs -a | grep nfs/server | grep ^online >/dev/null && DAEMONS="ok" + fi +fi + +# any exports or have running daemons? then look for registered exports +if [ "$EXPORTS" ]; then + echo "<<>>" + if [ "$DAEMONS" ]; then + showmount -e | grep ^/ + fi +fi diff --git a/files/plugins/nginx_status b/files/plugins/nginx_status new file mode 100755 index 0000000..fe0ec00 --- /dev/null +++ b/files/plugins/nginx_status @@ -0,0 +1,146 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Check_MK-Agent-Plugin - Nginx Server Status +# +# Fetches the stub nginx_status page from detected or configured nginx +# processes to gather status information about this process. +# +# Take a look at the check man page for details on how to configure this +# plugin and check. +# +# By default this plugin tries to detect all locally running processes +# and to monitor them. If this is not good for your environment you might +# create an nginx_status.cfg file in MK_CONFDIR and populate the servers +# list to prevent executing the detection mechanism. + +import os, sys, urllib2, re + +# tell urllib2 not to honour "http(s)_proxy" env variables +urllib2.getproxies = lambda: {} + +config_dir = os.getenv("MK_CONFDIR", "/etc/check_mk") +config_file = config_dir + "/nginx_status.cfg" + +# None or list of (proto, ipaddress, port) tuples. +# proto is 'http' or 'https' +servers = None +ssl_ports = [ 443, ] + +if os.path.exists(config_file): + execfile(config_file) + +def try_detect_servers(): + pids = [] + results = [] + for line in os.popen('netstat -tlnp 2>/dev/null').readlines(): + parts = line.split() + # Skip lines with wrong format + if len(parts) < 7 or '/' not in parts[6]: + continue + + pid, proc = parts[6].split('/', 1) + to_replace = re.compile('^.*/') + proc = to_replace.sub('', proc) + + procs = [ 'nginx', 'nginx:' ] + # the pid/proc field length is limited to 19 chars. Thus in case of + # long PIDs, the process names are stripped of by that length. + # Workaround this problem here + procs = [ p[:19 - len(pid) - 1] for p in procs ] + + # Skip unwanted processes + if proc not in procs: + continue + + # Add only the first found port of a single server process + if pid in pids: + continue + pids.append(pid) + + proto = 'http' + address, port = parts[3].rsplit(':', 1) + port = int(port) + + # Use localhost when listening globally + if address == '0.0.0.0': + address = '127.0.0.1' + elif address == '::': + address = '::1' + + # Switch protocol if port is SSL port. In case you use SSL on another + # port you would have to change/extend the ssl_port list + if port in ssl_ports: + proto = 'https' + + results.append((proto, address, port)) + + return results + +if servers is None: + servers = try_detect_servers() + +if not servers: + sys.exit(0) + +print '<<>>' +for server in servers: + if isinstance(server, tuple): + proto, address, port = server + page = 'nginx_status' + else: + proto = server['protocol'] + address = server['address'] + port = server['port'] + page = server.get('page', 'nginx_status') + + try: + url = '%s://%s:%s/%s' % (proto, address, port, page) + # Try to fetch the status page for each server + try: + request = urllib2.Request(url, headers={"Accept" : "text/plain"}) + fd = urllib2.urlopen(request) + except urllib2.URLError, e: + if 'SSL23_GET_SERVER_HELLO:unknown protocol' in str(e): + # HACK: workaround misconfigurations where port 443 is used for + # serving non ssl secured http + url = 'http://%s:%s/%s' % (address, port, page) + fd = urllib2.urlopen(url) + else: + raise + + for line in fd.read().split('\n'): + if not line.strip(): + continue + if line.lstrip()[0] == '<': + # seems to be html output. Skip this server. + break + print address, port, line + except urllib2.HTTPError, e: + sys.stderr.write('HTTP-Error (%s:%d): %s %s\n' % (address, port, e.code, e)) + + except Exception, e: + sys.stderr.write('Exception (%s:%d): %s\n' % (address, port, e)) diff --git a/files/plugins/plesk_backups b/files/plugins/plesk_backups index 6a1964d..b589624 100755 --- a/files/plugins/plesk_backups +++ b/files/plugins/plesk_backups @@ -1,26 +1,38 @@ #!/usr/bin/python -# encoding: utf-8 +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ # +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + # Monitors FTP backup spaces of plesk domains. # Data format # # <<>> # -# Cache the result for 1 hour by default -cache_seconds = 60 * 60 -# The cache file to use -cache_file = '/tmp/plesk_backups.cache' - import MySQLdb, sys, datetime, time, os from ftplib import FTP -# use the cache? -if os.path.exists(cache_file) \ - and os.stat(cache_file).st_mtime > time.time() - cache_seconds: - print file(cache_file).read() - sys.exit(0) - def connect(): try: return MySQLdb.connect( @@ -46,7 +58,7 @@ def get_domains(): 'WHERE id = %d AND type = \'domain\'' % domain_id) params = dict(cursor2.fetchall()) domains[domain] = params - + cursor2.close() cursor.close() return domains @@ -126,12 +138,11 @@ for domain, p in domains.iteritems(): size += int(l.split()[-5]) return size total_size = get_size('') - + output.append('%s 0 %s %d %d' % (domain, last_backup[1].strftime('%s'), last_backup[2], total_size)) - + except Exception, e: output.append('%s 2 %s' % (domain, e)) # Write cache and output -file(cache_file, 'w').write('\n'.join(output)) print '\n'.join(output) diff --git a/files/plugins/plesk_domains b/files/plugins/plesk_domains index 00ead9b..ff4ad06 100755 --- a/files/plugins/plesk_domains +++ b/files/plugins/plesk_domains @@ -1,6 +1,29 @@ #!/usr/bin/python -# encoding: utf-8 +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ # +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + # Lists all domains configured in plesk # # <<>> diff --git a/files/plugins/resolve_hostname b/files/plugins/resolve_hostname deleted file mode 100755 index 2d2da36..0000000 --- a/files/plugins/resolve_hostname +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# This check can be used to test the name resolution of a given host -# address using the local resolver of the system this script is -# running on. - -HOSTADDRESS=mathias-kettner.de - -OUTPUT=$(nslookup $HOSTADDRESS 2>&1) -RC=$? -if [ $RC -ne 0 ]; then - STATE=2 - OUTPUT="CRIT - $HOSTADDRESS could not be resolved" -else - STATE=0 - ADDRESSES=$(echo "$OUTPUT" | tail -n+3 | grep Address: | cut -d" " -f2) - OUTPUT="OK - $HOSTADDRESS resolved to ${ADDRESSES//$'\n'/, }" -fi - -echo "<<>>" -echo "Resolve_$HOSTADDRESS $STATE $OUTPUT" diff --git a/files/plugins/runas b/files/plugins/runas new file mode 100755 index 0000000..f40e307 --- /dev/null +++ b/files/plugins/runas @@ -0,0 +1,84 @@ +#!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# This plugin allows to execute mrpe, local and plugin skripts with a different user context +# It is configured with in the file $MK_CONFDIR/runas.cfg +# +# Syntax: +# [Script type] [User context] [File / Directory] +# +# Example configuration +# # Execute mrpe commands in given files under specific user +# # A '-' means no user context switch +# mrpe ab /home/ab/mrpe_commands.cfg +# mrpe lm /home/lm/mrpe_commands.cfg +# mrpe - /root/mrpe/extra_commands.cfg +# +# Excecute -executable- files in the target directories under specific user context +# plugin ab /var/ab/plugins +# local ab /var/ab/local +# + +grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/runas.cfg" | \ +while read type user include +do + if [ -d $include -o \( "$type" == "mrpe" -a -f $include \) ] ; then + PREFIX="" + if [ "$user" != "-" ] ; then + PREFIX="su $user -c " + fi + + # mrpe includes + if [ "$type" == "mrpe" ] ; then + echo "<<>>" + grep -Ev '^[[:space:]]*($|#)' "$include" | \ + while read descr cmdline + do + PLUGIN=${cmdline%% *} + if [ -n "$PREFIX" ] ; then + cmdline="$PREFIX\"$cmdline\"" + fi + OUTPUT=$(eval "$cmdline") + echo -n "(${PLUGIN##*/}) $descr $? $OUTPUT" | tr \\n \\1 + echo + done + # local and plugin includes + elif [ "$type" == "local" -o "$type" == "plugin" ] ; then + if [ "$type" == "local" ] ; then + echo "<<>>" + fi + find $include -executable -type f | \ + while read filename + do + if [ -n "$PREFIX" ] ; then + cmdline="$PREFIX\"$filename\"" + else + cmdline=$filename + fi + $cmdline + done + fi + fi +done diff --git a/files/plugins/smart b/files/plugins/smart index 1a0b8f5..1a0f250 100755 --- a/files/plugins/smart +++ b/files/plugins/smart @@ -1,4 +1,72 @@ #!/bin/bash +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + + + + +# This will be called on LSI based raidcontrollers and accesses +# the SMART data of SATA disks attached to a SAS Raid HBA via +# SCSI protocol interface. +megaraid_info() +{ + + PDINFO=$(MegaCli -PDlist -a0) + + echo "$PDINFO" | \ + while read line ; do + case "$line" in + # FIRST LINE + "Enclosure Device ID"*) #Enclosure Device ID: 252 + ENC=$( echo "$line" | awk '{print $4}') + unset SLOT LOG_DEV_ID VEND MODEL + ;; + "Slot Number"*) #Slot Number: 7 + SLOT=$( echo "$line" | awk '{print $3}') + ;; + # Identify the logical device ID. smartctl needs it to access the disk. + "Device Id"*) #Device Id: 19 + LOG_DEV_ID=$( echo "$line" | awk '{print $3}') + ;; + "PD Type"*) #PD Type: SATA + VEND=$( echo "$line" | awk '{print $3}') + ;; + # This is the last value, generate output here + "Inquiry Data"*) + #Inquiry Data: WD-WCC1T1035197WDC WD20EZRX-00DC0B0 80.00A80 + # $4 seems to be better for some vendors... wont be possible to get this perfect. + MODEL=$( echo "$line" | awk '{print $3}') + + # /dev/sdc ATA SAMSUNG_SSD_830 5 Reallocated_Sector_Ct 0x0033 100 100 010 Pre-fail Always - + smartctl -d megaraid,${LOG_DEV_ID} -v 9,raw48 -A /dev/sg0 | \ + grep Always | egrep -v '^190(.*)Temperature(.*)' | \ + sed "s|^|Enc${ENC}/Slot${SLOT} $VEND $MODEL |" + ;; + esac + done +} + # Only handle always updated values, add device path and vendor/model if which smartctl > /dev/null 2>&1 ; then @@ -9,7 +77,7 @@ if which smartctl > /dev/null 2>&1 ; then if which tw_cli > /dev/null 2>&1 ; then # support for only one controller at the moment TWAC=$(tw_cli show | awk 'NR < 4 { next } { print $1 }' | head -n 1) - + # - add a trailing zero to handle case of unused slot # trailing zeros are part of the device links in /dev/disk/by-id/... anyway # - only the last 9 chars seem to be relevant @@ -80,7 +148,14 @@ if which smartctl > /dev/null 2>&1 ; then else CMD="smartctl -d ata -v 9,raw48 -A $D" fi - + [ -n "$CMD" ] && $CMD | grep Always | egrep -v '^190(.*)Temperature(.*)' | sed "s|^|$DNAME $VEND $MODEL |" done 2>/dev/null + + + # Call MegaRaid submodule if conditions are met + if which MegaCli > /dev/null && [ -c /dev/sg0 ] ; then + megaraid_info + fi fi + diff --git a/files/plugins/symantec_av b/files/plugins/symantec_av new file mode 100755 index 0000000..3d1faf2 --- /dev/null +++ b/files/plugins/symantec_av @@ -0,0 +1,38 @@ +#!/bin/sh +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +if [ -f /opt/Symantec/symantec_antivirus/sav ] +then + echo "<<>>" + /opt/Symantec/symantec_antivirus/sav info -d + + echo "<<>>" + /opt/Symantec/symantec_antivirus/sav info -a + + echo "<<>>" + /opt/Symantec/symantec_antivirus/sav quarantine -l +fi + diff --git a/files/plugins/unitrends_backup b/files/plugins/unitrends_backup new file mode 100755 index 0000000..b4398a3 --- /dev/null +++ b/files/plugins/unitrends_backup @@ -0,0 +1,88 @@ +#!/usr/bin/pnp +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +>>\n"; +$conn = "port=5432 dbname=bpdb user=postgres"; +$db = pg_connect($conn); + +$query = "SELECT + schedule_id, a.type AS app_type + FROM + bp.schedules AS s + JOIN + bp.application_lookup AS a USING(app_id) + WHERE + enabled=true AND email_report=true + ORDER BY s.name"; +$res = pg_query($db, $query); + +$start = time() - (24 * 3600); +$in = array("start_time" => $start); +bp_bypass_cookie(3, 'schedule_report'); + +while ($obj = pg_fetch_object($res)) { + if ($obj->app_type == "Archive") + continue; + + $in["schedule_id"] = (int)$obj->schedule_id; + $ret = bp_get_schedule_history($in); + if (empty($ret[0]["backups"])) + continue; + + print "HEADER|". + $ret[0]["schedule_name"]."|" . + $ret[0]["application_name"]."|". + $ret[0]["schedule_description"]."|". + $ret[0]["failures"]."\n"; + + foreach($ret[0]["backups"] as $trash => $backup) { + foreach($backup as $row) { + + $name = $row["primary_name"]; + switch($ret[0]["app_type"]){ + case "SQL Server": + $name .= "/".$row["secondary_name"]; + break; + + case "VMware": + $name .= ", VM ".$row["secondary_name"]; + break; + } + + $backup_type = $row["type"]; + + if (!isset($name)) + $name = $backup_tyoe; + + $backup_no = (isset($row["backup_id"])) ? $row["backup_id"] : "N/A" ; + + print "$name|$backup_no|$backup_type|".$row['description']."\n"; + } + } +} +pg_free_result($res); +bp_destroy_cookie(); +?> diff --git a/files/plugins/unitrends_replication b/files/plugins/unitrends_replication new file mode 100755 index 0000000..8d3ffa4 --- /dev/null +++ b/files/plugins/unitrends_replication @@ -0,0 +1,49 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +import sys, time, urllib +from xml.dom import minidom +now = int(time.time()) +start = now - 24 * 60 * 60 +end = now +dpu = 1 + +url = "http://localhost/recoveryconsole/bpl/syncstatus.php?type=replicate&arguments=start:%s,end:%s&sid=%s&auth=1:" % ( start, end, dpu ) +xml = urllib.urlopen(url) + +print "<<>>" +dom = minidom.parse(xml) +for item in dom.getElementsByTagName('SecureSyncStatus'): + application = item.getElementsByTagName('Application') + if application: + application = application[0].attributes['Name'].value + else: + application = "N/A" + result = item.getElementsByTagName('Result')[0].firstChild.data + completed = item.getElementsByTagName('Complete')[0].firstChild.data + targetname = item.getElementsByTagName('TargetName')[0].firstChild.data + instancename = item.getElementsByTagName('InstanceName')[0].firstChild.data + print "%s|%s|%s|%s|%s" % (application, result, completed, targetname, instancename) diff --git a/files/plugins/veritas/vxvm_enclosures b/files/plugins/veritas/vxvm_enclosures deleted file mode 100755 index dbef723..0000000 --- a/files/plugins/veritas/vxvm_enclosures +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# Original Output -#ENCLR_NAME ENCLR_TYPE ENCLR_SNO STATUS ARRAY_TYPE LUN_COUNT -#=================================================================================== -#disk Disk DISKS CONNECTED Disk 2 -#emc1 EMC 0002XXXXXXXX CONNECTED A/A 512 -#emc_clariion0 EMC_CLARiiON CK2000XXXXXXXX CONNECTED CLR-A/P 1 - -# Disk: local disks, or maybe JBOD (then remove the -e ^disk) - -if type vxdmpadm > /dev/null ; then - echo '<<>>' - vxdmpadm listenclosure all | grep -v -w -e ^[dD]isk -e ^other_disks -e ^ENCLR_NAME -e \^= -fi diff --git a/files/plugins/veritas/vxvm_multipath b/files/plugins/veritas/vxvm_multipath deleted file mode 100755 index 250586d..0000000 --- a/files/plugins/veritas/vxvm_multipath +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# DMPNODENAME ENCLR-NAME STATE[A] PATH-TYPE[M] -# disk2057 emc1 ENABLED(A) - -# disk3119 emc_clariion0 ENABLED SECONDARY - - -if type vxdmpadm >/dev/null 2>&1 ; then - echo '<<>>' - ENCS=$( vxdmpadm listenclosure all | grep -v -w -e ^[dD]isk -e ENCLR_NAME -e \^= | awk '{print $1}') - - echo "$ENCS" | while read enc ; do - vxdmpadm getdmpnode enclosure=$enc | grep -v -e \^= -e NAME - done -fi diff --git a/files/plugins/veritas/vxvm_objstatus b/files/plugins/veritas/vxvm_objstatus deleted file mode 100755 index 4ea69da..0000000 --- a/files/plugins/veritas/vxvm_objstatus +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - - -if type vxdg > /dev/null; then - echo '<<>>' - # Get a list of the in-use disk groups. - DGS=$(vxdg list | grep enabled | awk '{print $1}') - # Deported or otherwise inactive needs no performance monitoring - if [ "X${DGS}" != "X" ]; then - for DG in $DGS ; do - vxprint -g $DG -v -q -Q -F "%type %dgname %name %admin_state %kstate" - done - fi -fi - - - -# Output examples: -# A stopped volume -#v datadg lalavol CLEAN DISABLED -# An active volume -#v datadg oravol ACTIVE ENABLE -# v2 layered volumes on lower level that we might or might not need. -#v datadg oravol-L01 ACTIVE ENABLED -#v datadg oravol-L02 ACTIVE ENABLED - - -# Man page - -# https://sort.symantec.com/public/documents/sfha/5.1sp1/solaris/manualpages/html/man/volume_manager/html/man4/vxmake.4.html diff --git a/files/plugins/vxvm b/files/plugins/vxvm new file mode 100755 index 0000000..fa7f142 --- /dev/null +++ b/files/plugins/vxvm @@ -0,0 +1,50 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# This plugin has been tested on Linux and HPUX. + + +if type vxdmpadm >/dev/null 2>&1; then + echo '<<>>' + vxdmpadm listenclosure all | grep -v -w -e ^[dD]isk -e ^other_disks -e ^ENCLR_NAME -e \^= + echo '<<>>' + ENCS=$( vxdmpadm listenclosure all | grep -v -w -e ^[dD]isk -e ENCLR_NAME -e \^= | awk '{print $1}') + + echo "$ENCS" | while read enc ; do + vxdmpadm getdmpnode enclosure=$enc | grep -v -e \^= -e NAME + done +fi + +if type vxdg >/dev/null 2>&1; then + echo '<<>>' + # Get a list of the in-use disk groups. + DGS=$(vxdg list | grep enabled | awk '{print $1}') + # Deported or otherwise inactive needs no performance monitoring + if [ "X${DGS}" != "X" ]; then + for DG in $DGS ; do + vxprint -g $DG -v -q -Q -F "%type %dgname %name %admin_state %kstate" + done + fi +fi diff --git a/files/plugins/websphere_mq b/files/plugins/websphere_mq new file mode 100755 index 0000000..158737a --- /dev/null +++ b/files/plugins/websphere_mq @@ -0,0 +1,62 @@ +#!/bin/sh +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# ails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# plugin for websphere_mq_* checks + +if [ "$1" = "" ] +then + su - mqm -c "/usr/lib/check_mk_agent/plugins/websphere_mq run" +else + # Loop over all local mq instances + for QM in $( ps -ef | grep -i '[/]usr/mqm/bin/runmqchl -c' | awk '{ print $NF }' | uniq) + do + echo '<<>>' + for i in `echo " display CHANNEL (*) TYPE (SDR) " | /usr/bin/runmqsc $QM | grep CHLTYPE | grep -v SYSTEM | awk '{print $1}'` + do + j=`echo "display $i " | /usr/bin/runmqsc $QM | grep XMITQ | tr " " "\n" | grep XMITQ | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }'` + a=`echo " display qlocal ($j) CURDEPTH " | /usr/bin/runmqsc $QM | grep CURDEPTH | tr " " "\n" | grep CURDEPTH | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }' | tr "\n" " "` + c=`echo " display qlocal ($j) MAXDEPTH " | /usr/bin/runmqsc $QM | grep MAXDEPTH | tr " " "\n" | grep MAXDEPTH | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }' | tr "\n" " "` + + l=`echo $i | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }'` + s=`echo " display chstatus($l)" | /usr/bin/runmqsc $QM | grep STATUS | tail -1 | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $NF }'` + + if [ "$s" = "" ] + then + s="Unknown" + fi + echo "$a $i $c $s" + done + echo '<<>>' + for t in `echo " display queue (*) where (USAGE EQ NORMAL) " | /usr/bin/runmqsc $QM | grep QLOCAL | grep -v SYSTEM | grep -v _T0 | grep -v _T1 | grep -v _T2 | grep -v _T3 | grep -v mqtest | grep QUEUE | awk '{ print $1 }' | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }'` + do + a=`echo " display queue ($t) CURDEPTH " | /usr/bin/runmqsc $QM | grep CURDEPTH | tail -1 | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }'` + b=`echo " display qlocal ($t) MAXDEPTH " | /usr/bin/runmqsc $QM | grep MAXDEPTH | tr " " "\n" | grep MAXDEPTH | sed '1,$s/(/ /g' | sed '1,$s/)/ /g'| awk '{print $2 }' | tr "\n" " "` + + # Muster: Anzahl eingehender Messages $a auf $t Max-Queues $b + + echo "$a $t $b" + done + done +fi diff --git a/tasks/main.yml b/tasks/main.yml index 6e811af..42bbd77 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -4,14 +4,17 @@ apt: name=xinit state=present when: not check_mk_agent_over_ssh -- name: Download check_mk agent deb package - get_url: url=https://mathias-kettner.de/download/{{ check_mk_agent_deb_package }} dest=/root/{{ check_mk_agent_deb_package }} validate_certs=no +#- name: Download check_mk agent deb package +# get_url: url=https://mathias-kettner.de/download/{{ check_mk_agent_deb_package }} dest=/root/{{ check_mk_agent_deb_package }} validate_certs=no + +- name: Copy check_mk agent deb package + copy: src={{ check_mk_agent_deb_package }} dest=/root/check_mk_agent.deb - name: Install deb package - apt: deb=/root/{{ check_mk_agent_deb_package }} + apt: deb=/root/check_mk_agent.deb - name: Setup SSH key - authorized_key: user=root key_options='command="/usr/bin/check_mk_agent"' key="{{ lookup('file', check_mk_agent_pubkey_file) }}" + authorized_key: user=root key_options='command="/usr/bin/check_mk_agent",no-pty,no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-user-rc' key="{{ lookup('file', check_mk_agent_pubkey_file) }}" when: check_mk_agent_over_ssh and check_mk_agent_pubkey_file - name: Install plugin requierments