root / plugins / nginx / nginx_error @ caf3b6c9
Historique | Voir | Annoter | Télécharger (3,82 ko)
| 1 | 90f35c58 | v | #!/bin/bash |
|---|---|---|---|
| 2 | # -*- bash -*- |
||
| 3 | |||
| 4 | 9598bc7c | Kenyon Ralph | : <<=cut |
| 5 | 90f35c58 | v | |
| 6 | =head1 NAME |
||
| 7 | |||
| 8 | nginx error - Munin plugin to monitor nginx error rates (http status codes per minute). |
||
| 9 | |||
| 10 | 24ea5d29 | Lars Kruse | |
| 11 | 90f35c58 | v | =head1 APPLICABLE SYSTEMS |
| 12 | |||
| 13 | 24ea5d29 | Lars Kruse | Any host running nginx, with bash version > 4.0 |
| 14 | |||
| 15 | 90f35c58 | v | |
| 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 | 24ea5d29 | Lars Kruse | Additionally you may want to adjust 'group' (or 'user') based on the |
| 21 | permissions required for reading the log file. |
||
| 22 | 90f35c58 | v | |
| 23 | [nginx_error] |
||
| 24 | 24ea5d29 | Lars Kruse | group adm |
| 25 | 90f35c58 | v | 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 | 24ea5d29 | Lars Kruse | |
| 31 | 90f35c58 | v | =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 | 24ea5d29 | Lars Kruse | 'env.logpattern' is ignored for a non-symlink configuration. |
| 43 | |||
| 44 | |||
| 45 | 90f35c58 | v | =head1 INTERPRETATION |
| 46 | |||
| 47 | The plugin shows nginx http "error" status rates by parsing access log. |
||
| 48 | |||
| 49 | 24ea5d29 | Lars Kruse | |
| 50 | 90f35c58 | v | =head1 MAGIC MARKERS |
| 51 | |||
| 52 | #%# family=auto |
||
| 53 | #%# capabilities=autoconf |
||
| 54 | |||
| 55 | 24ea5d29 | Lars Kruse | |
| 56 | 90f35c58 | v | =head1 BUGS |
| 57 | |||
| 58 | None known. |
||
| 59 | |||
| 60 | 24ea5d29 | Lars Kruse | |
| 61 | 90f35c58 | v | =head1 VERSION |
| 62 | |||
| 63 | 808a21d4 | Lars Kruse | 1.1 - 2018/01/20 |
| 64 | 7ed71b44 | Lars Kruse | * add 'dirty config' capability support |
| 65 | 8a68200a | Lars Kruse | * fix shell style issues reported by shellcheck |
| 66 | 808a21d4 | Lars Kruse | * improve readability of symlink configuration code |
| 67 | |||
| 68 | f4c19246 | Lars Kruse | 1.0 - 2017/02/21 |
| 69 | 90f35c58 | v | |
| 70 | 808a21d4 | Lars Kruse | |
| 71 | 90f35c58 | v | =head1 AUTHOR |
| 72 | |||
| 73 | vovansystems@gmail.com, 2013 |
||
| 74 | |||
| 75 | 24ea5d29 | Lars Kruse | |
| 76 | 90f35c58 | v | =head1 LICENSE |
| 77 | |||
| 78 | GPLv3 |
||
| 79 | |||
| 80 | =cut |
||
| 81 | |||
| 82 | |||
| 83 | a4882b19 | Lars Kruse | set -eu |
| 84 | |||
| 85 | |||
| 86 | 808a21d4 | Lars Kruse | # default environment variable values |
| 87 | logpath=${logpath:-/var/log/nginx}
|
||
| 88 | 90f35c58 | v | |
| 89 | 808a21d4 | Lars Kruse | |
| 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 | 90f35c58 | v | else |
| 100 | 808a21d4 | Lars Kruse | log_filename='access.log' |
| 101 | 90f35c58 | v | fi |
| 102 | |||
| 103 | 808a21d4 | Lars Kruse | log="$logpath/$log_filename" |
| 104 | 90f35c58 | v | |
| 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 | 8a68200a | Lars Kruse | |
| 121 | # parse error counts from log file |
||
| 122 | 7ed71b44 | Lars Kruse | do_fetch () {
|
| 123 | 0e864944 | Lars Kruse | local count status_code |
| 124 | 37a7317c | Daniel Schmitz | declare -A line_counts |
| 125 | caf3b6c9 | Filippo Tessarotto | 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 | 0e864944 | Lars Kruse | line_counts[$status_code]=$count |
| 130 | caf3b6c9 | Filippo Tessarotto | done <<< "$values" |
| 131 | fi |
||
| 132 | 0e864944 | Lars Kruse | |
| 133 | for status_code in "${!http_codes[@]}"; do
|
||
| 134 | echo "error${status_code}.value ${line_counts[$status_code]:-0}"
|
||
| 135 | 90f35c58 | v | done |
| 136 | } |
||
| 137 | |||
| 138 | 8a68200a | Lars Kruse | |
| 139 | 90f35c58 | v | do_config () {
|
| 140 | 0e864944 | Lars Kruse | local status_code |
| 141 | 808a21d4 | Lars Kruse | echo "graph_title $(basename "$log") - Nginx errors per minute" |
| 142 | 8a68200a | Lars Kruse | echo "graph_vlabel pages with http error codes / \${graph_period}"
|
| 143 | 3c98d069 | dipohl | echo "graph_category webserver" |
| 144 | 90f35c58 | v | echo "graph_period minute" |
| 145 | 24ea5d29 | Lars Kruse | echo "graph_info This graph shows nginx error rate per minute" |
| 146 | 0e864944 | Lars Kruse | 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 | 90f35c58 | v | done |
| 151 | } |
||
| 152 | |||
| 153 | 8a68200a | Lars Kruse | |
| 154 | 90f35c58 | v | do_autoconf () {
|
| 155 | echo yes |
||
| 156 | } |
||
| 157 | |||
| 158 | 8a68200a | Lars Kruse | |
| 159 | a4882b19 | Lars Kruse | case ${1:-} in
|
| 160 | 7ed71b44 | Lars Kruse | config) |
| 161 | do_config |
||
| 162 | # support "dirty config" capability |
||
| 163 | c81c20ab | Lars Kruse | if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then do_fetch; fi
|
| 164 | 7ed71b44 | Lars Kruse | ;; |
| 165 | autoconf) |
||
| 166 | do_autoconf |
||
| 167 | ;; |
||
| 168 | '') |
||
| 169 | do_fetch |
||
| 170 | ;; |
||
| 171 | 90f35c58 | v | esac |
| 172 | |||
| 173 | 9598bc7c | Kenyon Ralph | exit $? |
