User Tools

Site Tools


aix:graphite_aix

Graphite installation on AIX 7.1

install apache2 with Django and mod_wsgi:

ATTENTION

Install http 2.2 instead of 2.4, else apxs (extension for apache from devel package) will failed and it
reports many error during compilation
# /opt/freeware/bin/apxs -qv   
Use of uninitialized value in concatenation (.) or string at /opt/freeware/bin/apxs line 222.

In my compilation I use IBM compiler 11.1 instead gcc

All rpm are downloaded from http://www.perzl.org

http://www.sturge.ca/?p=117

AIX base rpm packages:

AIX-rpm-7.1.2.15-1
tcl-8.4.7-3
tk-8.4.7-3
expect-5.42.1-3
lsof-4.86-1
gettext-0.10.40-8
popt-1.16-1
info-4.13a-2
gmp-5.0.5-1
coreutils-8.18-1
logrotate-3.8.2-1
rsync-3.0.9-1
tar-1.26-1
bzip2-1.0.6-1
zip-3.0-1
unzip-6.0-2
zlib-1.2.7-2
libjpeg-8d-1
tightvnc-server-1.3.10-2
bash-4.2-12

Install wget:

rpm -Uhv bash-4.2-12.aix5.1.ppc.rpm
rpm -Uhv info-4.13a-2.aix5.1.ppc.rpm
rpm -Uhv libiconv-1.14-2.aix5.1.ppc.rpm
rpm -Uhv libidn-1.26-1.aix5.1.ppc.rpm
rpm -Uhv expat-2.1.0-1.aix5.1.ppc.rpm
rpm -Uhv gettext-0.10.40-8.aix5.2.ppc.rpm
rpm -Uhv libgcc-4.7.2-1.aix7.1.ppc.rpm
rpm -Uhv libffi-3.0.11-2.aix5.1.ppc.rpm
rpm -Uhv glib2-2.30.3-2.aix5.1.ppc.rpm
rpm -Uhv readline-6.2-4.aix5.1.ppc.rpm
rpm -Uhv pcre-8.32-1.aix5.1.ppc.rpm
rpm -Uhv wget-1.14-2.aix5.1.ppc.rpm

Install apache 2.2

rpm -Uhv apr-util-1.5.1-1.aix5.1.ppc.rpm
rpm -Uhv apr-1.4.6-1.aix5.2.ppc.rpm
rpm -Uhv db4-4.7.25-2.aix5.1.ppc.rpm
rpm -Uhv gdbm-1.10-1.aix5.1.ppc.rpm
rpm -Uhv openldap-2.4.23-0.3.aix5.1.ppc.rpm
rpm -Uhv apr-util-ldap-1.5.1-1.aix5.1.ppc.rpm
rpm -Uhv unixODBC-2.3.1-1.aix5.1.ppc.rpm
rpm -Uhv apr-util-odbc-1.5.1-1.aix5.1.ppc.rpm
rpm -Uhv httpd-2.2.24-1.aix5.1.ppc.rpm

Install gnutls and its required filesets

rpm -Uhv libgpg-error-1.10-1.aix5.1.ppc.rpm
rpm -Uhv libgcrypt-1.5.0-1.aix5.1.ppc.rpm
rpm -Uhv libtasn1-3.2-1.aix5.1.ppc.rpm
rpm -Uhv lzo-2.06-1.aix5.1.ppc.rpm
rpm -Uhv nettle-2.6-1.aix5.1.ppc.rpm
rpm -Uhv httpd-2.2.24-1.aix5.1.ppc.rpm
rpm -Uhv p11-kit-0.14-1.aix5.1.ppc.rpm
rpm -Uhv gnutls-2.12.20-1.aix5.1.ppc.rpm

Install http-devel

rpm -Uhv pkg-config-0.28-1.aix5.1.ppc.rpm
rpm -Uhv apr-devel-1.4.6-1.aix5.2.ppc.rpm
rpm -Uhv db4-devel-4.7.25-2.aix5.1.ppc.rpm
rpm -Uhv expat-devel-2.1.0-1.aix5.1.ppc.rpm
rpm -Uhv freetds-0.92.79-1.aix5.1.ppc.rpm
rpm -Uhv freetds-devel-0.92.79-1.aix5.1.ppc.rpm
rpm -Uhv openldap-devel-2.4.23-0.3.aix5.1.ppc.rpm
rpm -Uhv sqlite-3.7.15.2-1.aix5.1.ppc.rpm
rpm -Uhv sqlite-devel-3.7.15.2-1.aix5.1.ppc.rpm
rpm -Uhv unixODBC-devel-2.3.1-1.aix5.1.ppc.rpm
rpm -Uhv gdbm-devel-1.10-1.aix5.1.ppc.rpm
rpm -Uhv apr-util-devel-1.5.1-1.aix5.1.ppc.rpm
rpm -Uhv httpd-devel-2.2.24-1.aix5.1.ppc.rpm

