文件操作 - pmlogconf
返回文件管理
返回主菜单
删除本文件
文件: /usr/bin/pmlogconf
编辑文件内容
#!/bin/sh # # pmlogconf - generate/edit a pmlogger configuration file # # control lines have this format # #+ tag:on-off:delta # where # tag is arbitrary (no embedded :'s) and unique # on-off y or n to enable or disable this group, else # x for groups excluded by probing from pmlogconf-setup # when the group was added to the configuration file # delta delta argument for pmlogger "logging ... on delta" clause # # Copyright (c) 2014,2016,2017 Red Hat. # Copyright (c) 1998,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. # # Get standard environment . $PCP_DIR/etc/pcp.env # Clear this part to ensure many short-lived pmprobe children # don't waste time analyzing derived metrics. PCP_DERIVED_CONFIG= export PCP_DERIVED_CONFIG status=1 tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1 trap "rm -rf $tmp; exit \$status" 0 1 2 3 15 #debug# tmp=`pwd`/tmp prog=`basename $0` cat > $tmp/usage << EOF # Usage: [options] configfile Options: -c add message and timestamp (not for interactive use) -d=DIR,--groups=DIR specify path to the pmlogconf groups directory --host -q,--quiet quiet, suppress logging interval dialog -r,--reprobe every group reconsidered for inclusion in configfile -v,--verbose increase diagnostic verbosity --help EOF _usage() { pmgetopt --progname=$prog --config=$tmp/usage --usage exit } # Setup the $tmp/pmprobe.out file for use _setup() { rm -f $tmp/pmprobe.out $tmp/pmprobe.in $tmp/pmprobe find $BASE -type f \ | sed \ -e '/\/v1.0\//d' \ | LC_COLLATE=POSIX sort \ | while read tag do if sed 1q <"$tag" | grep '^#pmlogconf-setup 2.0' >/dev/null then : else # not one of our group files, skip it ... continue fi grep "^probe" $tag | $PCP_AWK_PROG '{ print $2 }' >>$tmp/pmprobe.in done sort -u $tmp/pmprobe.in > $tmp/pmprobe [ -z "$HOST" ] && HOST=local: pmprobe -F -h $HOST -v `cat $tmp/pmprobe` >> $tmp/pmprobe.out } quick=false pat='' prompt=true reprobe=false autocreate=false BASE='' HOST='' verbose=false setupflags='' ARGS=`pmgetopt --progname=$prog --config=$tmp/usage -- "$@"` [ $? != 0 ] && exit 1 eval set -- "$ARGS" while [ $# -gt 0 ] do case "$1" in -c) # automated, non-interactive file creation autocreate=true prompt=false ;; -d) # base directory for the group files BASE="$2" shift ;; -h) # host to contact for "probe" tests HOST="$2" shift ;; -q) # "quick" mode, don't change logging intervals quick=true ;; -r) # reprobe reprobe=true ;; -v) # verbose verbose=true setupflags="$setupflags -v" ;; --) # end options shift break ;; -\?) _usage ;; esac shift done [ $# -eq 1 ] || _usage if [ -n "$BASE" -a ! -d "$BASE" ] then echo "$prog: Error: base directory ($BASE) for group files does not exist" exit fi config="$1" # split $tmp/ctl at the line containing the unprocessed tag to # produce # $tmp/head # $tmp/tag - one line # $tmp/tail # _split() { rm -f $tmp/head $tmp/tag $tmp/tail $PCP_AWK_PROG <$tmp/ctl ' BEGIN { out = "'"$tmp/head"'" } /DO NOT UPDATE THE FILE ABOVE/ { seen = 1 } seen == 0 && /^\#\? [^:]*:[ynx]:/ { print >"'"$tmp/tag"'" out = "'"$tmp/tail"'" seen = 1 next } { print >out }' } # do all of the real iterative work # _update() { # strip the existing pmlogger config and leave the comments # and the control lines # $PCP_AWK_PROG <$tmp/in >$tmp/ctl ' /DO NOT UPDATE THE FILE ABOVE/ { tail = 1 } tail == 1 { print; next } /^\#\+ [^:]*:[ynx]:/ { sub(/\+/, "?", $1); print; skip = 1; next } skip == 1 && /^\#----/ { skip = 0; next } skip == 1 { next } { print }' # now need to be a little smarter ... tags may have appeared or # disappeared from the shipped defaults, so need to munge the contents # of $tmp/ctl to reflect this # find $BASE -type f \ | sed \ -e "s;$BASE/;;" \ -e '/^v1.0\//d' \ | LC_COLLATE=POSIX sort \ | while read tag do if sed 1q <$BASE/"$tag" | grep '^#pmlogconf-setup 2.0' >/dev/null then : else # not one of our group files, skip it ... continue fi if grep "^#? $tag:" $tmp/ctl >/dev/null then : else $verbose && echo "need to add new group tag=$tag" rm -f $tmp/pre $tmp/post $PCP_AWK_PROG <$tmp/ctl ' BEGIN { out = "'"$tmp/pre"'" } /DO NOT UPDATE THE FILE ABOVE/ { out = "'"$tmp/post"'" } { print >out }' mv $tmp/pre $tmp/ctl [ -z "$HOST" ] && HOST=local: if $PCP_BINADM_DIR/pmlogconf-setup -h $HOST -t $tmp/pmprobe.out $setupflags $BASE/"$tag" 2>$tmp/err >$tmp/out then : else echo >&2 "$prog: Warning: $BASE/$tag: pmlogconf-setup failed" sts=1 fi sed -e "s;$BASE/;;" <$tmp/out >$tmp/tmp [ -s $tmp/err ] && cat $tmp/err sed -e '/^#+/s/+/?/' <$tmp/tmp >>$tmp/ctl [ -s $tmp/post ] && cat $tmp/post >>$tmp/ctl fi done while true do _split [ ! -s $tmp/tag ] && break eval `sed <$tmp/tag -e 's/^#? /tag="/' -e 's/:/" onoff="/' -e 's/:/" delta="/' -e 's/:.*/"/'` if [ ! -f $BASE/"$tag" ] then # the tag file has gone away ... # if $autocreate then echo >&2 "$prog: Warning: cannot find group file ($tag): deleting obsolete group" cat $tmp/head $tmp/tail >$tmp/ctl continue fi fi [ -z "$delta" ] && delta=default if $reprobe then [ -z "$HOST" ] && HOST=local: if $PCP_BINADM_DIR/pmlogconf-setup -h $HOST -t $tmp/pmprobe.out $setupflags $BASE/"$tag" 2>$tmp/err >$tmp/out then : else echo >&2 "$prog: Warning: $BASE/$tag: pmlogconf-setup failed" sts=1 fi sed -e "s;$BASE/;;" <$tmp/out >$tmp/tmp [ -s $tmp/err ] && cat $tmp/err if [ -s $tmp/tmp ] then eval `sed <$tmp/tmp -e 's/^#+ /tag_r="/' -e 's/:/" onoff_r="/' -e 's/:/" delta_r="/' -e 's/:.*/"/'` [ -z "$delta_r" ] && delta_r=default if [ "$tag" != "$tag_r" ] then echo >&2 "Botch: reprobe for $tag found new tag ${tag_r}, no change" cat $tmp/tmp else if [ "$onoff" = y ] then # existing y takes precedence if [ "$onoff_r" = x ] then echo >&2 "Warning: reprobe for $tag suggests exclude, keeping current include status" fi else onoff=$onoff_r [ "$delta" != "default" ] && delta=$delta_r fi fi fi fi case $onoff in y|n) ;; x) # excluded group from setup cat $tmp/head >$tmp/ctl echo "#+ $tag:x::" >>$tmp/ctl echo "#----" >>$tmp/ctl cat $tmp/tail >>$tmp/ctl continue ;; *) echo >&2 "Warning: tag=$tag onoff is illegal ($onoff) ... setting to \"n\"" onoff=n ;; esac if [ -f $BASE/$tag ] then eval `$PCP_AWK_PROG <$BASE/$tag ' BEGIN { desc = ""; metrics = "" } $1 == "ident" { if (desc != "") desc = desc "\n" for (i = 2; i <= NF; i++) { if (i == 2) desc = desc $2 else desc = desc " " $i } next } END { printf "desc='"'"'%s'"'"'\n",desc }'` sed -n <$BASE/$tag >$tmp/metrics \ -e '/^[ ]/s/[ ]*//p' #debug# echo $tag: #debug# echo "desc: $desc" else case "$tag" in v1.0/*) # from migration, silently do nothing ;; *) echo >&2 "Warning: cannot find group file ($tag): no change is possible" ;; esac $PCP_AWK_PROG <"$config" >>$tmp/head ' BEGIN { tag="'"$tag"'" } $1 == "#+" && $2 ~ tag { want = 1 } want == 1 { print } want == 1 && /^#----/ { exit }' cat $tmp/head $tmp/tail >$tmp/ctl continue fi if [ ! -z "$pat" ] then if echo "$desc" | grep "$pat" >/dev/null then pat='' prompt=true fi if grep "$pat" $tmp/metrics >/dev/null then pat='' prompt=true fi fi if $prompt then # prompt for answers # echo was_onoff=$onoff echo "Group: $desc" \ | if [ "$PCP_PLATFORM" = netbsd ] then fmt -g 74 -m 75 else fmt -w 74 fi \ | sed -e '1!s/^/ /' while true do $PCP_ECHO_PROG $PCP_ECHO_N "Log this group? [$onoff] ""$PCP_ECHO_C" read ans if [ "$ans" = "?" ] then echo 'Valid responses are: m report the names of the metrics in this group n do not log this group q quit; no change for this or any of the following groups y log this group /pattern no change for this group and search for a group containing pattern in the description or the metrics associated with the group' continue fi if [ "$ans" = m ] then echo "Metrics in this group ($tag):" sed -e 's/^/ /' $tmp/metrics continue fi if [ "$ans" = q ] then # quit ... ans="$onoff" prompt=false fi pat=`echo "$ans" | sed -n 's/^\///p'` if [ ! -z "$pat" ] then echo "Searching for \"$pat\"" ans="$onoff" prompt=false fi [ -z "$ans" ] && ans="$onoff" [ "$ans" = y -o "$ans" = n ] && break echo "Error: you must answer \"m\" or \"n\" or \"q\" or \"y\" or \"/pattern\" ... try again" done onoff="$ans" if [ $prompt = true -a "$onoff" = y ] then if $quick then if [ $was_onoff = y ] then # no change, be quiet : else echo "Logging interval: $delta" fi else while true do $PCP_ECHO_PROG $PCP_ECHO_N "Logging interval? [$delta] ""$PCP_ECHO_C" read ans if [ -z "$ans" ] then # use suggested value, assume this is good # ans="$delta" break else # do some sanity checking ... # ok=`echo "$ans" \ | sed -e 's/^every //' \ | $PCP_AWK_PROG ' /^once$/ { print "true"; exit } /^default$/ { print "true"; exit } /^[0-9][0-9]* *msec$/ { print "true"; exit } /^[0-9][0-9]* *msecs$/ { print "true"; exit } /^[0-9][0-9]* *millisecond$/ { print "true"; exit } /^[0-9][0-9]* *milliseconds$/ { print "true"; exit } /^[0-9][0-9]* *sec$/ { print "true"; exit } /^[0-9][0-9]* *secs$/ { print "true"; exit } /^[0-9][0-9]* *second$/ { print "true"; exit } /^[0-9][0-9]* *seconds$/ { print "true"; exit } /^[0-9][0-9]* *min$/ { print "true"; exit } /^[0-9][0-9]* *mins$/ { print "true"; exit } /^[0-9][0-9]* *minute$/ { print "true"; exit } /^[0-9][0-9]* *minutes$/ { print "true"; exit } /^[0-9][0-9]* *hour$/ { print "true"; exit } /^[0-9][0-9]* *hours$/ { print "true"; exit } { print "false"; exit }'` if $ok then delta="$ans" break else echo "Error: logging interval must be of the form \"once\" or \"default\" or" echo "\"<integer> <scale>\", where <scale> is one of \"sec\", \"secs\", \"min\"," echo "\"mins\", etc ... try again" fi fi done fi fi else $PCP_ECHO_PROG $PCP_ECHO_N ".""$PCP_ECHO_C" fi echo "#+ $tag:$onoff:$delta:" >>$tmp/head echo "$desc" | fmt | sed -e 's/^/## /' >>$tmp/head if [ "$onoff" = y ] then if [ -s $tmp/metrics ] then echo "log advisory on $delta {" >>$tmp/head sed -e 's/^/ /' <$tmp/metrics >>$tmp/head echo "}" >>$tmp/head fi fi echo "#----" >>$tmp/head cat $tmp/head $tmp/tail >$tmp/ctl done } if $autocreate || $reprobe then # Once-off check for pmcd connectivity, to avoid subsequent repeated # failures in pmlogconf-setup (which may take awhile, especially when # the environment is setup with slow/faraway PMCD timeout values). # PMCD="$HOST" [ -z "$PMCD" ] && PMCD=local: WAIT="-t 10" [ -z "$PMCD_WAIT_TIMEOUT" ] || WAIT="-t $PMCD_WAIT_TIMEOUT" if $PCP_BINADM_DIR/pmcd_wait -h "$PMCD" $WAIT -v 2>$tmp/err then : else sed -e "s/pmcd_wait/$prog/g" < $tmp/err exit fi fi if [ ! -s "$config" ] then # create a new config file # touch "$config" if [ ! -f "$config" ] then echo "$prog: Error: config file \"$config\" does not exist and cannot be created" exit fi $PCP_ECHO_PROG "Creating config file \"$config\" using default settings ..." prompt=false new=true [ -z "$HOST" ] && HOST=local: [ -z "$BASE" ] && BASE=$PCP_VAR_DIR/config/pmlogconf _setup cat <<End-of-File >$tmp/in #pmlogconf 2.0 # # pmlogger(1) config file created and updated by pmlogconf End-of-File $autocreate && echo "# Auto-generated by pmlogconf on: "`date` >>$tmp/in cat <<End-of-File >>$tmp/in # # DO NOT UPDATE THE INITIAL SECTION OF THIS FILE. # Any changes may be lost the next time pmlogconf is used # on this file. # #+ groupdir $BASE # End-of-File find $BASE -type f \ | sed \ -e '/\/v1.0\//d' \ | LC_COLLATE=POSIX sort \ | while read tag do if sed 1q <"$tag" | grep '^#pmlogconf-setup 2.0' >/dev/null then : else # not one of our group files, skip it ... continue fi if $PCP_BINADM_DIR/pmlogconf-setup -h $HOST -t $tmp/pmprobe.out $setupflags "$tag" 2>$tmp/err >$tmp/out then : else echo >&2 "$prog: Warning: $BASE/$tag: pmlogconf-setup failed" [ -s $tmp/err ] && cat $tmp/err sts=1 fi sed -e "s;$BASE/;;" <$tmp/out >>$tmp/in [ -s $tmp/err ] && cat $tmp/err done cat <<End-of-File >>$tmp/in # DO NOT UPDATE THE FILE ABOVE THIS LINE # Otherwise any changes may be lost the next time pmlogconf is # used on this file. # # It is safe to make additions from here on ... # [access] disallow .* : all; disallow :* : all; allow local:* : enquire; End-of-File else # updating an existing config file # new=false magic=`sed 1q "$config"` if echo "$magic" | grep "^#pmlogconf" >/dev/null then version=`echo $magic | sed -e "s/^#pmlogconf//" -e 's/^ *//'` if [ "$version" = "1.0" ] then echo "$prog: migrating \"$config\" from version 1.0 to 2.0 ..." [ -z "$BASE" ] && BASE=$PCP_VAR_DIR/config/pmlogconf sed <"$config" >$tmp/in \ -e '1s/1\.0/2.0/' \ -e "/# on this file./a\\ #\\ #+ groupdir $BASE" \ -e '/^#\+/{ s; C0:; cpu/summary:; s; C1:; cpu/percpu:; s; C2:; v1.0/C2:; s; C3:; v1.0/C3:; s; D0:; disk/summary:; s; D1:; disk/percontroller:; s; D2:; disk/perdisk:; s; D3:; v1.0/D3:; s; F0:; filesystem/all:; s; F1:; filesystem/xfs-io-linux:; s; F2:; filesystem/xfs-all:; s; F3:; sgi/xlv-activity:; s; F4:; sgi/xlv-stripe-io:; s; F5:; sgi/efs:; s; F6:; sgi/xvm-ops:; s; F7:; sgi/xvm-stats:; s; F8:; sgi/xvm-all:; s; G1:; gfs2/gfs2-base:; s; G2:; gfs2/gfs2-all:; s; H0:; sgi/craylink:; s; H1:; sgi/hub:; s; H2:; sgi/cpu-evctr:; s; H3:; sgi/xbow:; s; I0:; platform/hinv:; s; K0:; v1.0/K0:; s; K1:; kernel/syscalls-irix:; s; K2:; kernel/syscalls-percpu-irix:; s; K3:; kernel/read-write-data:; s; K4:; kernel/interrupts-irix:; s; K5:; kernel/bufcache-activity:; s; K6:; kernel/bufcache-all:; s; K7:; kernel/vnodes:; s; K8:; kernel/inode-cache:; s; K9:; sgi/kaio:; s; Ka:; kernel/queues-irix:; s; M0:; memory/swap-activity:; s; M1:; memory/tlb-irix:; s; M2:; kernel/memory-irix:; s; M3:; memory/swap-all:; s; M4:; memory/swap-config:; s; M5:; sgi/node-memory:; s; M6:; sgi/numa:; s; M7:; sgi/numa-summary:; s; N0:; networking/interface-summary:; s; N1:; networking/interface-all:; s; N2:; networking/tcp-activity-irix:; s; N3:; networking/tcp-all:; s; N4:; networking/udp-packets-irix:; s; N5:; networking/udp-all:; s; N6:; networking/socket-irix:; s; N7:; networking/other-protocols:; s; N8:; networking/mbufs:; s; N9:; networking/multicast:; s; Na:; networking/streams:; s; S0:; v1.0/S0:; s; S1:; v1.0/S1:; s; S2:; networking/rpc:; }' reprobe=true elif [ "$version" = "2.0" ] then # start with existing config file # cp "$config" $tmp/in else echo "$prog: Error: existing config file \"$config\" is wrong version ($version)" exit fi else echo "$prog: Error: existing \"$config\" is not a $prog control file" exit fi if [ ! -w "$config" ] then echo "$prog: Error: existing config file \"$config\" is not writeable" exit fi [ -n "$HOST" -a ! $reprobe ] && echo >&2 "$prog: Warning: existing config file, -h $HOST will be ignored" CBASE=`sed -n -e '/^#+ groupdir /s///p' <$tmp/in` if [ -z "$BASE" ] then BASE="$CBASE" else if [ "$BASE" != "$CBASE" ] then echo >&2 "$prog: Warning: using base directory for group files from command line ($BASE) which is different from that in $config ($CBASE)" fi fi fi while true do _update [ -z "$pat" ] && break echo " not found." while true do $PCP_ECHO_PROG $PCP_ECHO_N "Continue searching from start of the file? [y] ""$PCP_ECHO_C" read ans [ -z "$ans" ] && ans=y [ "$ans" = y -o "$ans" = n ] && break echo "Error: you must answer \"y\" or \"n\" ... try again" done mv $tmp/ctl $tmp/in if [ "$ans" = n ] then pat='' prompt=true else echo "Searching for \"$pat\"" fi done if $new then echo cp $tmp/ctl "$config" else echo if diff "$config" $tmp/ctl >/dev/null then echo "No changes" else echo "Differences ..." ${DIFF-diff} -c "$config" $tmp/ctl while true do $PCP_ECHO_PROG $PCP_ECHO_N "Keep changes? [y] ""$PCP_ECHO_C" read ans [ -z "$ans" ] && ans=y [ "$ans" = y -o "$ans" = n ] && break echo "Error: you must answer \"y\" or \"n\" ... try again" done [ "$ans" = y ] && cp $tmp/ctl "$config" fi fi status=0 exit
修改文件时间
将文件时间修改为当前时间的前一年
删除文件