Operating System - HP-UX
1825781 Members
2143 Online
109687 Solutions
New Discussion

Re: 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 ))