diff --git a/docs/20_Checks/inc_pluginfunctions.md b/docs/20_Checks/inc_pluginfunctions.md index 65d951ca676db0fb6a1b3996d92365ae68709d18..325f857646c05deab6eef73c1d39b12c5382506f 100644 --- a/docs/20_Checks/inc_pluginfunctions.md +++ b/docs/20_Checks/inc_pluginfunctions.md @@ -4,7 +4,9 @@ All scripts start with sourcing a shared bash file -``. `dirname $0`/inc_pluginfunctions`` +```shell +. $( dirname $0 )/inc_pluginfunctions +``` In that script are several functions starting with prefix **ph.** (=plugin helper) @@ -12,40 +14,191 @@ In that script are several functions starting with prefix **ph.** (=plugin helpe This is a list in alphabetic order -**ph.abort** [TEXT] +### ph.abort Shows error message and exit with status unknown. -**ph.exit** +Syntax: + +```text +ph.abort [TEXT] +``` + +Parameters: + +1. TEXT {string} The text message to show -Use at the end to send performance data and exit plugin with set statuscode +Example: -**ph.getFileAge** [FILE] +```shell +if ! data=$( sudo /bin/ceph df 2>&1 ) +then + echo "$data" + ph.abort "UNKNOWN: ceph is not available or no sudo permissions to execute ceph commands." +fi +``` + +### ph.execIfReady + +Execute a command and repeat max. MAXTRIES times if it fails. + +Syntax: + +```text +ph.execIfReady [FUNCTION] [ [WAITTIME] [MAXTRIES] ] +``` + +Parameters: + +1. FUNCTION {string} - command line to execute +2. WAITTIME {integer} - optional: sleeptime in sec before repeating again; default: 5 +3. MAXTRIES {integer} - optional: max number of tries; default: 3 + +Example: + +```shell +ph.execIfReady "timedatectl show >$tmpfile; grep '^NTPSynchronized' $tmpfile >/dev/null" + +cat $tmpfile | grep "^NTPSynchronized" >/dev/null +if [ $? -ne 0 ]; then + ph.setStatus "unknown" + ph.status "timesync: timedatectl has no line NTP synchronized" + cat $tmpfile +else + cat $tmpfile | grep "^NTPSynchronized=yes" >/dev/null + if [ $? -eq 0 ]; then + ph.status "timesync: a timesync service is active on this ${myos} host" + else + ph.setStatus "critical" + ph.status "timesync: there is no active timesync - you need to activate ntpd or timesyncd on this ${myos} host" + fi +fi +# /timedatectl +``` + +### ph.exit + +Use at the end to send performance data and exit plugin with set statuscode. + +This is the last line of your check script. + +Syntax: + +```text +ph.exit +``` + +(no parameters) + +### ph.getFileAge get age of a given file in sec -**ph.getOS** +The file must be reachable by the monitoring user. + +Syntax: + +```text +ph.getFileAge [FILE] +``` + +Parameters: + +1. FILE {string} - filename + +### ph.getOS get operating system as lowercase - centos/ debian/ ubuntu ... -**ph.getOSMajor** +Syntax: + +```text +ph.getOS +``` + +(no parameters) + +Example: + +```shell +$ bash -c ". inc_pluginfunctions; ph.getOS" +manjaro +``` + +In a script: + +```shell +distro=$( ph.getOS ) + +case $distro in + + "centos"|"almalinux") + # ... do something + ;; + + "debian"|"ubuntu") + # ... do something + ;; + + *) + ph.abort "UNKNOWN: distro [$distro] was detected but is not supported (yet)." + ;; +esac +``` + +### ph.getOSMajor get OS Major version as integer, i.e. 7 on a CentOS7 -**ph.getValueWithParam** VALUE PARAMNAME "$@" +Syntax: + +```text +ph.getOSMajor +``` + +(no parameters) + +### ph.getValueWithParam + +Return default value or its override from command line. -return default value or its override from command line. +Syntax: + +```text +ph.getFileAge VALUE PARAMNAME "$@" +``` + +Parameters: + +1. VALUE {integer} - the default value if the parameter (2nd param) was not set in the command line +2. PARAMNAME {char} - a single letter for the parameter to search +3. PARAM LIST {string} - list of all parameters to check; use "$@" set all current params from command line Example: -``typeset -i iWarnLimit=`ph.getValueWithParam 75 w "$@"` `` +```shell +# set default / override from command line params +typeset -i iWarnLimit=$( ph.getValueWithParam 75 w "$@") +typeset -i iCriticalLimit=$( ph.getValueWithParam 90 c "$@") +``` This will set variable iWarnLimit based on CLI parameter -w [value] ... if it does not exist it gets the default 75. -**ph.hasParamoption** PARAMNAME "$@" +### ph.hasParamoption check if a letter was used as command line option and return as 0 (=no) or 1 (=yes) +Syntax: + +```text +ph.hasParamoption PARAMNAME "$@" +``` + +Parameters: + +1. PARAMNAME{char} - a single letter for the parameter to search +2. PARAM LIST{string} - list of all parameters to check; use "$@" set all current params from command line + Example: ```bash @@ -57,39 +210,74 @@ if [ $bOptHelp -eq 1 -o $# -lt 1 ]; then fi ``` -**ph.setStatus** [STATUS] -Set a status with keyword ok, warning, critical, unknown -You can override it as often you want during the script. Based on the last setting the ph.exit function will set the exitcode. +### ph.perfadd + +Add performance data. Their output will be written with ```ph.exit```. So you are free to add perfomance data anywhere within your check script. + +Syntax: -**ph.setStatusByLimit** VALUE WARNLIMIT CRITLIMIT +```txt +ph.perfadd LABEL VALUE [ WARNLEVEL CRITICAL [ MIN MAX ] ] +``` -set statuscode by verifying integer(!) value with crtical and warning limit +Parameters: + +1. LABEL {string} - a label for the performance value; it must be unique for your script; The given value will be cleaned to lowercase; other chars than a-z, 0-9, minus will be deleted. +2. VALUE {integer|float} - your value; default (if missing): 0 +3. WARNLEVEL {integer} - optional: warning level; not handled by graphite; default: empty string +4. CRITICAL {integer} - optional: critical level; not handled by graphite; default: empty string +5. MIN {integer} - optional: minimum value of graph; default: empty string +6. MAX {integer} - optional: maximum value of graph;; default: empty string Example: -``ph.setStatusByLimit $ramUsage $iWarnLimit $iCriticalLimit`` +Add values with label and value only: -**ph.status** [TEXT] +```shell +data2=$( echo "$netdata" | sort | uniq -c ) -Show status as Text. +iEst=$( echo "$data2" | grep ESTABLISHED | awk '{ print $1 }' ) +iListen=$( echo "$data2" | grep LISTEN | awk '{ print $1 }' ) +iWait=$( echo "$data2" | grep TIME_WAIT | awk '{ print $1 }' ) -**ph.execIfReady** [FUNCTION] [ [WAITTIME] [MAXTRIES] ] +ph.perfadd "established" "$iEst" +ph.perfadd "listen" "$iListen" +ph.perfadd "time-wait" "$iWait" -Execute a command and repeat max. MAXTRIES times if it fails. +ph.exit +``` -**ph.perfadd** [VALUE] [OPTIONS…] +Add values and define limits for the graph: I will draw it from 0 to a fixed maximum value like for a given physical maximum or 100 for percent values. -Add performance data. Their output will be written with ph.exit. So you are free to add perfomance data anywhere within your check script. +Remark that here are empty values for warning and critical to skip them. -**ph.perfdeltaspeed** [VARNAME] [VALUE] [[unit] [isfloat]] +```shell +ph.perfadd "memory-total" "${ramTotal}MB" "" "" 0 ${ramTotal} +ph.perfadd "memory-used" "${ramUsed}MB" "" "" 0 ${ramTotal} +ph.perfadd "memory-avail" "${ramAvail}MB" "" "" 0 ${ramTotal} -For increasing system counters: get changerate per second since last check. +ph.exit +``` -Unit value can be +### ph.perfdeltaspeed -* s or sec - for seconds -* m or min - for minutes +For increasing system counters: get changerate per second or per minute since last check. + +Syntax: + +```text +ph.perfdeltaspeed VARNAME VALUE [ UNIT [isfloat] ] +``` + +Parameters: + +1. VARNAME {string} - an identifier for the value. It is needed to store the last given value and read it on next request. +2. VALUE {integer} - your counter value +3. UNIT {string} - optional: set a unit value can be + * "s" or "sec" - for seconds (default) + * "m" or "min" - for minutes +4. isfloat {string} - optional: flag to return a float value; set a non empty string for true. Example: @@ -98,14 +286,180 @@ Example: iSpeedRead=` ph.perfdeltaspeed "netio-${myinterface}-rx" $iRead` ``` -**ph.perfshow** +### ph.perfshow dump performance data (if u are not using ph.exit) -**ph.require** [PROG [...PROG_N]] +Syntax: + +```text +ph.perfshow +``` + +(no parameters) + +### ph.require check if a binary PROG exists in search path (=are installed) - if not then execution stops with showing a warning message and status unknown (using ph.abort). +Syntax: + +```text +ph.require [PROG [...PROG_N]] +``` + +Parameters: + +1. PROG - name of program to find in path + Example: `ph.require bc lsblk` + +Hint: +Do not place the requirement check before processing -h to show a help. The help should be visible in any case. + +### ph.setStatus + +Set a return status of your check with a keyword. This is easier to handle and to read than fiddling with Nagios exitcodes. You can override it as often you want during the script. Based on the last setting the ``ph.exit`` function will set the exitcode. + +Syntax: + +```text +ph.setStatus [STATUS] +``` + +Parameters: + +1. STATUS {string} - a keyword for the return status. + * ok + * warning + * critical + * unknown + +You get an error message when using another keyword. +The default value - if you do not set it anywhere - is "ok". + +Example: + +```shell +if [ $iMyValue -lt $iWarnLimit ]; then + ph.setStatus "ok" +else + if [ $iMyValue -ge $iCriticalLimit ]; then + ph.setStatus "critical" + else + ph.setStatus "warning" + fi +fi +ph.status "Return value was $iMyValue" +ph.exit +``` + +### ph.setStatusByLimit + +Set statuscode by verifying integer only(!) value with critical and warning limit. + +Syntax: + +```text +ph.setStatusByLimit VALUE WARNLIMIT CRITLIMIT +``` + +Parameters: + +1. VALUE {integer} - your discovered value +2. WARNLIMIT {integer} - warning limit +3. CRITLIMIT {integer} - critical limit + +This function works in both directions: + +* critcal value is HIGHER than warning value; eg. for cpu usage warn on 80% and critical on 90% +* critcal value is LOWER than warning value; eg. for free disk space warn on 10% space left and critical on 3% + +Example: + +If no warning or critical value is set they are 0 - and a check will return OK on any value. But if they were set then it reacts on these limits. + +```shell +if [ $iWarnLimit -gt 0 -a $iCriticalLimit -gt 0 ]; then + ph.setStatusByLimit $iTotal $iWarnLimit $iCriticalLimit +fi +``` + +### ph.status + +Show the current status (set by ``ph.setStatus``) as Text. + +Syntax: + +```text +ph.status [TEXT] +``` + +Parameters: + +1. TEXT {string} - optional (but recommended) message to display + +Without a given text only the status will be shown without linebreak. + +Example: + +```shell +if [ $iWarnLimit -gt 0 -a $iCriticalLimit -gt 0 ]; then + ph.setStatusByLimit $iTotal $iWarnLimit $iCriticalLimit +fi +ph.status "NETSTAT - count of connections: $iTotal" +``` + +This shows OK (or WARNING or CRITICAL) as prefix + ": " + "NETSTAT - count of connections: $iTotal". + +``OK: NETSTAT - count of connections: 123`` + +### ph.toUnit + +Transform values eg. to Megabyte or back. + +The calculation is done by bc. A given Input value will be multiplicated with the source unit and then divided by target unit. +It has its limits. + +Syntax: + +```text +ph.toUnit VALUE [UNIT] [DIGITS] +``` + +Parameters: + +1. VALUE {integer|float|string} - your input value as integer or float. Behind your value optionally can be a letter for a unit. +2. UNIT {string} - target unit +3. DIGITS {integer} - optional: for return value set a number of digits behind "."; default: no digits (=integer) + +Valid units are: + +* "K" - Kilo 2^10 +* "M" - Mega 2^20 +* "G" - Giga 2^30 +* "T" - Tera 2^40 +* "P" - Peta 2^50 + +Examples: + +```shell +# -- Convert "kilo" into number: +ph.toUnit 2K +2048 + +# -- Convert "kilo" as float value into number: +ph.toUnit 2.33K +2385 + +# -- Get megabytes from a value in bytes: +ph.toUnit 314351346 M +29979 + +# -- Convert an integer source value with Kilo prefix into megabyte and +# return as float with 4 digits: +ph.toUnit 200.5K M 4 +0.1958 +``` diff --git a/inc_pluginfunctions b/inc_pluginfunctions index 39f583841f7afcb7545f719b5f9992743a451d73..9771ef5dd3705f711c6db6f0f72987c6c8928e12 100644 --- a/inc_pluginfunctions +++ b/inc_pluginfunctions @@ -393,9 +393,12 @@ function ph._perfinit(){ function ph._getperflabel(){ echo "$1" | tr [:upper:] [:lower:] | sed "s#[^a-z0-9\-]##g" } + # get speed of change of a counter value -# param1: string variable name -# param2: integer value +# param string variable name +# param integer value +# param string unit to calculate a speed value per min or per sec; one of s|sec or m|min; default: "s" +# param string optional: flag to return a float value function ph.perfdeltaspeed(){ local varName=$1 local value=$2 @@ -453,6 +456,13 @@ function ph.perfdeltaspeed(){ # # example # ph.perfadd +# +# param string label +# param int|float your value +# param integer optional: warning level +# param integer optional: critical level +# param integer optional: min graph value +# param integer optional: max graph value function ph.perfadd(){ if [ -z "$ph_perfdatafile" ]; then ph._perfinit