Install httpd doc and ssl_mod

rpm -Uhv httpd-manual-22.2.24-1.aix5.1.ppc.rpm
rpm -Uhv mod_ssl-2.4.4-1.aix5.1.ppc.rpm

Install python

rpm -Uhv python-libs-2.6.7-1.aix5.1.ppc.rpm
rpm -Uhv python-devel-2.6.7-1.aix5.1.ppc.rpm
rpm -Uhv tcl-8.5.13-1.aix5.1.ppc.rpm
rpm -Uhv freetype2-2.4.11-1.aix5.1.ppc.rpm
rpm -Uhv fontconfig-2.8.0-2.aix5.1.ppc.rpm
rpm -Uhv libXrender-0.9.7-2.aix6.1.ppc.rpm
rpm -Uhv libXft-2.3.1-1.aix5.1.ppc.rpm
rpm -Uhv tk-8.5.13-1.aix5.1.ppc.rpm
rpm -Uhv tkinter-2.6.7-1.aix5.1.ppc.rpm
rpm -Uhv python-tools-2.6.7-1.aix5.1.ppc.rpm
rpm -Uhv jbigkit-libs-2.0-2.aix5.1.ppc.rpm
rpm -Uhv xz-libs-5.0.4-1.aix5.1.ppc.rpm
rpm -Uhv libtiff-4.0.3-1.aix5.1.ppc.rpm
rpm -Uhv lcms-1.19-1.aix5.1.ppc.rpm
rpm -Uhv python-imaging-1.1.7-1.aix5.1.ppc.rpm
rpm -Uhv python-docutils-0.10-1.aix5.1.ppc.rpm

Compiler:

rpm -Uhv mpfr-3.1.2-1.aix5.1.ppc.rpm
rpm -Uhv libmpc-1.0.1-2.aix5.1.ppc.rpm
rpm -Uhv gcc-cpp-4.7.2-1.aix7.1.ppc.rpm
rpm -Uhv libstdc++-4.7.2-1.aix7.1.ppc.rpm
rpm -Uhv libstdc++-devel-4.7.2-1.aix7.1.ppc.rpm
rpm -Uhv gcc-c++-4.7.2-1.aix7.1.ppc.rpm
rpm -Uhv libgomp-4.7.2-1.aix7.1.ppc.rpm
rpm -Uhv sed-4.2.2-1.aix5.1.ppc.rpm
rpm -Uhv mod_python-3.3.1-1.aix5.1.ppc.rpm

Download the wsgi module:

wget http://modwsgi.googlecode.com/files/mod_wsgi-3.4.tar.gz

