#!/usr/bin/env bash # vim: expandtab:ts=4:sw=4 : << =cut =head1 NAME http_response - Monitor HTTP response statistics =head1 CONFIGURATION The following environment variables are used: =over =item * sites - The sites to check =over =item * separated by spaces =item * can contain basic auth credentials =item * defaults to C =back =item * max_time - Timeout for each site check in seconds =over =item * defaults to C<5> =back =item * short_label - Switch for shortening the label below the graph =over =item * defaults to C =back =item * follow_redirect - Switch for following http redirects =over =item * defaults to C =back =back =head2 CONFIGURATION EXAMPLE [http_response] env.sites http://example.com/ https://user:secret@example2.de env.max_time 20 env.short_label true env.follow_redirect true =head1 PREREQUISITES This plugin needs at least bash version 4 to run. Additionally the following programs must be present on your system: =over =item * awk =item * curl =item * date =item * echo =item * mktemp =back =head1 SEE ALSO This plugin unifies the functionalities of the following plugins into one multigraph plugin: =over =item * L =item * L =back In contrast to using these two plugins with the same configuration, this plugin performs only one request per site and munin run to gather its statistics. =head1 AUTHOR Copyright (C) 2020-2021 Klaus Sperner =head1 LICENSE This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991. 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. =head1 MAGIC MARKERS #%# family=manual =cut # shellcheck disable=SC1091 . "$MUNIN_LIBDIR/plugins/plugin.sh" readonly uri_regex='^(https?://)([^:]*):(.*)@(.*)$' strip_credentials_from_url() { if [[ "$1" =~ $uri_regex ]]; then echo "${BASH_REMATCH[1]}${BASH_REMATCH[4]}" else echo "$1" fi } extract_username_from_url() { if [[ "$1" =~ $uri_regex ]]; then echo "${BASH_REMATCH[2]}" else echo "" fi } extract_password_from_url() { if [[ "$1" =~ $uri_regex ]]; then echo "${BASH_REMATCH[3]}" else echo "" fi } compute_label() { if [[ "${short_label,,}" == "true" || "${short_label,,}" == "yes" ]]; then if [[ ${#1} -gt 33 ]]; then echo "${1:0:30}..." else echo "$1" fi else echo "$1" fi } check_programs_installed() { for program in "$@"; do if ! hash "$program" 2>/dev/null; then >&2 echo "The plugin http_response needs $program but it is not installed. Aborting." exit 1 fi done } if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then >&2 echo "The plugin http_response needs at least bash version 4. Aborting." exit 1 fi check_programs_installed awk curl date echo mktemp sites=${sites:-"http://localhost/"} max_time=${max_time:-5} short_label=${short_label:-"false"} follow_redirect=${follow_redirect:-"false"} if [[ ! "$max_time" =~ ^[0-9]+$ ]]; then >&2 echo "Invalid configuration: max_time $max_time must contain only digits. Aborting." exit 1 fi if [[ "$1" == "config" ]]; then echo 'multigraph http_response_code' echo 'graph_args --base 1000 --lower-limit 0 --upper-limit 511' echo 'graph_title HTTP Response Codes' echo 'graph_vlabel Response Code' echo 'graph_category network' echo 'graph_info This graph shows HTTP response code statistics' echo 'graph_printf %3.0lf' for site in $sites; do site_without_credentials=$( strip_credentials_from_url "$site" ) site_id="$( clean_fieldname "$site_without_credentials" )" echo "$site_id.label $( compute_label "$site_without_credentials" )" echo "$site_id.info HTTP response code statistics for $site_without_credentials" echo "$site_id.critical 99:399"; done echo 'multigraph http_response_time' echo 'graph_args --base 1000 -l 0' echo 'graph_title HTTP Response Times' echo 'graph_vlabel Response Time in seconds' echo 'graph_category network' echo 'graph_info This graph shows HTTP response time statistics' for site in $sites; do site_without_credentials=$( strip_credentials_from_url "$site" ) site_id="$( clean_fieldname "$site_without_credentials" )" echo "$site_id.label $( compute_label "$site_without_credentials" )" echo "$site_id.info HTTP response time statistics for $site_without_credentials" done exit 0 fi declare -A response_codes declare -A response_times for site in $sites; do site_without_credentials=$( strip_credentials_from_url "$site" ) username=$( extract_username_from_url "$site" ) password=$( extract_password_from_url "$site" ) configurable_arguments=() curl_config_file="" if [ -n "$username" ]; then if [ -z "$password" ]; then >&2 echo "Invalid configuration: username specified without password" exit 1 fi curl_config_file=$(mktemp) || exit 1 trap 'rm -f "$curl_config_file"' EXIT echo "user=${username}:${password}" >> "$curl_config_file" configurable_arguments+=(--config "$curl_config_file") fi if [[ "${follow_redirect,,}" == "true" || "${follow_redirect,,}" == "yes" ]]; then configurable_arguments+=(--location) fi site_id="$( clean_fieldname "$site_without_credentials" )" start=$(date +%s.%N) status_code=$( curl "${configurable_arguments[@]}" --write-out '%{http_code}' --max-time "$max_time" --silent --output /dev/null "$site_without_credentials" ) return_code=$? load_time=$( echo "$start" "$(date +%s.%N)" | awk '{ print($2 - $1); }' ) if [[ $return_code -ne 0 ]]; then load_time="U" status_code="U" fi response_codes+=(["$site_id"]="$status_code") response_times+=(["$site_id"]="$load_time") if [ -n "$curl_config_file" ]; then rm -f "$curl_config_file" fi done echo 'multigraph http_response_code' for site_id in "${!response_codes[@]}"; do echo "${site_id}.value ${response_codes[${site_id}]}" done echo 'multigraph http_response_time' for site_id in "${!response_times[@]}"; do echo "${site_id}.value ${response_times[${site_id}]}" done