Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / apache / apache_users @ 8589c6df

Historique | Voir | Annoter | Télécharger (4,5 ko)

1 8054d81a Rainer Wolff
#!/bin/bash
2
#
3
# apache_users - Munin plugin, displays traffic by user
4
#
5
# Version: 03.06.2009
6
# Author: Rainer Wolff <rainer.wolff@gmx.com>
7
#
8
# ################################################################################ MAGIC MARKERS
9
10
#%# family=contrib
11
#%# capabilities=autoconf
12
13
# ####################################################################################### CONFIG
14
15
DIRECTORY=${MUNIN_PLUGINSTATE:-/var/lib/munin/plugin-state/apache_users}
16
TIMESTAMP=$DIRECTORY/.apache_users
17
ACCESSLOG=/var/log/apache2/access_log
18
19
# ##################################################################################### AUTOCONF
20
21
if [ "$1" = "autoconf" ]
22
then
23
	if ! ls $ACCESSLOG > /dev/null
24
	then
25
		echo "no (could not find apache access log \"$ACCESSLOG\")"
26
		exit 1
27
	elif ! ls $DIRECTORY > /dev/null
28
	then
29
		echo "no (could not find munin plugins directory \"$DIRECTORY\")"
30
		exit 2
31
32
	else
33
		echo "yes"
34
		exit 0
35
	fi
36
fi
37
38
# ######################################################################################### INIT
39
40
# Define regex for all possible timestamps of last 5 minutes block
41
REGEX=$(LC_ALL=en_US date -d "5 minutes ago" "+\[%d\/%b\/%Y:%H: %M :[0-5][0-9] %z\]" \
42
	| awk '{ printf "%s(%02d|%02d|%02d|%02d|%02d)%s", $1, $2-$2%5, $2-$2%5+1, $2-$2%5+2, $2-$2%5+3, $2-$2%5+4, $3 }')
43
44
45
# Analyse logfile
46
while read REQUEST_ADDR REQUEST_USERNAME REQUEST_BYTES
47
do
48 8589c6df klemens
	# Name resolution for known addresses
49 8054d81a Rainer Wolff
	REQUEST_DOMAIN=$( awk '/^'"$REQUEST_ADDR"'/ { print $2 }' /etc/hosts )
50
	REQUEST_ADDR=${REQUEST_DOMAIN:-$REQUEST_ADDR}
51
52
53
	# Scan for known addresses, if found, sum up traffic
54
	FOUND=false
55
	for (( I=${#ADDR[@]}-1; I>=0; I-- ))
56
	do
57
		# Address known, name maybe, anonymous access (again)
58
		if [ "${ADDR[I]}" == "$REQUEST_ADDR" -a "$REQUEST_USERNAME" == "-" ]
59
		then
60
			FOUND=true
61
			BYTES[$I]=$(( ${BYTES[I]} + $REQUEST_BYTES ))
62
			break
63
64
		# Known address and name
65
		elif [ "${ADDR[I]}" == "$REQUEST_ADDR" -a "${USERNAME[I]}" == "$REQUEST_USERNAME" ]
66
		then
67
			FOUND=true
68
			BYTES[$I]=$(( ${BYTES[I]} + $REQUEST_BYTES ))
69
			break
70
71
		# Known address, previous access anonymous
72
		elif [ "${ADDR[I]}" == "$REQUEST_ADDR" -a "${USERNAME[I]}" == "-" ]
73
		then
74
			FOUND=true
75
			USERNAME[$I]="$REQUEST_USERNAME"
76
			BYTES[$I]=$(( ${BYTES[I]} + $REQUEST_BYTES ))
77
			break
78
		fi
79
	done
80
81
	# Combination of address and name unknown, create new entry
82
	if [ "$FOUND" == "false" ]
83
	then
84
		ADDR[${#ADDR[@]}]=$REQUEST_ADDR
85
		USERNAME[${#USERNAME[@]}]="$REQUEST_USERNAME"
86
		BYTES[${#BYTES[@]}]=$REQUEST_BYTES
87
	fi
88
89
done < <( awk '/'"$REGEX"'/ { printf "%s %s %d\n", $1, $3, $10 }' $ACCESSLOG )
90
91
92
# Assign anonymous access when possible and correct identifiers
93
for (( I=0; I<${#USERNAME[@]}; I++ ))
94
do
95
	if [ "${USERNAME[I]}" == "-" ]
96
	then
97
		if $( echo "${ADDR[I]}" | egrep -q "[^0-9.]" )
98
		then
99
			USERNAME[$I]="${ADDR[I]}"
100
		else
101
			USERNAME[$I]="anonymous"
102
		fi
103
		NAME[$I]="_${USERNAME[I]}" # Output sort order 
104
	else
105
		NAME[$I]="${USERNAME[I]}"
106
	fi
107
108
	NAME[$I]="$( echo "${NAME[I]}" \
109
		| sed "s/^[^A-Za-z_]/_/" | sed "s/[^A-Za-z0-9_]/_/g" \
110
		| sed "s/^\(.\{,19\}\).*/\1/" )"
111
done
112
113
# Create timestamp
114
mkdir -p $DIRECTORY
115
touch -d "-1 second" $TIMESTAMP # find needs time span
116
117
# Aggregate parallel traffic
118
for (( I=0; I<${#NAME[@]}; I++ ))
119
do
120
	if [ -z "$( find $DIRECTORY -name "${NAME[I]}" -newer $TIMESTAMP )" ]
121
	then
122
		echo "${NAME[I]} ${BYTES[I]} ${USERNAME[I]}" > $DIRECTORY/${NAME[I]}
123
	else
124
		awk '{ printf "%s %d %s", $1, $2+${BYTES[I]}, $3 }' $DIRECTORY/${NAME[I]} > $DIRECTORY/${NAME[I]}
125
	fi
126
done
127
128
129
# ####################################################################################### CONFIG
130
131
if [ "$1" = "config" ]
132
then
133
	echo "graph_title Apache users"
134
	echo "graph_vlabel bytes per five minute period"
135
	echo "graph_args --lower-limit 1 --base 1024 --logarithmic"
136 65652aa0 dipohl
	echo "graph_category webserver"
137 8054d81a Rainer Wolff
	echo "graph_total total"
138
	echo "graph_info Webserver traffic by user."
139
140
	FILENAMES=$( find $DIRECTORY -type f -not -wholename $TIMESTAMP | sort)
141
142
	awk '{ printf "%s.label %s\n%s.draw AREA\n", $1, $3, $1 }' $( echo "$FILENAMES" | head -n1 )
143
	
144
	for FILENAME in $( echo "$FILENAMES" | tail -n+2)
145
	do
146
		awk '{ printf "%s.label %s\n%s.draw STACK\n", $1, $3, $1 }' $FILENAME
147
	done
148
149
	exit 0
150
fi
151
152
153
# ######################################################################################## VALUE
154
155
{
156
157
for FILENAME in $( find $DIRECTORY -type f -newer $TIMESTAMP -not -wholename $TIMESTAMP )
158
do
159
	awk '{ printf "%s.value %d\n", $1, $2 }' $FILENAME
160
done
161
162
for FILENAME in $( find $DIRECTORY -type f -not -newer $TIMESTAMP -not -wholename $TIMESTAMP )
163
do
164
	awk '{ printf "%s.value 0\n", $1 }' $FILENAME
165
done
166
167
} | sort
168
169
exit 0