Change some line into the file mod_wsgi.c (http://stackoverflow.com/questions/4229542/aix-missing-symbols-ap-cleanup-scoreboard-and-ap-accept-lock-mech-for-apache-pro)

#if !defined(AP_ACCEPT_MUTEX_TYPE)
   sconfig->lock_mechanism = ap_accept_lock_mech;
#else
   sconfig->lock_mechanism = APR_LOCK_DEFAULT;
#endif

and change it to:

#define AP_ACCEPT_MUTEX_TYPE 1
#if !defined(AP_ACCEPT_MUTEX_TYPE)
   sconfig->lock_mechanism = ap_accept_lock_mech;
#else
   sconfig->lock_mechanism = APR_LOCK_DEFAULT;
#endif

Compilation:

[root@graphiteaix]/root/mod_wsgi-3.4# ./configure
checking for apxs2... no
checking for apxs... /opt/freeware/sbin/apxs
checking Apache version... 2.2.24
checking for python... /usr/bin/python
configure: creating ./config.status
config.status: creating Makefile

[root@graphiteaix]/root/mod_wsgi-3.4# ll /opt/freeware/sbin/apxs
24 -rwxr-xr-x 1 root system 22643 Mar  4 10:51 /opt/freeware/sbin/apxs
[root@graphiteaix]/root/mod_wsgi-3.4# rpm -qa | grep httd
httpd-2.2.24-1
httpd-devel-2.2.24-1
[root@graphiteaix]/root/mod_wsgi-3.4# rpm -ql httpd-2.2.24-1 | grep apxs
[root@graphiteaix]/root/mod_wsgi-3.4# rpm -ql httpd-devel-2.2.24-1 | grep apxs
/opt/freeware/man/man8/apxs.8
/opt/freeware/sbin/apxs

[root@graphiteaix]/root/mod_wsgi-3.4# make
        /opt/freeware/sbin/apxs -c -I/opt/freeware/include/python2.6 -DSYSV -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 -D_AIX51 -D_ALL_SOURCE -DFUNCPROTO=15 -DNDEBUG  -Wc,-qmaxmem=16384 -Wc,-DSYSV -Wc,-D_AIX -Wc,-D_AIX61 -Wc,-D_AIX71 -Wc,-D_ALL_SOURCE -Wc,-DFUNCPROTO=15 -Wc,-O -Wc,-I/opt/freeware/include  mod_wsgi.c -L/opt/freeware/lib64 -L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib64:/opt/freeware/lib:/usr/lib:/lib -Wl,-bmaxdata:0x80000000 -L/opt/freeware/lib -L/opt/freeware/lib/python2.6/config  -lpython2.6 -ldl -lm
/opt/freeware/lib/apr-1/build/libtool --silent --mode=compile cc -qlanglvl=extc89 -prefer-pic -qmaxmem=16384 -DSYSV -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 -D_AIX51 -D_ALL_SOURCE -DFUNCPROTO=15 -O -I/opt/freeware/include  -U__STR__ -D_THREAD_SAFE -D_USE_IRS -D_LARGEFILE64_SOURCE -qHALT=E -I/opt/freeware/include/httpd  -I/opt/freeware/include/apr-1   -I/opt/freeware/include/apr-1  -qmaxmem=16384 -DSYSV -D_AIX -D_AIX61 -D_AIX71 -D_ALL_SOURCE -DFUNCPROTO=15 -O -I/opt/freeware/include -I/opt/freeware/include/python2.6 -DSYSV -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 -D_AIX51 -D_ALL_SOURCE -DFUNCPROTO=15 -DNDEBUG  -c -o mod_wsgi.lo mod_wsgi.c && touch mod_wsgi.slo
   11064  1500-010: (W) WARNING in wsgi_deadlock_thread: Infinite loop.  Program may not stop.
   11095  1500-010: (W) WARNING in wsgi_monitor_thread: Infinite loop.  Program may not stop.
    1500-030: (I) INFORMATION: newInterpreterObject: Additional optimization may be attained by recompiling and specifying MAXMEM option with a value greater than 16384.
/opt/freeware/lib/apr-1/build/libtool --silent --mode=link cc -qlanglvl=extc89 -o mod_wsgi.la  -rpath /opt/freeware/lib/httpd/modules -module -avoid-version   -Wl,-brtl  mod_wsgi.lo -L/opt/freeware/lib64 -L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib64:/opt/freeware/lib:/usr/lib:/lib -Wl,-bmaxdata:0x80000000 -L/opt/freeware/lib -L/opt/freeware/lib/python2.6/config -lpython2.6 -ldl -lm
Target "all" is up to date.

[root@graphiteaix]/root/mod_wsgi-3.4# ls -l
total 916
  4 drwxr-xr-x 3  501 staff    4096 May 10 16:51 .
  4 drwxr-xr-x 6 root system   4096 May 10 15:26 ..
  4 -rw-r--r-- 1  501 staff      97 Aug 23  2012 .hgignore
  4 -rw-r--r-- 1  501 staff      56 Aug 23  2012 .hgtags
  0 drwxr-xr-x 2 root system    256 May 10 16:51 .libs
 12 -rw-r--r-- 1  501 staff   11358 Aug 23  2012 LICENCE
  4 -rw-r--r-- 1 root system   1729 May 10 16:49 Makefile
  0 lrwxrwxrwx 1 root system     16 May 10 16:49 Makefile.in -> posix-ap2X.mk.in
 20 -rw-r--r-- 1  501 staff   18063 Aug 23  2012 README
 24 -rw-r--r-- 1 root system  23516 May 10 16:10 apxs1
  4 -rw-r--r-- 1 root system   4000 May 10 16:49 config.log
 24 -rwxr-xr-x 1 root system  20893 May 10 16:49 config.status
 80 -rwxr-xr-x 1  501 staff   80107 Aug 23  2012 configure
  8 -rw-r--r-- 1  501 staff    5886 Aug 23  2012 configure.ac
476 -rw-r--r-- 1  501 staff  484965 May 10 16:03 mod_wsgi.c
  4 -rw-r--r-- 1 root system   1031 May 10 16:51 mod_wsgi.la
  4 -rw-r--r-- 1 root system    276 May 10 16:51 mod_wsgi.lo
220 -rw-r--r-- 1 root system 224159 May 10 16:51 mod_wsgi.o
  0 -rw-r--r-- 1 root system      0 May 10 16:51 mod_wsgi.slo
  4 -rw-r--r-- 1  501 staff    1195 Aug 23  2012 posix-ap1X.mk.in
  4 -rw-r--r-- 1  501 staff    1247 Aug 23  2012 posix-ap2X.mk.in
  4 -rw-r--r-- 1  501 staff     907 Aug 23  2012 win32-ap22py26.mk
  4 -rw-r--r-- 1  501 staff     907 Aug 23  2012 win32-ap22py27.mk
  4 -rw-r--r-- 1  501 staff     907 Aug 23  2012 win32-ap22py31.mk


[root@graphiteaix]/root/mod_wsgi-3.4# make install
        /opt/freeware/sbin/apxs -i -S LIBEXECDIR=/opt/freeware/lib/httpd/modules -n 'mod_wsgi' mod_wsgi.la
/var/www/build/instdso.sh SH_LIBTOOL='/opt/freeware/lib/apr-1/build/libtool' mod_wsgi.la /opt/freeware/lib/httpd/modules
rm -f /opt/freeware/lib/httpd/modules/mod_wsgi.so
/opt/freeware/lib/apr-1/build/libtool --mode=install cp mod_wsgi.la /opt/freeware/lib/httpd/modules/
libtool: install: cp .libs/mod_wsgi.so /opt/freeware/lib/httpd/modules/mod_wsgi.so
libtool: install: cp .libs/mod_wsgi.lai /opt/freeware/lib/httpd/modules/mod_wsgi.la
libtool: install: cp .libs/mod_wsgi.a /opt/freeware/lib/httpd/modules/mod_wsgi.a
libtool: install: chmod 644 /opt/freeware/lib/httpd/modules/mod_wsgi.a
libtool: install: ranlib /opt/freeware/lib/httpd/modules/mod_wsgi.a
chmod 755 /opt/freeware/lib/httpd/modules/mod_wsgi.so

Additionnal for compiling httpd server:

rpm -Uhv libxml2-2.9.0-1.aix5.1.ppc.rpm lua-5.2.1-1.aix5.1.ppc.rpm xz-devel-5.0.4-1.aix5.1.ppc.rpm readline-devel-6.2-4.aix5.1.ppc.rpm libxml2-devel-2.9.0-1.aix5.1.ppc.rpm lua-devel-5.2.1-1.aix5.1.p
pc.rpm openssl-devel-1.0.1e-1.aix5.1.ppc.rpm pcre-devel-8.32-1.aix5.1.ppc.rpm zlib-devel-1.2.7-2.aix5.1.ppc.rpm

Compilation options with XlC 11.1:

export CONFIG_SHELL=/opt/freeware/bin/bash
 export CONFIG_ENV_ARGS=/opt/freeware/bin/bash

 export CC=cc
 export CFLAGS="-qmaxmem=16384 -DSYSV -D_AIX -D_AIX61 -D_AIX71 -D_ALL_SOURCE -DFUNCPROTO=15 -O -I/opt/freeware/include"

 export CXX=xlC
 export CXXFLAGS=$CFLAGS

 export F77=xlf
 export FFLAGS="-qmaxmem=16384 -O -I/opt/freeware/include"

 export LD=ld
 # for 32-bit applications
 export LDFLAGS="-L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib:/usr/lib:/lib -Wl,-bmaxdata:0x80000000"
 # for 64-bit applications
 export LDFLAGS="-L/opt/freeware/lib64 -L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib64:/opt/freeware/lib:/usr/lib:/lib -Wl,-bmaxdata:0x80000000"

export PATH=/usr/bin:/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:/usr/vac/bin:/usr/vacpp/bin:/usr/ccs/bin:/usr/dt/bin:/usr/opt/perl5/bin:/opt/freeware/bin:/opt/freeware/sbin:/usr/local/bin:/usr/lib/instl

With gcc:

export CONFIG_SHELL=/opt/freeware/bin/bash
 export CONFIG_ENV_ARGS=/opt/freeware/bin/bash

 export CC=gcc
 export CFLAGS="-DSYSV -D_AIX -D_AIX61 -D_AIX71 -D_ALL_SOURCE -DFUNCPROTO=15 -O -I/opt/freeware/include"

 export CXX=g++
 export CXXFLAGS=$CFLAGS

 export F77=xlf
 export FFLAGS="-O -I/opt/freeware/include"

 export LD=ld
 # for 32-bit applications
 export LDFLAGS="-L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib:/usr/lib:/lib -Wl,-bmaxdata:0x80000000"
 # for 64-bit applications
 export LDFLAGS="-L/opt/freeware/lib64 -L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib64:/opt/freeware/lib:/usr/lib:/lib -Wl,-bmaxdata:0x80000000"

 export PATH=/usr/bin:/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:/usr/vac/bin:/usr/vacpp/bin:/usr/ccs/bin:/usr/dt/bin:/usr/opt/perl5/bin:/opt/freeware/bin:/opt/freeware/sbin:/usr/local/bin:/usr/lib/instl

Sample script to send to graphite

cat create_nmon_data.sh
#!/bin/ksh
# field:   nmon.aix.serial.hostname.disk.hdiskx.param
# Send data to Graphite
#    echo "stats.${HOSTNAME}.tmp.file.count ${MY_DATA} ${DATE}" | nc $GRAPHITE $GRAPHITE_PORT
# -f option to use a nmon static log
# perl -e 'print scalar(localtime(1384258765)), "\n"'
# Add an entry into crontab
#0 0 * * * /usr/bin/nmon -fTNWLAd^ -m /tools/perf/nmon -s30 -c2880 >/dev/null 2>&1
#set -x

FILE_DEF=0

case $1 in
  "-f" ) NMON_FILE=$2
         FILE_DEF=1;;
