Repository
Munin (contrib)
Last change
2021-04-05
Graph Categories
Family
manual
Capabilities
Keywords
Language
Bash
License
curl
Authors

http_response

Name

http_response - Monitor HTTP response statistics

Configuration

The following environment variables are used

sites           - Sites to check
                    - separated by spaces
                    - can contain basic auth credentials
                    - defaults to "http://localhost/"
max_time        - Timeout for each site check in seconds
                    - defaults to 5 seconds
short_label     - Switch for shortening the label below the graph
                    - defaults to false
follow_redirect - Follow http redirects
                    - defaults to false

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

Prerequisites

This plugin needs at least bash version 4 to run

Notes

This plugin unifies the functionalities of the following plugins into one multigraph plugin

http_loadtime     - https://gallery.munin-monitoring.org/plugins/munin/http_loadtime/
http_responsecode - https://gallery.munin-monitoring.org/plugins/munin-contrib/http_responsecode/

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.

Author

Copyright (C) 2020 Klaus Sperner

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.

Magic Markers

#%# family=manual
#!/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

 sites           - Sites to check
                     - separated by spaces
                     - can contain basic auth credentials
                     - defaults to "http://localhost/"
 max_time        - Timeout for each site check in seconds
                     - defaults to 5 seconds
 short_label     - Switch for shortening the label below the graph
                     - defaults to false
 follow_redirect - Follow http redirects
                     - defaults to false

=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

=head1 NOTES

This plugin unifies the functionalities of the following plugins into one
multigraph plugin

 http_loadtime     - https://gallery.munin-monitoring.org/plugins/munin/http_loadtime/
 http_responsecode - https://gallery.munin-monitoring.org/plugins/munin-contrib/http_responsecode/

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 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

. "$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
}

if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then
    >&2 echo "The plugin http_response needs at least bash version 4"
    exit 1
fi

sites=${sites:-"http://localhost/"}
max_time=${max_time:-5}
short_label=${short_label:-"false"}
follow_redirect=${follow_redirect:-"false"}

if [[ "$1" == "config" ]]; then
    echo 'multigraph http_response_code'
    echo 'graph_args --base 1000 -l 0 -u 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" )
        siteid="$( clean_fieldname "$site_without_credentials" )"
        echo "$siteid.label $( compute_label "$site_without_credentials" )"
        echo "$siteid.info HTTP response code statistics for $site_without_credentials"
        echo "$siteid.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" )
        siteid="$( clean_fieldname "$site_without_credentials" )"
        echo "$siteid.label $( compute_label "$site_without_credentials" )"
        echo "$siteid.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" )

    curl_config_file=""
    curl_auth_opt=()
    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"
        curl_auth_opt=(--config "$curl_config_file")
    fi

    curl_arg=""
    if $follow_redirect; then
        curl_arg="--location"
    fi

    siteid="$( clean_fieldname "$site_without_credentials" )"
    statuscode=
    loadtime=
    start=$(date +%s.%N)
    statuscode=$( curl "${curl_auth_opt[@]}" --write-out '%{http_code}' --max-time "$max_time" $curl_arg --silent --output /dev/null "$site_without_credentials" )
    returncode=$?
    loadtime=$( echo "$start" "$(date +%s.%N)" | awk '{ print($2 - $1); }' )
    if [[ $returncode -ne 0 ]]; then
        loadtime="U"
        statuscode="U"
    fi
    response_codes+=(["$siteid"]="$statuscode")
    response_times+=(["$siteid"]="$loadtime")

    if [ -n "$curl_config_file" ]; then
        rm -f "$curl_config_file"
    fi
done

echo 'multigraph http_response_code'
for siteid in "${!response_codes[@]}"; do
    echo "${siteid}.value ${response_codes[${siteid}]}"
done

echo 'multigraph http_response_time'
for siteid in "${!response_times[@]}"; do
    echo "${siteid}.value ${response_times[${siteid}]}"
done