root / plugins / nginx / nginx_error @ a7139bca
Historique | Voir | Annoter | Télécharger (3,82 ko)
| 1 |
#!/bin/bash |
|---|---|
| 2 |
# -*- bash -*- |
| 3 |
|
| 4 |
: <<=cut |
| 5 |
|
| 6 |
=head1 NAME |
| 7 |
|
| 8 |
nginx error - Munin plugin to monitor nginx error rates (http status codes per minute). |
| 9 |
|
| 10 |
|
| 11 |
=head1 APPLICABLE SYSTEMS |
| 12 |
|
| 13 |
Any host running nginx, with bash version > 4.0 |
| 14 |
|
| 15 |
|
| 16 |
=head1 CONFIGURATION |
| 17 |
|
| 18 |
This shows the default configuration of this plugin. You can override |
| 19 |
the log file path and the logpattern. |
| 20 |
Additionally you may want to adjust 'group' (or 'user') based on the |
| 21 |
permissions required for reading the log file. |
| 22 |
|
| 23 |
[nginx_error] |
| 24 |
group adm |
| 25 |
env.logpath /var/log/nginx |
| 26 |
env.logpattern a.*.log |
| 27 |
|
| 28 |
Nginx must also be configured to log accesses in "combined" log format (default) |
| 29 |
|
| 30 |
|
| 31 |
=head1 USAGE |
| 32 |
|
| 33 |
Link this plugin to /etc/munin/plugins/ and restart the munin-node. |
| 34 |
|
| 35 |
This plugin also can be used like wildcard-plugin for monitoring particular virtual host log. |
| 36 |
E.g. |
| 37 |
ln -s /usr/share/munin/plugins/nginx_error /etc/munin/plugins/nginx_error_mydomaincom |
| 38 |
will parse the log file /var/log/nginx/a.mydomaincom.log |
| 39 |
|
| 40 |
You can change 'env.logpattern' using asterisk ('*') to match your logs filenames.
|
| 41 |
|
| 42 |
'env.logpattern' is ignored for a non-symlink configuration. |
| 43 |
|
| 44 |
|
| 45 |
=head1 INTERPRETATION |
| 46 |
|
| 47 |
The plugin shows nginx http "error" status rates by parsing access log. |
| 48 |
|
| 49 |
|
| 50 |
=head1 MAGIC MARKERS |
| 51 |
|
| 52 |
#%# family=auto |
| 53 |
#%# capabilities=autoconf |
| 54 |
|
| 55 |
|
| 56 |
=head1 BUGS |
| 57 |
|
| 58 |
None known. |
| 59 |
|
| 60 |
|
| 61 |
=head1 VERSION |
| 62 |
|
| 63 |
1.1 - 2018/01/20 |
| 64 |
* add 'dirty config' capability support |
| 65 |
* fix shell style issues reported by shellcheck |
| 66 |
* improve readability of symlink configuration code |
| 67 |
|
| 68 |
1.0 - 2017/02/21 |
| 69 |
|
| 70 |
|
| 71 |
=head1 AUTHOR |
| 72 |
|
| 73 |
vovansystems@gmail.com, 2013 |
| 74 |
|
| 75 |
|
| 76 |
=head1 LICENSE |
| 77 |
|
| 78 |
GPLv3 |
| 79 |
|
| 80 |
=cut |
| 81 |
|
| 82 |
|
| 83 |
set -eu |
| 84 |
|
| 85 |
|
| 86 |
# default environment variable values |
| 87 |
logpath=${logpath:-/var/log/nginx}
|
| 88 |
|
| 89 |
|
| 90 |
# derive the name of the log file from a potential symlink-configured virtual host |
| 91 |
script_name=$(basename "$0") |
| 92 |
plugin_suffix=${script_name#nginx_error}
|
| 93 |
if [ -n "${plugin_suffix#_}" ]; then
|
| 94 |
# a domain was given via symlink configuration: adjust the logpattern |
| 95 |
domain=${plugin_suffix#_}
|
| 96 |
# default logpattern for symlink configuration mode |
| 97 |
logpattern=${logpattern:-a.*.log}
|
| 98 |
log_filename=${logpattern/\*/$domain}
|
| 99 |
else |
| 100 |
log_filename='access.log' |
| 101 |
fi |
| 102 |
|
| 103 |
log="$logpath/$log_filename" |
| 104 |
|
| 105 |
# declaring an array with http status codes, we are interested in |
| 106 |
declare -A http_codes |
| 107 |
http_codes[400]='Bad Request' |
| 108 |
http_codes[401]='Unauthorized' |
| 109 |
http_codes[403]='Forbidden' |
| 110 |
http_codes[404]='Not Found' |
| 111 |
http_codes[405]='Method Not Allowed' |
| 112 |
http_codes[406]='Not Acceptable' |
| 113 |
http_codes[408]='Request Timeout' |
| 114 |
http_codes[429]='Too Many Requests' |
| 115 |
http_codes[499]='Client Connection Terminated' |
| 116 |
http_codes[500]='Internal Server Error' |
| 117 |
http_codes[502]='Bad Gateway' |
| 118 |
http_codes[503]='Service Unavailable' |
| 119 |
|
| 120 |
|
| 121 |
# parse error counts from log file |
| 122 |
do_fetch () {
|
| 123 |
local count status_code |
| 124 |
declare -A line_counts |
| 125 |
values="$(awk '{print $9}' "$log" | sort | uniq -c)"
|
| 126 |
# Log files may be empty due to logrotation |
| 127 |
if [ -n "$values" ]; then |
| 128 |
while read -r count status_code; do |
| 129 |
line_counts[$status_code]=$count |
| 130 |
done <<< "$values" |
| 131 |
fi |
| 132 |
|
| 133 |
for status_code in "${!http_codes[@]}"; do
|
| 134 |
echo "error${status_code}.value ${line_counts[$status_code]:-0}"
|
| 135 |
done |
| 136 |
} |
| 137 |
|
| 138 |
|
| 139 |
do_config () {
|
| 140 |
local status_code |
| 141 |
echo "graph_title $(basename "$log") - Nginx errors per minute" |
| 142 |
echo "graph_vlabel pages with http error codes / \${graph_period}"
|
| 143 |
echo "graph_category webserver" |
| 144 |
echo "graph_period minute" |
| 145 |
echo "graph_info This graph shows nginx error rate per minute" |
| 146 |
for status_code in "${!http_codes[@]}"; do
|
| 147 |
echo "error${status_code}.type DERIVE"
|
| 148 |
echo "error${status_code}.min 0"
|
| 149 |
echo "error${status_code}.label $status_code ${http_codes[$status_code]}"
|
| 150 |
done |
| 151 |
} |
| 152 |
|
| 153 |
|
| 154 |
do_autoconf () {
|
| 155 |
echo yes |
| 156 |
} |
| 157 |
|
| 158 |
|
| 159 |
case ${1:-} in
|
| 160 |
config) |
| 161 |
do_config |
| 162 |
# support "dirty config" capability |
| 163 |
if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then do_fetch; fi
|
| 164 |
;; |
| 165 |
autoconf) |
| 166 |
do_autoconf |
| 167 |
;; |
| 168 |
'') |
| 169 |
do_fetch |
| 170 |
;; |
| 171 |
esac |
| 172 |
|
| 173 |
exit $? |
