top_mysql_users 7 KB
Newer Older
1
#!/bin/bash
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#
# $Id: top_mysql_users 22 2005-04-11 17:21:15Z jerome $
# ----------------------------------------------------------------------
# AlternC - Web Hosting System
# Copyright (C) 2002 by the AlternC Development Team.
# http://alternc.org
# ----------------------------------------------------------------------
# Based on:
# Valentin Lacambre's web hosting softwares: http://altern.org/
# ----------------------------------------------------------------------
# LICENSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License (GPL)
# 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.
#
# To read the license please visit http://www.gnu.org/copyleft/gpl.html
# ----------------------------------------------------------------------
# Original Author of file: Jerome Moinet
# Purpose of file: Parse the mysql logs to give the n most active users
# ----------------------------------------------------------------------
#
30 31
echo "This script does not work with this AlternC version"
exit 1
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
PATH=""
PROG_NAME=top_mysql_users
PROG_VERSION=0.1.0
ALTERNC_ROOT=/var/alternc
ALTERNC_ETC=/etc/alternc
ALTERNC_LIB=/usr/lib/alternc
ALTERNC_CONF_FILE=$ALTERNC_ETC/local.sh
LOG_DIR=/var/log
LOG_FILE=$LOG_DIR/mysql.log
TMP_ROOT=$ALTERNC_ROOT/tmp
RES_FILE=$TMP_ROOT/$PROG_NAME.res.$$
LOCK_FILE=/var/run/$PROG_NAME
export TEXTDOMAIN=alternc-admintools
YES=yes
NO=no

# Be sure to use the right programs
# and be sure they are there
awk=/usr/bin/awk
grep=/bin/grep
cat=/bin/cat
zcat=/bin/zcat
head=/usr/bin/head
id=/usr/bin/id
sort=/usr/bin/sort
rm=/bin/rm
sed=/bin/sed
cut=/usr/bin/cut
tail=/usr/bin/tail
ls=/bin/ls
gettext=/usr/bin/gettext
printf=/usr/bin/printf
lockfileremove=/usr/bin/lockfile-remove
lockfilecreate=/usr/bin/lockfile-create
lockfiletouch=/usr/bin/lockfile-touch

# Must have gettext first to display error messages
[ -x "$gettext" ] || { echo "Cannot execute $gettext"; exit 1 ; }

for i in $awk $grep $cat $zcat $head $id $sort $rm $sed $cut $tail $ls $printf $lockfileremove $lockfilecreate $lockfiletouch
do
	[ -x "$i" ] || { echo "$($gettext "Unable to execute") ${i}."; exit 1 ; }
done


#-------------------------
78
set_messages()
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#-------------------------
{
	# Language-dependent messages
	# Uses gettext and mo files.
	# Don't change these messages, change the .po file instead.
	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.")
	NOT_FOUND_MSG=$($gettext "does not exist.")
	NON_NUM_MSG=$($gettext "The \"number\" argument must be a number.")
	NON_COMPATIBLE_MSG=$($gettext "The -n and -z options are not compatible.")
	NON_NUM_MSG_FOR_N=$($gettext "The -n option requieres a number as argument.")
	LOCKFILE_CREATION_FAILED=`$printf "$($gettext "%s is allready beeing executed.")" $PROG_NAME`
	NON_ROOT_MSG=$($gettext "You have to be root (uid 0) to execute this program.")
	HIT_RES_MSG=`$printf "$($gettext "Top %s mysql users, sorted by connexion number (using gzipped logs: %s):")" $NB_USERS $($gettext "$USE_GZ_LOGS")`
	MISSING_CONF_FILE=`$printf "$($gettext "Can't find %s. Are you sure AlterncC is properly installed?")" $ALTERNC_CONF_FILE`
	UNKNOWN_OPTION=$($gettext "Unknown %s option.")
}


#-------------------------
98
trap_EXIT()
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
#-------------------------
{
	# Does some cleaning
	$rm -f $RES_FILE
	$lockfileremove $LOCK_FILE
	exit
}
trap trap_EXIT INT KILL TERM QUIT ABRT STOP HUP


#-------------------------
# Main
#-------------------------
set_messages
# Must be root
[ "`$id -u`" != "0" ] && { echo $NON_ROOT_MSG ; exit 1 ; }

# Parse args
IS_N_PARAM=false
USE_GZ_LOGS="$NO"
N_PARAM=""
COMMAND=$cat
for ARG in "$@" ; do
	[ "$IS_N_PARAM" = "true" ] && { shift ; IS_N_PARAM=false ; continue ; }
	[ "`$printf "$ARG\n" | $cut -c1`" != "-" ] && [ "$IS_N_PARAM" = "false" ] &&  break

	case $ARG in
		-h | --help        ) echo $PROG_NAME version $PROG_VERSION ; $printf "$USAGE\n" ; exit ;;
		-v | --version     ) echo $PROG_NAME version $PROG_VERSION ; exit ;;
		-z | --use-gz-logs ) USE_GZ_LOGS="$YES" ;;
		-n | --number=*    ) 
			if [ "$ARG" != "-n" ] ; then
				N_PARAM=`echo $ARG | $cut -d"=" -f2`
			else
				N_PARAM=$2
				IS_N_PARAM=true
			fi
			[ `echo "$N_PARAM" | $grep -c [^0-9]` != 0 ] && { echo "$NON_NUM_MSG_FOR_N" ; exit 1 ; }
			COMMAND="$tail -n $N_PARAM"
			;;
		*) $printf "${UNKNOWN_OPTION}\n" $ARG ; exit 1 ;;
	esac
	shift
done

# -n and -z options are not compatible
[ "$USE_GZ_LOGS" = "$YES" ] && ! [ -z "$N_PARAM" ] && { echo $NON_COMPATIBLE_MSG ; exit 1 ; }
# Must have only 1 parameter
[ -z "$1" ] || [ "$#" -gt 1 ] && { $printf "$USAGE\n" ; exit 1 ; }
# Argument "number"  must be numeric
[ `echo "$1" | $grep -c [^0-9]` != 0 ] && { echo "$NON_NUM_MSG" ; exit 1 ; } || NB_USERS=$1
# These dirs/files must exist
[ -d "$LOG_DIR" ] || { echo "$LOG_DIR $NOT_FOUND_MSG" ; exit 1 ; }
[ -d "$TMP_ROOT" ] || { echo "$TMP_ROOT $NOT_FOUND_MSG" ; exit 1 ; }
[ -f "$LOG_FILE" ] || { echo "$LOG_FILE $NOT_FOUND_MSG" ; exit 1 ; }
# Have to get AlternC conf file :
[ -f "$ALTERNC_CONF_FILE" ] || { echo $MISSING_CONF_FILE ; exit 1 ; } && . $ALTERNC_CONF_FILE

# Prevents executing more than one shell at the same time
$lockfilecreate --retry 1 $LOCK_FILE
if [ $? != 0 ]
then
	echo $LOCKFILE_CREATION_FAILED
	exit 1
fi
$lockfiletouch $LOCK_FILE &
BADGER="$!"


# Does the stuff
set_messages
# Have to parse files one by one or else system wil go on knees
$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
for FILE in `$ls -1 $LOG_FILE.* | $grep -v "\.gz$"`; do
	[ "$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
done
if [ "$USE_GZ_LOGS" = "$YES" ] 
then
	for GZLOG in $LOG_FILE.*.gz
	do
		$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
	done
fi


# show results
echo $HIT_RES_MSG
$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


# cleanly exit and remove temp files
kill "${BADGER}"
trap_EXIT