Operating System - HP-UX
1825756 Members
2365 Online
109687 Solutions
New Discussion

Memory negative result in Nagios Script

 
SOLVED
Go to solution
Mahesh Alexander
Frequent Advisor

Memory negative result in Nagios Script


Hi all,

We use a Nagios monitoring script to monitor our servers and in our memory script we receive in some servers negative results. When I go trough the script step by step I do get a positive result (e.g: 2% of mem percentage used), but never negative as when I run the script.

Please could someone check the script and tell me why it gives negative results?

Serverx:/usr/local/nagios/libexec#./check_memory.sh 85 96
OK: -49% used. Used Mem= -2071116 Kb, Total Mem= 4185088 Kb | Memory_perc=-49%;85;96;; Memory_Kb=-2071116KB;3557324;4017684;0;4185088

Thanks as always for your help.

P.S: And no, there's no way I can ask this to the creator of this script ;-)

Regards,
14 REPLIES 14
James R. Ferguson
Acclaimed Contributor
Solution

Re: Memory negative result in Nagios Script

Hi:

It is possible that you have exceeded 32-bit shell arithmetic limitations. If you are running 11.23 try using '/usr/bin/ksh' which should support 64-bit precision. Otherwise, you could try the Korn93 shell found as '/usr/dt/bin/dtksh'. Change your "she-bang" (#! interpreter line) accordingly.

Regards!

...JRF...
TTr
Honored Contributor

Re: Memory negative result in Nagios Script

Edit the script (or copy it to an new script name and edit the new script) and add the line "set -x" below the "#!/bin/sh" line and rerun it as

./check_memory.sh 85 96 > chkmem.log 2>&1

Then look at the chkmem.log file or post it back. Most likely shell arithmetic overflow.
James R. Ferguson
Acclaimed Contributor

Re: Memory negative result in Nagios Script

Hi (again):

> ME: If you are running 11.23 try using '/usr/bin/ksh' which should support 64-bit precision. Otherwise, you could try the Korn93 shell found as '/usr/dt/bin/dtksh'.

While the 'ksh' shell on 11.23 or later will do 64-bit arithmetic, the 'dtksh' shell will _not_.

You could use 'bc' or 'awk' [with printf()'s "f" specification], or Perl to perform your calculations in lieu of the shell. For example, 'awk' will do:

# echo 2147483647 | awk '{printf "%12.0f\n",$0*4}'
8589934588

Regards!

...JRF...

Dennis Handly
Acclaimed Contributor

Re: Memory negative result in Nagios Script

>JRF: the dtksh shell will _not_.

Yes but it will do floating point arithmetic.

Mahesh Alexander
Frequent Advisor

Re: Memory negative result in Nagios Script

Hi again,

Your answers are very useful. Although changing the shell from #!/bin/sh to #!/usr/bin/ksh helped a lot, now I get results above 100% ¿? Check example:

root:serverx:/ # ./usr/local/nagios/libexec/check_memory.sh 85 95
CRITICAL: 114% used. Used Mem= 52837076 Kb, Total Mem= 46086144 Kb | Memory_perc=114%;85;95;; Memory_Kb=52837076KB;39173222;43781836;0;46086144

Perhaps the following line does not provide the best way to check physical memory used:

USEDPAGES=`vmstat |grep -v memory | grep -v avm | awk '{ print $4 }'`

Any idea on what could be the best command to achieve the memory used?

However I wanted to paste the result that TTr asked just in case there's something interesting to mention about
:
root:serverx:/usr/local/nagios/libexec # more check_mem.log
+ test 2 -ne 2
+ + getconf PAGESIZE
PAGESIZE=4096
+ WARNING=85
+ CRITICAL=96
+ + machinfo
+ grep -i memory
+ awk { print $3 }
TOTALMBMEM=49102
+ TOTALMEM=50280448
+ + vmstat
+ grep -v memory
+ awk { print $4 }
+ grep -v avm
USEDPAGES=3137222
+ USEDMEM=-34024
+ FREEMEM=50314472
+ USEDPERCENT=0
+ WARNINGKB=-211292
+ CRITICALKB=5319557
+ [ 0 != ]
+ [ 0 -ge 96 ]
+ [ 0 -ge 85 ]
+ [ 0 -lt 85 ]
+ echo OK: 0% used. Used Mem= -34024 Kb, Total Mem= 50280448 Kb | Memory_perc=0%;85;96;; Memory_Kb=-34024KB;-211292;5319557;0;502804
48
OK: 0% used. Used Mem= -34024 Kb, Total Mem= 50280448 Kb | Memory_perc=0%;85;96;; Memory_Kb=-34024KB;-211292;5319557;0;50280448
+ exit 0

Thanks again for your help.
Regards,
James R. Ferguson
Acclaimed Contributor

Re: Memory negative result in Nagios Script

Hi:

Using double parentheses for arithmetic evaluation is fine as where you do:

# TOTALMEM=$(($TOTALMBMEM * 1024))

However, you should use curly braces for parameter substitution. Change things like:

# echo "Memory_Kb=$((USEDMEM))KB;"
to:

# echo "Memory_Kb=${USEDMEM}KB;"

Regards!

...JRF...
TTr
Honored Contributor

Re: Memory negative result in Nagios Script

It is 32 bit arithmetic overflow. The first error appears at the USEDMEM=-34024 variable which is calculated as USEDMEM=$(($USEDPAGES * $PAGESIZE / 1024)). The numbers here involved are 3137222 * 4096 / 1024. The overflow is in the multiplication.

3137222 * 4096 = 12,850,061,312 This number is too big and overflows as follows

12,850,061,312 mod 2^31 = 2,112,643,072

2,112,643,072 - 2^31 = -34840576 (The number is in the negative range for 2^32 integers)

-34840576 / 1024 = -34024
TTr
Honored Contributor

Re: Memory negative result in Nagios Script

I would convert all calculations to use "bc". It is rather easy, rather than using
TOTALMEM=$(($TOTALMBMEM * 1024)), you can use
TOTALMEM=`echo "$TOTALMBMEM * 1024" | /usr/bin/bc`
and
USEDMEM=`echo "$USEDPAGES * $PAGESIZE / 1024" | /usr/bin/bc`
and so on.
James R. Ferguson
Acclaimed Contributor

Re: Memory negative result in Nagios Script

Hi (again):

> TTr: It is 32 bit arithmetic overflow.

I agree if this is the Posix shell, but if the Korn ('ksh') shell is used in 11.23 or later, the result is valid.

Regards!

...JRF...

Dennis Handly
Acclaimed Contributor

Re: Memory negative result in Nagios Script

>JRF: Using double parentheses for arithmetic evaluation is fine as where you do:
# TOTALMEM=$(($TOTALMBMEM * 1024))

Actually no need to use any stinkin' "$" for arithmetic evaluation:
(( TOTALMEM = TOTALMBMEM * 1024 ))

>TTr: The first error appears at the ... which is calculated as USEDMEM=$(($USEDPAGES * $PAGESIZE / 1024)).

You can change the order to:
(( USEDMEM = USEDPAGES * (PAGESIZE / 1024) ))

>TOTALMEM=`echo "$TOTALMBMEM * 1024" | /usr/bin/bc`

You shouldn't go backwards and use `` vs $():
TOTALMEM=$(echo "$TOTALMBMEM * 1024" | /usr/bin/bc)
Mahesh Alexander
Frequent Advisor

Re: Memory negative result in Nagios Script

OK
I'm trying to when it goes over 100% then set variable to 100. With lines:

if [ $var -eg 100 ]; then
$VAR=100
fi

But does not work like this.

Other way of doing this?

regards,
Steven Schweda
Honored Contributor

Re: Memory negative result in Nagios Script

> if [ $var -eg 100 ]; then
> $VAR=100
> fi

> But does not work like this.

"does not work" is not a useful problem
description. What happens? Error messages?

Compare:
$var $VAR
-eg -ge
Mahesh Alexander
Frequent Advisor

Re: Memory negative result in Nagios Script

Never mind it does work now. Thanks!

I used the following:

if [ $VAR-ge 100 ]; then
VAR=$((100))
fi

Regards!
Dennis Handly
Acclaimed Contributor

Re: Memory negative result in Nagios Script

>VAR=$((100))

No need to do something that complicated.
VAR=100
(( VAR = 100 ))