esac

sn=`basename $0 | cut -d. -f1`
DAY=$(date "+%d")
GRAPH_PREFIX="nmon.aix"
CARBON_HOST=192.168.222.164
CARBON_PORT=2003

NMON_BIN=/usr/bin/nmon
NMON_INTERVAL=30
NMON_SNAPSHOTS=2880
NMON_DATADIR=/tools/perf/nmon
NMON_LOG=/tools/perf/nmon/$sn.$DAY.log

RET_LOG=4 # in days

GRAPH_FILE=$NMON_DATADIR/to_send_to_graphite.$DAY

DIR_BIN=/tools/perf/bin
FILE_REF=$NMON_DATADIR/nmon.ref
FILE_DATA=${NMON_FILE:- $NMON_DATADIR/$(hostname -s)_$DAY.nmon}
LINUX_DATE=/usr/linux/bin/date
FILE_TOP=$NMON_DATADIR/$(hostname -s)_$DAY.process

# Initialize 2 number on 4 characters
typeset -Z4 number1
typeset -Z4 number2


#*************************************
# function
#*************************************
cleanup ()
{
find $NMON_DATADIR -mtime +$RET_LOG | grep -v '.process' | xargs rm -f
rm -f $GRAPH_FILE* > /dev/null 2>&1
rm -f $NMON_DATADIR/to_send_to_graphite.* > /dev/null 2>&1
rm -f $FILE_REF* > /dev/null 2>&1
}

