Projet

Général

Profil

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

root / plugins / apache / apache_users @ d8fd604e

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

1
#!/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_PLUGSTATE/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
	elif ! ls $DIRECTORY > /dev/null
27
	then
28
		echo "no (could not find munin plugins directory \"$DIRECTORY\")"
29
	else
30
		echo "yes"
31
	fi
32
	exit 0
33
fi
34

    
35
# ######################################################################################### INIT
36

    
37
# Define regex for all possible timestamps of last 5 minutes block
38
REGEX=$(LC_ALL=en_US date -d "5 minutes ago" "+\[%d\/%b\/%Y:%H: %M :[0-5][0-9] %z\]" \
39
	| 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 }')
40

    
41

    
42
# Analyse logfile
43
while read REQUEST_ADDR REQUEST_USERNAME REQUEST_BYTES
44
do
45
	# Name resolution for known addresses
46
	REQUEST_DOMAIN=$( awk '/^'"$REQUEST_ADDR"'/ { print $2 }' /etc/hosts )
47
	REQUEST_ADDR=${REQUEST_DOMAIN:-$REQUEST_ADDR}
48

    
49

    
50
	# Scan for known addresses, if found, sum up traffic
51
	FOUND=false
52
	for (( I=${#ADDR[@]}-1; I>=0; I-- ))
53
	do
54
		# Address known, name maybe, anonymous access (again)
55
		if [ "${ADDR[I]}" == "$REQUEST_ADDR" -a "$REQUEST_USERNAME" == "-" ]
56
		then
57
			FOUND=true
58
			BYTES[$I]=$(( ${BYTES[I]} + $REQUEST_BYTES ))
59
			break
60

    
61
		# Known address and name
62
		elif [ "${ADDR[I]}" == "$REQUEST_ADDR" -a "${USERNAME[I]}" == "$REQUEST_USERNAME" ]
63
		then
64
			FOUND=true
65
			BYTES[$I]=$(( ${BYTES[I]} + $REQUEST_BYTES ))
66
			break
67

    
68
		# Known address, previous access anonymous
69
		elif [ "${ADDR[I]}" == "$REQUEST_ADDR" -a "${USERNAME[I]}" == "-" ]
70
		then
71
			FOUND=true
72
			USERNAME[$I]="$REQUEST_USERNAME"
73
			BYTES[$I]=$(( ${BYTES[I]} + $REQUEST_BYTES ))
74
			break
75
		fi
76
	done
77

    
78
	# Combination of address and name unknown, create new entry
79
	if [ "$FOUND" == "false" ]
80
	then
81
		ADDR[${#ADDR[@]}]=$REQUEST_ADDR
82
		USERNAME[${#USERNAME[@]}]="$REQUEST_USERNAME"
83
		BYTES[${#BYTES[@]}]=$REQUEST_BYTES
84
	fi
85

    
86
done < <( awk '/'"$REGEX"'/ { printf "%s %s %d\n", $1, $3, $10 }' $ACCESSLOG )
87

    
88

    
89
# Assign anonymous access when possible and correct identifiers
90
for (( I=0; I<${#USERNAME[@]}; I++ ))
91
do
92
	if [ "${USERNAME[I]}" == "-" ]
93
	then
94
		if $( echo "${ADDR[I]}" | egrep -q "[^0-9.]" )
95
		then
96
			USERNAME[$I]="${ADDR[I]}"
97
		else
98
			USERNAME[$I]="anonymous"
99
		fi
100
		NAME[$I]="_${USERNAME[I]}" # Output sort order
101
	else
102
		NAME[$I]="${USERNAME[I]}"
103
	fi
104

    
105
	NAME[$I]="$( echo "${NAME[I]}" \
106
		| sed "s/^[^A-Za-z_]/_/" | sed "s/[^A-Za-z0-9_]/_/g" \
107
		| sed "s/^\(.\{,19\}\).*/\1/" )"
108
done
109

    
110
# Create timestamp
111
mkdir -p $DIRECTORY
112
touch -d "-1 second" $TIMESTAMP # find needs time span
113

    
114
# Aggregate parallel traffic
115
for (( I=0; I<${#NAME[@]}; I++ ))
116
do
117
	if [ -z "$( find $DIRECTORY -name "${NAME[I]}" -newer $TIMESTAMP )" ]
118
	then
119
		echo "${NAME[I]} ${BYTES[I]} ${USERNAME[I]}" > $DIRECTORY/${NAME[I]}
120
	else
121
		awk '{ printf "%s %d %s", $1, $2+${BYTES[I]}, $3 }' $DIRECTORY/${NAME[I]} > $DIRECTORY/${NAME[I]}
122
	fi
123
done
124

    
125

    
126
# ####################################################################################### CONFIG
127

    
128
if [ "$1" = "config" ]
129
then
130
	echo "graph_title Apache users"
131
	echo "graph_vlabel bytes per five minute period"
132
	echo "graph_args --lower-limit 1 --base 1024 --logarithmic"
133
	echo "graph_category webserver"
134
	echo "graph_total total"
135
	echo "graph_info Webserver traffic by user."
136

    
137
	FILENAMES=$( find $DIRECTORY -type f -not -wholename $TIMESTAMP | sort)
138

    
139
	awk '{ printf "%s.label %s\n%s.draw AREA\n", $1, $3, $1 }' $( echo "$FILENAMES" | head -n1 )
140

    
141
	for FILENAME in $( echo "$FILENAMES" | tail -n+2)
142
	do
143
		awk '{ printf "%s.label %s\n%s.draw STACK\n", $1, $3, $1 }' $FILENAME
144
	done
145

    
146
	exit 0
147
fi
148

    
149

    
150
# ######################################################################################## VALUE
151

    
152
{
153

    
154
for FILENAME in $( find $DIRECTORY -type f -newer $TIMESTAMP -not -wholename $TIMESTAMP )
155
do
156
	awk '{ printf "%s.value %d\n", $1, $2 }' $FILENAME
157
done
158

    
159
for FILENAME in $( find $DIRECTORY -type f -not -newer $TIMESTAMP -not -wholename $TIMESTAMP )
160
do
161
	awk '{ printf "%s.value 0\n", $1 }' $FILENAME
162
done
163

    
164
} | sort
165

    
166
exit 0
167