summaryrefslogtreecommitdiff
path: root/src/pcp/pcp.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/pcp/pcp.sh')
-rwxr-xr-xsrc/pcp/pcp.sh521
1 files changed, 521 insertions, 0 deletions
diff --git a/src/pcp/pcp.sh b/src/pcp/pcp.sh
new file mode 100755
index 0000000..33ddb47
--- /dev/null
+++ b/src/pcp/pcp.sh
@@ -0,0 +1,521 @@
+#! /bin/sh
+#
+# Copyright (c) 2013-2014 Red Hat.
+# Copyright (c) 1997,2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# Displays the Performance Co-Pilot configuration for a host running the
+# pmcd(1) daemon or from an archive created by pmlogger(1).
+#
+
+. $PCP_DIR/etc/pcp.env
+
+sts=2
+tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1
+trap "rm -rf $tmp; exit \$sts" 0 1 2 3 15
+
+errors=0
+progname=`basename $0`
+pcp_host=`hostname` # may match pmcd.hostname
+for var in unknown version build numagents numclients ncpu ndisk nnode nrouter nxbow ncell mem cputype uname timezone hostname services status
+do
+ eval $var="unknown?"
+done
+for var in Aflag aflag Dflag gflag hflag Lflag nflag Oflag Pflag pflag Sflag sflag Tflag tflag Zflag zflag
+do
+ eval $var=false
+done
+
+# metrics
+metrics="pmcd.numagents pmcd.numclients pmcd.version pmcd.build pmcd.timezone pmcd.hostname pmcd.services pmcd.agent.status pmcd.pmlogger.archive pmcd.pmlogger.pmcd_host hinv.ncpu hinv.ndisk hinv.nnode hinv.nrouter hinv.nxbow hinv.ncell hinv.physmem hinv.cputype pmda.uname pmcd.pmie.pmcd_host pmcd.pmie.configfile pmcd.pmie.numrules pmcd.pmie.logfile"
+pmiemetrics="pmcd.pmie.actions pmcd.pmie.eval.true pmcd.pmie.eval.false pmcd.pmie.eval.unknown pmcd.pmie.eval.expected"
+
+# usage spec for pmgetopt, note posix flag (commands mean no reordering)
+cat > $tmp/usage << EOF
+# getopts: A:a:D:gh:Ln:O:p:PS:s:T:t:Z:z?
+# Usage: [options] [[...] command [...]]
+
+Summary Options:
+ --archive
+ --host
+ --namespace
+ -P,--pmie display pmie evaluation statistics
+ --help
+
+Command Options:
+ --align
+ --archive
+ --debug
+ --guimode
+ --host
+ --namespace
+ --origin
+ --guiport
+ --start
+ --samples
+ --finish
+ --interval
+ --timezone
+ --hostzone
+# end
+EOF
+
+_usage()
+{
+ [ ! -z "$@" ] && echo $@ 1>&2
+
+ ls $PCP_BINADM_DIR/pcp-* $HOME/.pcp/bin/pcp-* 2>/dev/null | \
+ while read command
+ do
+ [ -x "$command" ] || continue
+ basename "$command" | sed -e 's/^pcp-//g' >> $tmp/cmds
+ done
+
+ echo >> $tmp/usage
+ ( $PCP_ECHO_PROG $PCP_ECHO_N "Available Commands: ""$PCP_ECHO_C" && \
+ sort -u < $tmp/cmds ) | _fmt >> $tmp/usage
+ pmgetopt --progname=$progname --usage --config=$tmp/usage
+ exit 1
+}
+
+_plural()
+{
+ if [ "$1" = $unknown -o "$1" = 0 ]
+ then
+ echo ""
+ elif [ "$1" = 1 ]
+ then
+ echo " $1 $2,"
+ else
+ echo " $1 ${2}s,"
+ fi
+}
+
+_fmt()
+{
+ if [ "$PCP_PLATFORM" = netbsd ]
+ then
+ fmt -g 64
+ else
+ fmt -w 64
+ fi \
+ | tr -d '\r' | tr -s '\n' | $PCP_AWK_PROG '
+NR > 1 { printf " %s\n", $0; next }
+ { print }'
+}
+
+opts=""
+ARGS=`pmgetopt --progname=$progname --config=$tmp/usage -- "$@"`
+[ $? != 0 ] && exit 1
+
+eval set -- "$ARGS"
+while [ $# -gt 0 ]
+do
+ case "$1" in
+ -A)
+ Aflag=true
+ pcp_align_time="$2"
+ shift
+ ;;
+ -a)
+ aflag=true
+ pcp_archive="$2"
+ opts="$opts -a $2"
+ shift
+ ;;
+ -D)
+ Dflag=true
+ pcp_debug="$2"
+ opts="$opts -D $2"
+ shift
+ ;;
+ -g)
+ gflag=true
+ ;;
+ -h)
+ hflag=true
+ pcp_host="$2"
+ opts="$opts -h $2"
+ shift
+ ;;
+ -L)
+ Lflag=true
+ ;;
+ -n)
+ nflag=true
+ pcp_namespace="$2"
+ opts="$opts -n $2"
+ shift
+ ;;
+ -O)
+ Oflag=true
+ pcp_origin_time="$2"
+ shift
+ ;;
+ -P)
+ Pflag=true
+ metrics="$metrics $pmiemetrics"
+ ;;
+ -p)
+ pflag=true
+ pcp_guiport="$2"
+ shift
+ ;;
+ -S)
+ Sflag=true
+ pcp_start_time="$2"
+ shift
+ ;;
+ -s)
+ sflag=true
+ pcp_samples="$2"
+ shift
+ ;;
+ -T)
+ Tflag=true
+ pcp_finish_time="$2"
+ shift
+ ;;
+ -t)
+ tflag=true
+ pcp_interval="$2"
+ shift
+ ;;
+ -Z)
+ Zflag=true
+ pcp_timezone="$2"
+ shift
+ ;;
+ -z)
+ zflag=true
+ ;;
+ -\?)
+ _usage ""
+ ;;
+ --) # end of options, start of arguments
+ shift
+ break
+ ;;
+ esac
+ shift # finished with this option now, next!
+done
+
+if [ $# -gt 0 ]
+then
+ # pcp-command mode - seek out a matching command and execute it
+ # with the remaining arguments - pmGetOptions(3) will discover
+ # all of the standard arguments we've set above, automagically.
+ #
+ command=$1
+ shift
+
+ if [ -x "$HOME/.pcp/bin/pcp-$command" ]
+ then
+ command="$HOME/.pcp/bin/pcp-$command"
+ elif [ -x "$PCP_BINADM_DIR/pcp-$command" ]
+ then
+ command="$PCP_BINADM_DIR/pcp-$command"
+ else
+ _usage "Cannot find a pcp-$command command to execute"
+ fi
+ $Aflag && export PCP_ALIGN_TIME="$pcp_align_time"
+ $aflag && export PCP_ARCHIVE="$pcp_archive"
+ $Dflag && export PCP_DEBUG="$pcp_debug"
+ $gflag && export PCP_GUIMODE=true
+ $hflag && export PCP_HOST="$pcp_host"
+ $Lflag && export PCP_LOCALMODE=true
+ $nflag && export PCP_NAMESPACE="$pcp_namespace"
+ $Oflag && export PCP_ORIGIN_TIME="$pcp_origin_time"
+ $pflag && export PCP_GUIPORT="$pcp_guiport"
+ $Sflag && export PCP_START_TIME="$pcp_start_time"
+ $sflag && export PCP_SAMPLES="$pcp_samples"
+ $Tflag && export PCP_FINISH_TIME="$pcp_finish_time"
+ $tflag && export PCP_INTERVAL="$pcp_interval"
+ $Zflag && export PCP_TIMEZONE="$pcp_timezone"
+ $zflag && export PCP_HOSTZONE=true
+ exec $command $@
+fi
+
+$hflag && $aflag && _usage "$progname: -a and -h mutually exclusive"
+
+if $aflag
+then
+ eval `pmdumplog -Lz "$pcp_archive" 2>/dev/null | $PCP_AWK_PROG '
+/^Performance metrics from host/ { printf "pcp_host=%s\n", $5 }
+/^Archive timezone: / { printf "timezone=%s\n", $3 }
+/^ commencing/ { tmp = substr($5, 7, 6)
+ sub(tmp, tmp+0.001, $5)
+ sub("commencing", "@")
+ printf "offset=\"%s\"\n", $0
+ }'`
+ [ "X$pcp_host" = X ] && pcp_host="unknown host"
+ [ "X$offset" != X ] && opts="$opts -O '$offset' -z"
+fi
+
+
+if eval pminfo $opts -f $metrics > $tmp/metrics 2>$tmp/err
+then
+ :
+else
+ if grep "^pminfo:" $tmp/err > /dev/null 2>&1
+ then
+ $PCP_ECHO_PROG $PCP_ECHO_N "$progname: ""$PCP_ECHO_C"
+ sed < $tmp/err -e 's/^pminfo: //g'
+ sts=1
+ exit
+ fi
+fi
+
+[ -s $tmp/err ] && sed -e '/Unknown metric name/d' <$tmp/err >&2
+
+eval `$PCP_AWK_PROG < $tmp/metrics -v out=$tmp '
+BEGIN { mode = 0; count = 0; errors = 0; quote="" }
+
+function quoted()
+{
+ if ($1 == "value") {
+ printf "%s=", quote
+ for (i = 2; i < NF; i++)
+ printf "%s ", $i
+ printf "%s\n", $NF
+ }
+ else
+ errors++
+}
+
+function inst()
+{
+ if (count == 0)
+ file=sprintf("%s/%s", out, quote)
+ if (NF == 0) {
+ mode = 0
+ printf "%s=%d\n", quote, count
+ }
+ else if ($1 == "inst") {
+ count++
+ id=substr($2, 2, length($2) - 1)
+ value=$6
+ if (mode == 2) {
+ agent=substr($4, 2, length($4) - 3)
+ printf "%s %s %s\n", id, agent, value > file
+ }
+ else
+ printf "%s %s\n", id, value > file
+ }
+ else {
+ printf "%s=%d\n", quote, 0
+ mode = 0
+ errors++
+ }
+}
+
+mode == 1 { quoted(); mode = 0; next }
+mode == 2 { inst(); next }
+mode == 3 { inst(); next }
+/pmcd.version/ { mode = 1; quote="version"; next }
+/pmcd.build/ { mode = 1; quote="build"; next }
+/pmcd.numagents/ { mode = 1; quote="numagents"; next }
+/pmcd.numclients/ { mode = 1; quote="numclients"; next }
+/pmcd.timezone/ { mode = 1; quote="timezone"; next }
+/pmcd.hostname/ { mode = 1; quote="hostname"; next }
+/pmcd.services/ { mode = 1; quote="services"; next }
+/pmcd.agent.status/ { mode = 2; count = 0; quote="status"; next }
+/pmcd.pmlogger.archive/ { mode = 3; count = 0; quote="log_archive"; next }
+/pmcd.pmlogger.pmcd_host/ { mode = 3; count = 0; quote="log_host"; next }
+/pmcd.pmie.pmcd_host/ { mode = 3; count = 0; quote="ie_host"; next }
+/pmcd.pmie.logfile/ { mode = 3; count = 0; quote="ie_log"; next }
+/pmcd.pmie.configfile/ { mode = 3; count = 0; quote="ie_config"; next }
+/pmcd.pmie.numrules/ { mode = 3; count = 0; quote="ie_numrules"; next }
+/pmcd.pmie.actions/ { mode = 3; count = 0; quote="ie_actions"; next }
+/pmcd.pmie.eval.true/ { mode = 3; count = 0; quote="ie_true"; next }
+/pmcd.pmie.eval.false/ { mode = 3; count = 0; quote="ie_false"; next }
+/pmcd.pmie.eval.unknown/ { mode = 3; count = 0; quote="ie_unknown"; next }
+/pmcd.pmie.eval.expected/ { mode = 3; count = 0; quote="ie_expected"; next }
+/hinv.ncpu/ { mode = 1; quote="ncpu"; next }
+/hinv.ndisk/ { mode = 1; quote="ndisk"; next }
+/hinv.nnode/ { mode = 1; quote="nnode"; next }
+/hinv.nrouter/ { mode = 1; quote="nrouter"; next }
+/hinv.nxbow/ { mode = 1; quote="nxbow"; next }
+/hinv.ncell/ { mode = 1; quote="ncell"; next }
+/hinv.physmem/ { mode = 1; quote="mem"; next }
+/hinv.cputype/ { mode = 3; count = 0; quote="cputype"; next }
+/pmda.uname/ { mode = 1; quote="uname"; next }
+END { printf "errors=%d\n", errors }'`
+
+numagents=`_plural $numagents agent`
+ndisk=`_plural $ndisk disk`
+nnode=`_plural $nnode node`
+nrouter=`_plural $nrouter router`
+nxbow=`_plural $nxbow xbow`
+ncell=`_plural $ncell cell`
+
+if [ -f $tmp/status ]
+then
+ agents=`$PCP_AWK_PROG < $tmp/status '
+$3 == 0 { printf "%s ",$2 }
+$3 != 0 { printf "%s[%d] ",$2,$3 }' | _fmt`
+fi
+
+if [ "$numclients" = $unknown ]
+then
+ numclients=""
+else
+ numclients=`expr $numclients - 1`
+ numclients=`_plural $numclients client | tr -d ','`
+ [ "$numclients" = "" ] && numagents=`echo "$numagents" | tr -d ','`
+fi
+
+if [ "$version" = $unknown ]
+then
+ version="Version unknown"
+else
+ version="Version $version"
+ [ "$build" != $unknown ] && version="$version-$build"
+fi
+
+if [ "$mem" = $unknown -o "$mem" = 0 ]
+then
+ mem=""
+else
+ mem=" ${mem}MB RAM"
+fi
+
+if [ "$uname" = $unknown ]
+then
+ uname=""
+else
+ uname="$uname"
+fi
+
+[ "$services" = $unknown ] && services=""
+[ "$timezone" = $unknown ] && timezone="Unknown"
+[ "$hostname" = $unknown ] || pcp_host="$hostname"
+
+if [ "$cputype" = $unknown ]
+then
+ cputype=""
+elif [ -f $tmp/cputype ]
+then
+ cputype=`head -1 $tmp/cputype | sed -e 's/^.*"R/R/' -e 's/"$//g'`
+else
+ cputype=""
+fi
+
+ncpu=`_plural $ncpu "$cputype cpu"`
+
+hardware="${ncpu}${ndisk}${nnode}${nrouter}${nxbow}${ncell}$mem"
+
+if [ -f $tmp/log_archive -a -f $tmp/log_host ]
+then
+ sort $tmp/log_archive -o $tmp/log_archive
+ sort $tmp/log_host -o $tmp/log_host
+
+ # need \n\n here to force line breaks when piped into fmt later
+ #
+ numloggers=`join $tmp/log_host $tmp/log_archive | sort \
+ | sed -e 's/"//g' | tee $tmp/log | $PCP_AWK_PROG '
+BEGIN { count = 0 }
+$1 == "0" { next }
+$1 == "1" { next }
+ { count++ }
+END { print count }'`
+
+ $PCP_AWK_PROG < $tmp/log > $tmp/loggers '
+BEGIN { primary=0 }
+$1 == "0" { primary=$3; next }
+$3 == primary { printf "primary logger: %s\n\n",$3; exit }'
+
+ $PCP_AWK_PROG < $tmp/log >> $tmp/loggers '
+BEGIN { primary=0 }
+$1 == "0" { primary=$3; next }
+$1 == "1" { next }
+$3 == primary { next }
+ { printf "%s: %s\n\n",$2,$3 }'
+else
+ numloggers=0
+fi
+
+if [ -f $tmp/ie_host -a -f $tmp/ie_config -a -f $tmp/ie_log -a -f $tmp/ie_numrules ]
+then
+ sort $tmp/ie_log -o $tmp/ie_log
+ sort $tmp/ie_host -o $tmp/ie_host
+ sort $tmp/ie_config -o $tmp/ie_config
+ sort $tmp/ie_numrules -o $tmp/ie_numrules
+ if [ $Pflag = "true" ]; then
+ numpmies=`join $tmp/ie_host $tmp/ie_config | join - $tmp/ie_numrules \
+ | sort -n | sed -e 's/"//g' | tee $tmp/pmie | wc -l | tr -d ' '`
+ else
+ numpmies=`join $tmp/ie_host $tmp/ie_log \
+ | sort -n | sed -e 's/"//g' | tee $tmp/pmie | wc -l | tr -d ' '`
+ fi
+
+ if [ $Pflag = "true" -a -f $tmp/ie_actions -a -f $tmp/ie_true -a \
+ -f $tmp/ie_false -a -f $tmp/ie_unknown -a -f $tmp/ie_expected ]
+ then
+ sort $tmp/ie_actions -o $tmp/ie_actions
+ sort $tmp/ie_true -o $tmp/ie_true
+ sort $tmp/ie_false -o $tmp/ie_false
+ sort $tmp/ie_unknown -o $tmp/ie_unknown
+ sort $tmp/ie_expected -o $tmp/ie_expected
+ join $tmp/pmie $tmp/ie_true | join - $tmp/ie_false \
+ | join - $tmp/ie_unknown | join - $tmp/ie_actions \
+ | join - $tmp/ie_expected > $tmp/tmp
+ mv $tmp/tmp $tmp/pmie
+ fi
+
+ $PCP_AWK_PROG -v Pflag=$Pflag < $tmp/pmie '{
+ if (Pflag == "true") {
+ printf "%s: %s (%u rules)\n\n",$2,$3,$4
+ printf "evaluations true=%u false=%u unknown=%u (actions=%u)\n\n",$5,$6,$7,$8
+ printf "expected evaluation rate=%.2f rules/sec\n\n",$9
+ } else {
+ printf "%s: %s\n\n",$2,$3
+ }
+ }' > $tmp/pmies
+else
+ numpmies=0
+fi
+
+# finally, display everything we've found...
+#
+echo "Performance Co-Pilot configuration on ${pcp_host}:"
+echo
+[ -n "$pcp_archive" ] && echo " archive: $pcp_archive"
+echo " platform: ${uname}"
+echo " hardware: "`echo $hardware | _fmt`
+echo " timezone: $timezone"
+[ -n "$services" ] && echo " services: $services"
+
+echo " pmcd: ${version},${numagents}$numclients"
+
+[ -n "$agents" ] && echo " pmda: $agents"
+
+if [ "$numloggers" != 0 ]
+then
+ $PCP_ECHO_PROG $PCP_ECHO_N " pmlogger: ""$PCP_ECHO_C"
+ LC_COLLATE=POSIX sort < $tmp/loggers \
+ | sed -e '/^$/d' | sed -e '1!s/^/ /'
+fi
+
+if [ "$numpmies" != 0 ]
+then
+ $PCP_ECHO_PROG $PCP_ECHO_N " pmie: ""$PCP_ECHO_C"
+ if [ $Pflag = "true" ]; then
+ _fmt < $tmp/pmies
+ else
+ LC_COLLATE=POSIX sort < $tmp/pmies \
+ | sed -e '/^$/d' | sed -e '1!s/^/ /'
+ fi
+fi
+
+sts=0
+exit