#*************************************
# function
#*************************************
create_ref_file ()
{
cat $FILE_DATA | sed -e '/^ZZZZ/G' | grep -p 'AAA' | sort -A > $FILE_REF
cat $FILE_DATA | sed 's/^ *//' | grep -v '^BBB' | grep -v 'T00' > $FILE_REF.1
egrep '^TOP|^UARG' $FILE_REF > $FILE_TOP
}




#*************************************
# function
#*************************************
send_graphite ()
{
date >> $GRAPH_FILE.err

# Select only valid datas
for graph_data in $(cat $GRAPH_FILE)
do
  echo $graph_data | sed "s/\.\./ERROR/g" | sed "s/\.\;/ERROR/g" | grep ERROR > /dev/null 2>&1
  if [ $? -eq 0 ]
  then 
    echo $graph_data >> $GRAPH_FILE.err
  else
    echo $graph_data >> $GRAPH_FILE.tmp
  fi
done
sed 's/;/\ /g' $GRAPH_FILE.tmp > $GRAPH_FILE.OK

# Send to Graphite server
#$DIR_BIN/send2graphite.pl $CARBON_HOST $CARBON_PORT "$GRAPH_FILE.OK"
send_graphite_perl
if [ $? -eq 0 ]
then 
  echo "send OK"
  cat /dev/null > $GRAPH_FILE
  cat /dev/null > $GRAPH_FILE.tmp
else 
  echo "Not send"
fi
}

#*************************************
# function perl
#*************************************
send_graphite_perl ()
{
/usr/bin/perl - $CARBON_HOST $CARBON_PORT "$GRAPH_FILE.OK" <<'__HERE__'
use strict;
#use Data::Dumper;
use Time::Piece;
use Time::Local;
use IO::Socket;
use POSIX;
use Getopt::Long;
use Data::Dumper qw(Dumper);

print Dumper \@ARGV;

my $graphite_host = $ARGV[0];
my $graphite_port = $ARGV[1];
#my $fileName = '/tools/perf/nmon/to_send_to_graphite.19.OK';
my $fileName = $ARGV[2];

print "ARG1=${fileName}\n";

my @buf = ();

open(FILE, "$fileName") or die "Cannot open file";
while (<FILE>) {
  push(@buf, $_);
}
close (FILE);

my $sock = new IO::Socket::INET (
        PeerAddr => $graphite_host,
        PeerPort => $graphite_port,
        Proto => 'tcp'
    );
    if ($sock) {
        print $sock @buf;
        close($sock);
    } else {
        print "Error sending data to graphite server\n";
        exit 1;
    }
    @buf = ();
__HERE__
}

