| 1 | #!/bin/ksh |
|---|
| 2 | # |
|---|
| 3 | # $Id: top_mysql_users 22 2005-04-11 17:21:15Z jerome $ |
|---|
| 4 | # ---------------------------------------------------------------------- |
|---|
| 5 | # AlternC - Web Hosting System |
|---|
| 6 | # Copyright (C) 2002 by the AlternC Development Team. |
|---|
| 7 | # http://alternc.org |
|---|
| 8 | # ---------------------------------------------------------------------- |
|---|
| 9 | # Based on: |
|---|
| 10 | # Valentin Lacambre's web hosting softwares: http://altern.org/ |
|---|
| 11 | # ---------------------------------------------------------------------- |
|---|
| 12 | # LICENSE |
|---|
| 13 | # |
|---|
| 14 | # This program is free software; you can redistribute it and/or |
|---|
| 15 | # modify it under the terms of the GNU General Public License (GPL) |
|---|
| 16 | # as published by the Free Software Foundation; either version 2 |
|---|
| 17 | # of the License, or (at your option) any later version. |
|---|
| 18 | # |
|---|
| 19 | # This program is distributed in the hope that it will be useful, |
|---|
| 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 22 | # GNU General Public License for more details. |
|---|
| 23 | # |
|---|
| 24 | # To read the license please visit http://www.gnu.org/copyleft/gpl.html |
|---|
| 25 | # ---------------------------------------------------------------------- |
|---|
| 26 | # Original Author of file: Jerome Moinet |
|---|
| 27 | # Purpose of file: Parse the mysql logs to give the n most active users |
|---|
| 28 | # ---------------------------------------------------------------------- |
|---|
| 29 | # |
|---|
| 30 | PATH="" |
|---|
| 31 | PROG_NAME=top_mysql_users |
|---|
| 32 | PROG_VERSION=0.1.0 |
|---|
| 33 | ALTERNC_ROOT=/var/alternc |
|---|
| 34 | ALTERNC_ETC=/etc/alternc |
|---|
| 35 | ALTERNC_LIB=/usr/lib/alternc |
|---|
| 36 | ALTERNC_CONF_FILE=$ALTERNC_ETC/local.sh |
|---|
| 37 | LOG_DIR=/var/log |
|---|
| 38 | LOG_FILE=$LOG_DIR/mysql.log |
|---|
| 39 | TMP_ROOT=$ALTERNC_ROOT/tmp |
|---|
| 40 | RES_FILE=$TMP_ROOT/$PROG_NAME.res.$$ |
|---|
| 41 | LOCK_FILE=/var/run/$PROG_NAME |
|---|
| 42 | export TEXTDOMAIN=alternc-admintools |
|---|
| 43 | YES=yes |
|---|
| 44 | NO=no |
|---|
| 45 | |
|---|
| 46 | # Be sure to use the right programs |
|---|
| 47 | # and be sure they are there |
|---|
| 48 | awk=/usr/bin/awk |
|---|
| 49 | grep=/bin/grep |
|---|
| 50 | cat=/bin/cat |
|---|
| 51 | zcat=/bin/zcat |
|---|
| 52 | head=/usr/bin/head |
|---|
| 53 | id=/usr/bin/id |
|---|
| 54 | sort=/usr/bin/sort |
|---|
| 55 | rm=/bin/rm |
|---|
| 56 | sed=/bin/sed |
|---|
| 57 | cut=/usr/bin/cut |
|---|
| 58 | tail=/usr/bin/tail |
|---|
| 59 | ls=/bin/ls |
|---|
| 60 | gettext=/usr/bin/gettext |
|---|
| 61 | printf=/usr/bin/printf |
|---|
| 62 | lockfileremove=/usr/bin/lockfile-remove |
|---|
| 63 | lockfilecreate=/usr/bin/lockfile-create |
|---|
| 64 | lockfiletouch=/usr/bin/lockfile-touch |
|---|
| 65 | |
|---|
| 66 | # Must have gettext first to display error messages |
|---|
| 67 | [ -x "$gettext" ] || { echo "Cannot execute $gettext"; exit 1 ; } |
|---|
| 68 | |
|---|
| 69 | for i in $awk $grep $cat $zcat $head $id $sort $rm $sed $cut $tail $ls $printf $lockfileremove $lockfilecreate $lockfiletouch |
|---|
| 70 | do |
|---|
| 71 | [ -x "$i" ] || { echo "$($gettext "Unable to execute") ${i}."; exit 1 ; } |
|---|
| 72 | done |
|---|
| 73 | |
|---|
| 74 | |
|---|
| 75 | #------------------------- |
|---|
| 76 | set_messages |
|---|
| 77 | #------------------------- |
|---|
| 78 | { |
|---|
| 79 | # Language-dependent messages |
|---|
| 80 | # Uses gettext and mo files. |
|---|
| 81 | # Don't change these messages, change the .po file instead. |
|---|
| 82 | USAGE=$($gettext -e "Usage: top_mysql_users [ options ] number\n\ntop_mysql_users is a program that gives brief statistics\non mysql usage by parsing the mysql logs.\n\nOptions:\n -h, --help This help text.\n -v, --version Show version.\n -z, --use-gz-logs Parse gzipped and .1, ...n apache logs instead of just parsing the current log.\n -n, --number=NUMBER parse the NUMBER last lines of the current log.\n This option is not compatible with the --use-gz-logs option.\nSee the top_mysql_users(8) manual page for more information.") |
|---|
| 83 | NOT_FOUND_MSG=$($gettext "does not exist.") |
|---|
| 84 | NON_NUM_MSG=$($gettext "The \"number\" argument must be a number.") |
|---|
| 85 | NON_COMPATIBLE_MSG=$($gettext "The -n and -z options are not compatible.") |
|---|
| 86 | NON_NUM_MSG_FOR_N=$($gettext "The -n option requieres a number as argument.") |
|---|
| 87 | LOCKFILE_CREATION_FAILED=`$printf "$($gettext "%s is allready beeing executed.")" $PROG_NAME` |
|---|
| 88 | NON_ROOT_MSG=$($gettext "You have to be root (uid 0) to execute this program.") |
|---|
| 89 | HIT_RES_MSG=`$printf "$($gettext "Top %s mysql users, sorted by connexion number (using gzipped logs: %s):")" $NB_USERS $($gettext "$USE_GZ_LOGS")` |
|---|
| 90 | MISSING_CONF_FILE=`$printf "$($gettext "Can't find %s. Are you sure AlterncC is properly installed?")" $ALTERNC_CONF_FILE` |
|---|
| 91 | UNKNOWN_OPTION=$($gettext "Unknown %s option.") |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | #------------------------- |
|---|
| 96 | trap_EXIT |
|---|
| 97 | #------------------------- |
|---|
| 98 | { |
|---|
| 99 | # Does some cleaning |
|---|
| 100 | $rm -f $RES_FILE |
|---|
| 101 | $lockfileremove $LOCK_FILE |
|---|
| 102 | exit |
|---|
| 103 | } |
|---|
| 104 | trap trap_EXIT INT KILL TERM QUIT ABRT STOP HUP |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | #------------------------- |
|---|
| 108 | # Main |
|---|
| 109 | #------------------------- |
|---|
| 110 | set_messages |
|---|
| 111 | # Must be root |
|---|
| 112 | [ "`$id -u`" != "0" ] && { echo $NON_ROOT_MSG ; exit 1 ; } |
|---|
| 113 | |
|---|
| 114 | # Parse args |
|---|
| 115 | IS_N_PARAM=false |
|---|
| 116 | USE_GZ_LOGS="$NO" |
|---|
| 117 | N_PARAM="" |
|---|
| 118 | COMMAND=$cat |
|---|
| 119 | for ARG in "$@" ; do |
|---|
| 120 | [ "$IS_N_PARAM" = "true" ] && { shift ; IS_N_PARAM=false ; continue ; } |
|---|
| 121 | [ "`$printf "$ARG\n" | $cut -c1`" != "-" ] && [ "$IS_N_PARAM" = "false" ] && break |
|---|
| 122 | |
|---|
| 123 | case $ARG in |
|---|
| 124 | -h | --help ) echo $PROG_NAME version $PROG_VERSION ; $printf "$USAGE\n" ; exit ;; |
|---|
| 125 | -v | --version ) echo $PROG_NAME version $PROG_VERSION ; exit ;; |
|---|
| 126 | -z | --use-gz-logs ) USE_GZ_LOGS="$YES" ;; |
|---|
| 127 | -n | --number=* ) |
|---|
| 128 | if [ "$ARG" != "-n" ] ; then |
|---|
| 129 | N_PARAM=`echo $ARG | $cut -d"=" -f2` |
|---|
| 130 | else |
|---|
| 131 | N_PARAM=$2 |
|---|
| 132 | IS_N_PARAM=true |
|---|
| 133 | fi |
|---|
| 134 | [ `echo "$N_PARAM" | $grep -c [^0-9]` != 0 ] && { echo "$NON_NUM_MSG_FOR_N" ; exit 1 ; } |
|---|
| 135 | COMMAND="$tail -n $N_PARAM" |
|---|
| 136 | ;; |
|---|
| 137 | *) $printf "${UNKNOWN_OPTION}\n" $ARG ; exit 1 ;; |
|---|
| 138 | esac |
|---|
| 139 | shift |
|---|
| 140 | done |
|---|
| 141 | |
|---|
| 142 | # -n and -z options are not compatible |
|---|
| 143 | [ "$USE_GZ_LOGS" = "$YES" ] && ! [ -z "$N_PARAM" ] && { echo $NON_COMPATIBLE_MSG ; exit 1 ; } |
|---|
| 144 | # Must have only 1 parameter |
|---|
| 145 | [ -z "$1" ] || [ "$#" -gt 1 ] && { $printf "$USAGE\n" ; exit 1 ; } |
|---|
| 146 | # Argument "number" must be numeric |
|---|
| 147 | [ `echo "$1" | $grep -c [^0-9]` != 0 ] && { echo "$NON_NUM_MSG" ; exit 1 ; } || NB_USERS=$1 |
|---|
| 148 | # These dirs/files must exist |
|---|
| 149 | [ -d "$LOG_DIR" ] || { echo "$LOG_DIR $NOT_FOUND_MSG" ; exit 1 ; } |
|---|
| 150 | [ -d "$TMP_ROOT" ] || { echo "$TMP_ROOT $NOT_FOUND_MSG" ; exit 1 ; } |
|---|
| 151 | [ -f "$LOG_FILE" ] || { echo "$LOG_FILE $NOT_FOUND_MSG" ; exit 1 ; } |
|---|
| 152 | # Have to get AlternC conf file : |
|---|
| 153 | [ -f "$ALTERNC_CONF_FILE" ] || { echo $MISSING_CONF_FILE ; exit 1 ; } && . $ALTERNC_CONF_FILE |
|---|
| 154 | |
|---|
| 155 | # Prevents executing more than one shell at the same time |
|---|
| 156 | $lockfilecreate --retry 1 $LOCK_FILE |
|---|
| 157 | if [ $? != 0 ] |
|---|
| 158 | then |
|---|
| 159 | echo $LOCKFILE_CREATION_FAILED |
|---|
| 160 | exit 1 |
|---|
| 161 | fi |
|---|
| 162 | $lockfiletouch $LOCK_FILE & |
|---|
| 163 | BADGER="$!" |
|---|
| 164 | |
|---|
| 165 | |
|---|
| 166 | # Does the stuff |
|---|
| 167 | set_messages |
|---|
| 168 | # Have to parse files one by one or else system wil go on knees |
|---|
| 169 | $COMMAND $LOG_FILE | $grep " Connect " | $awk -F "@" '{z=split($1, a, " ") ; account[a[z]]++} END {for (item in account) print item" "account[item]}' > $RES_FILE |
|---|
| 170 | for FILE in `$ls -1 $LOG_FILE.* | $grep -v "\.gz$"`; do |
|---|
| 171 | [ "$USE_GZ_LOGS" = "$YES" ] && [ -f $FILE ] && $cat $FILE | $grep " Connect " | $awk -F "@" '{z=split($1, a, " ") ; account[a[z]]++} END {for (item in account) print item" "account[item]}' >> $RES_FILE |
|---|
| 172 | done |
|---|
| 173 | if [ "$USE_GZ_LOGS" = "$YES" ] |
|---|
| 174 | then |
|---|
| 175 | for GZLOG in $LOG_FILE.*.gz |
|---|
| 176 | do |
|---|
| 177 | $zcat $GZLOG | $grep -e " Connect " | $awk -F "@" '{z=split($1, a, " ") ; account[a[z]]++} END {for (item in account) print item" "account[item]}' >> $RES_FILE |
|---|
| 178 | done |
|---|
| 179 | fi |
|---|
| 180 | |
|---|
| 181 | |
|---|
| 182 | # show results |
|---|
| 183 | echo $HIT_RES_MSG |
|---|
| 184 | $cat $RES_FILE | $awk '{account[$1]+=$2} END {for (item in account) print item" "account[item]}' | $awk {'printf ("%20.0f %s\n", $2, $1)'} | $sort -gr | $head -n$NB_USERS |
|---|
| 185 | |
|---|
| 186 | |
|---|
| 187 | # cleanly exit and remove temp files |
|---|
| 188 | kill "${BADGER}" |
|---|
| 189 | trap_EXIT |
|---|
| 190 | |
|---|
| 191 | |
|---|