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
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
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
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; }