#*************************************
# function
#*************************************
precheck ()
{
# Required linux date binary to convert date to epoch:
# /usr/linux/bin/date -d "12-NOV-2013 13:19:25" "+%s" 
# For info reverse:
# perl -e 'print scalar(localtime(1384258765)), "\n"'

if [[ ! -e $LINUX_DATE ]]
then
  echo "########## ERROR : ##########"
  echo "Please install coreutil rpm package from http://www.perzl.org/aix/"
  echo "Linux date binary is included in this package and required"
  exit 1
fi
}

#*************************************
# function
#*************************************
disk_value ()
{
param=$1
cnt=0
disk=$(echo $ref | cut -d',' -f2- | sed 's/,/\ /g')
set -A disk_ref $(echo $disk) 

for val in $(echo $2 | sed 's/,/\ /g')
do
  echo $GRAPH_NAME.disk.${disk_ref[$cnt]}.$param";"$val";"$GRAPH_TIME >> $GRAPH_FILE
  ((cnt=cnt+1))
done
}

#*************************************
# function
#*************************************
cpu_value ()
{
cpu=$(echo $ref | tr 'A-Z' 'a-z' | sed 's/\%/_pct/g' | sed 's/\ //g' | sed 's/,/\ /g')
set -A cpu_ref $(echo $cpu) 

param=${cpu_ref[0]}
cnt=1
for val in $(echo $1 | sed 's/,/\ /g')
do
  echo $GRAPH_NAME.cpu.$param.${cpu_ref[$cnt]}";"$val";"$GRAPH_TIME >> $GRAPH_FILE
  ((cnt=cnt+1))
done
}

#*************************************
# function
#*************************************
adapter_value ()
{
adapter=$(echo $ref | cut -d',' -f2- | sed 's/\_/\-/g' | sed 's/\//p/g' | sed 's/,/\ /g')
set -A adapter_ref $(echo $adapter)
cnt=0

for val in $(echo $1 | sed 's/,/\ /g')
do
  adapter_ref1=$(echo ${adapter_ref[$cnt]} | sed 's/\-/\./1')
  echo $GRAPH_NAME.adapter.$adapter_ref1";"$val";"$GRAPH_TIME >> $GRAPH_FILE
done
}

#*************************************
# function
#*************************************
fcadapter_value ()
{
param=$1
cnt=0
adapter=$(echo $ref | cut -d',' -f2- | sed 's/,/\ /g')
set -A fcadapter_ref $(echo $adapter) 

for val in $(echo $2 | sed 's/,/\ /g')
do
  echo $GRAPH_NAME.adapter.${fcadapter_ref[$cnt]}.$param";"$val";"$GRAPH_TIME >> $GRAPH_FILE
  ((cnt=cnt+1))
done
}

#*************************************
# function
#*************************************
other_value ()
{
other=$(echo $ref | cut -d',' -f2- | sed 's/\//@/g' | sed 's/,/\ /g')
set -A other_ref $(echo $other)
cnt=0

for val in $(echo $1 | sed 's/,/\ /g')
do
  adapter_ref1=$(echo ${other_ref[$cnt]} | sed 's/\-/\./1')
  echo $GRAPH_NAME.other.$other_ref1";"$val";"$GRAPH_TIME >> $GRAPH_FILE
done
}

#*************************************
# function
#*************************************
extract_nmon ()
{
number1=0
number2=1
echo $number
# While nmon_topas PID < 1 day then
#for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
while (( "$NMON_EXIST" == "0" || "$FILE_DEF" == "1" ))
do
  NMON_EXIST=$(ps $NMON_PID > /dev/null 2>&1; echo $?)
  cat /dev/null > $GRAPH_FILE
  ((number1=number1+1))
  ((number2=number2+1))
  # Add until next data collection T+1 is complete to continue by processing data collection T+0
  if [[ $FILE_DEF != "1" ]]
  then
    while [[ $(grep "T$number2" $FILE_DATA | cut -d',' -f2-3 | grep "T$number2" > /dev/null 2>&1;echo $?) -ne 0 ]]
    do
      sleep 3; echo "waiting T$number2"
      if [ $(ps $NMON_PID > /dev/null 2>&1; echo $?) -eq 1 ]
      then
        echo "End of normal process, NMON process is finished for day $DAY at $(date)"
        break
      fi
    done
  fi
      echo "waiting T$number2"
  for line in $(grep "T$number1" $FILE_DATA | sed 's/\ //g' | egrep -v "^AAA|^BBB")
  do
    if [ $(echo $line | cut -d',' -f2-3 | grep "T$number1" | sort -r) ]
    then
      # keep only good lines
      arg=$(echo $line | cut -d',' -f1)
      if [ $(echo $line | grep '^ZZZZ') ]
      then
        echo $line >> $FILE_TOP
        val1=$(echo $line | cut -d',' -f3)
        val2=$(echo $line | cut -d',' -f4)
        GRAPH_TIME=$($LINUX_DATE -d"$val2 $val1" "+%s")
      else
        rest=$(echo $line | cut -d',' -f3-)
        ref=$(grep "^$arg," $FILE_REF | sed 's/^ *//' | cut -d',' -f1,3- | sed 's/\ //g')
        if [ "$ref" == "" ]
        then
          ref=$(grep "^$arg," $FILE_DATA | sed 's/^ *//' | head -1 | cut -d',' -f1,3- | sed 's/\ /_/g')
        fi
        if [ $(echo $line | grep '^DISK') ]
        then
          case $arg in
                "DISKBUSY")         disk_value busypct $rest;;
                "DISKREAD")         disk_value rkBps $rest;;
                "DISKWRITE")        disk_value wkBps $rest;;
                "DISKXFER")         disk_value xfiops $rest;;
                "DISKRXFER")        disk_value xfriops $rest;;
                "DISKBSIZE")        disk_value blksz $rest;;
                "DISKRIO")          disk_value riops $rest;;
                "DISKWIO")          disk_value wiops $rest;;
                "DISKAVGRIO")       disk_value avgriops $rest;;
                "DISKAVGWIO")       disk_value avgwiops $rest;;
                "DISKSERV")         disk_value svctms $rest;;
                "DISKREADSERV")     disk_value svcrtms $rest;;
                "DISKWRITESERV")    disk_value svcwtms  $rest;;
                "DISKWAIT")         disk_value waitqtms $rest;;
          esac
        else
          if [ $(echo $line | grep 'CPU') ]
          then
            cpu_value $rest
          else
            if [ $(echo $line | egrep "^NET|^IO") ]
            then
              adapter_value $rest
            else
              if [ $(echo $line | egrep "^FC") ]
              then
                case $arg in
                  "FCREAD")         fcadapter_value rKBps $rest;;
                  "FCWRITE")        fcadapter_value wKBps $rest;;
                  "FCXFERIN")       fcadapter_value xferinps $rest;;
                  "FCXFEROUT")      fcadapter_value xferoutps $rest;;
                esac
              else
                other_value $rest
              fi
            fi
          fi
        fi
      fi
    fi
  done
  grep "T$number1" $FILE_DATA | egrep '^TOP|^UARG' >> $FILE_TOP
  echo "Trying to send to graphite server"
  send_graphite 
done
}

######################################
# main
######################################
main ()
{
date 
echo "Process number: $$"
precheck
cleanup

echo "Start NMON process"
if [[ $FILE_DEF != "1" ]]
then
  $NMON_BIN -fTNWLAd^ -F $FILE_DATA -s${NMON_INTERVAL} -c${NMON_SNAPSHOTS}
  sleep 30
fi

NMON_PID=$(ps -eo pid,ppid,args | grep -v grep | grep topas_nmon | grep "$FILE_DATA" | awk '{print $1}')
NMON_EXIST=$(ps $NMON_PID > /dev/null 2>&1; echo $?)
echo "NMON PID: $NMON_PID"

echo "Create reference file"
create_ref_file
HOST=$(grep '^AAA,host,' $FILE_REF | cut -d',' -f3 | cut -d'.' -f1)
SERIAL=$(grep '^AAA,SerialNumber,' $FILE_REF | cut -d',' -f3)
#GRAPH_NAME=$(echo $GRAPH_PREFIX.$SERIAL.$HOST)
GRAPH_NAME=$(echo $GRAPH_PREFIX.$HOST)

echo "Start NMON extract"
extract_nmon
}
 
main > $NMON_LOG 2>&1

script collect perf svc to graphite

cat perf_svc_graphite.pl
#!/usr/bin/perl -w
#
# Collect IBM SVC stat for graphite monitoring
#

use strict;
use Data::Dumper;
use Time::Piece;
use Time::Local;
use IO::Socket;
use POSIX;
use Getopt::Long;

#
# configuration
# 'no password' ssh connection should be enable
#
my $graphite_host = 'graphite';
my $graphite_port = 2003;
my $step = 60;  # seconds
my $tmpDir = '/tmp';
my @nodes = ( 'svc-node1', 'svc-node2' );
my $svc_host = 'svc';
my $svc_user = 'admin';

#
# global var
#
my %vdisks = ();
my @buf = ();
my @statFiles = ();
my $wallClock = undef;

#
# convert tag 'YYMMDD_HHMMSS' to epoch time.
#
sub tag2epoc {
    my $tag = $_[0];
    $tag = $1 if $tag =~ /(\d{6}_\d{6})$/;
    my @t = localtime(time);
    my $offset_in_seconds = timegm(@t) - timelocal(@t);
    my $date = Time::Piece->strptime($tag, "%y%m%d_%H%M%S") or die "Cannot parse time tag";
    return $date->epoch() - $offset_in_seconds;
}

#
# Download stats file from the svc node.
#
sub downloadFile {
    my $node = $_[0];
    
    # get last stat filename time tag.
    my @lines = `ssh $svc_user\@$svc_host lsdumps -nohdr -delim : -prefix /dumps/iostats $node` or die "Cannot get file list";
    my $timetag = ( sort map { $1 if /(\d{6}_\d{6}$)/ } @lines )[-1];
    die "Cannot get last available timetag" unless $timetag;
    
    # stat file list to download (vdisks, node and mdisks)
    @statFiles = grep { /^Nv_stats_\d{6}_$timetag/ } map { $1 if /^\d+:(.*)$/ } @lines;
    die "Cannot get stat 1 fileNames" unless scalar @statFiles == 1;

    # download files
    foreach my $fileName(@statFiles) {
        system("scp -q $svc_user\@$node:/dumps/iostats/$fileName $tmpDir") == 0 or die "cannot download $fileName";
    }
}

#
# Parse svc vdisk stats 
# http://www-01.ibm.com/support/docview.wss?uid=ssg1S1003597
#
sub getVdiskStats {
    my $svc = $_[0];
    my $fileName = ( grep { /^Nv/ } @statFiles )[0];
    my $epoch = tag2epoc($fileName);
    
    my $idx = undef;
    open(FILE, "$tmpDir/$fileName") or die "Cannot open file";
    while (<FILE>) {
        if (/<vdsk idx="(\d+)"/) {
            $idx = $1;
            $vdisks{$svc}{$idx} = ();
        }
        if (/ro="(\d+)" wo="(\d+)" rb="(\d+)" wb="(\d+)"/ and ( $idx or $idx == 0 )) {
            $vdisks{$svc}{$idx}{'ro'} = $1 / $step;        # want per second stat
            $vdisks{$svc}{$idx}{'wo'} = $2 / $step;
            $vdisks{$svc}{$idx}{'rb'} = $3 * 512 / $step;  # want byte, stat value is in 512 byte block
            $vdisks{$svc}{$idx}{'wb'} = $4 * 512 / $step;
        }
        if (/^rl="(\d+)" wl="(\d+)" rlw="(\d+)" wlw="(\d+)" xl="(\d+)"/ and ( $idx or $idx == 0 )) {
            $vdisks{$svc}{$idx}{'rl'} = $vdisks{$svc}{$idx}{'ro'} ? $1 / $vdisks{$svc}{$idx}{'ro'} * $step : $1; # prevent division by zero
            $vdisks{$svc}{$idx}{'wl'} = $vdisks{$svc}{$idx}{'wo'} ? $2 / $vdisks{$svc}{$idx}{'wo'} * $step : $2;
            $vdisks{$svc}{$idx}{'rlw'} = $3 / 1000;    # microsecond, want milisecond
            $vdisks{$svc}{$idx}{'wlw'} = $4 / 1000;
        }
        $vdisks{$svc}{$idx}{'name'} = $1 if /^id="([\w-]+)/ and ( $idx or $idx == 0 );
    }
    close(FILE);
    unlink("$tmpDir/$fileName");
    
    # populate buf with graphite format
    foreach (keys %{$vdisks{$svc}}) {
        my %v = %{$vdisks{$svc}{$_}};
        foreach my $stat (keys %v) {
            next if $stat eq "name";
            my $line = "svc.vdisk.$svc.$v{'name'}.$stat $v{$stat} $epoch\n";
            push(@buf, $line);
        }
   }
}

#
#  wait for next stat availaible
#
sub waitStep {
    $wallClock = time() unless $wallClock;
    while(1) {
        sleep(1);
        if (time() - $wallClock > $step) {
            $wallClock = time();
            return 0;
        }
    }
}

#
# send stat to graphite
#
sub sendStat {
    my $sock = new IO::Socket::INET (
        PeerAddr => $graphite_host,
        PeerPort => $graphite_port,
        Proto => 'tcp'
    );
    if ($sock) {
        print $sock @buf;
        close($sock);
    } else {
        print @buf;
    }
    @buf = ();
}

#
# Make this script a Daemon
#
sub daemonize {
    POSIX::setsid or die "setsid: $!";
    my $pid = fork();
    if ($pid < 0) {
        die "fork: $!";
    } elsif ($pid) {
        print "Daemonize: $pid\n";
        exit 0;
    }
    chdir "/";
    umask 0;
    foreach (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024)) {
        POSIX::close $_
    }
    open(STDIN, "</dev/null");
    open(STDOUT, ">/dev/null");
    open(STDERR, ">&STDOUT");
 }

#
# Main
#
my $daemon = '';
GetOptions(( 'daemon' => \$daemon ));
daemonize() if $daemon;

while(1) {
    foreach my $node (@nodes) {
        downloadFile($node);
        getVdiskStats($node);
        sendStat();
    }
    waitStep;
}
aix/graphite_aix.txt · Last modified: 2021/01/01 21:21 (external edit)