diff --git a/plugins/isp/internode_usage b/plugins/isp/internode_usage index 739242c8..a467d9db 100755 --- a/plugins/isp/internode_usage +++ b/plugins/isp/internode_usage @@ -35,6 +35,13 @@ If multiple services are available, the plugin will automatically pick the first service from the list. To monitor other services, the plugin can be used multiple times, by symlinking it as 'internode_usage_SERVICEID'. +=head1 CACHING + +As the API is sometimes flakey, the initial service information is cached +locally, with a one-hour lifetime, before hitting the base API again. However, +if hitting the API to refresh the cache fails, the stale cache is used anyway, +to have a better chance of getting the data out nonetheless. + =head1 CAVEATS * The hourly rate are a bit spikey in the -day view, as the API seems to update @@ -105,7 +112,45 @@ fetch() { || { echo "error fetching ${*} for user ${internode_api_login}" >&2; false; } } -get_data() { +get_cached_api() { + # shellcheck disable=SC2039 + local url=${1} + # shellcheck disable=SC2039 + local name=${2} + # shellcheck disable=SC2039 + local api_data='' + # shellcheck disable=SC2039 + local cachefile="${MUNIN_PLUGSTATE}/$(basename "${0}").${name}.cache" + if [ -n "$(find "${cachefile}" -mmin -1440 2>/dev/null)" ]; then + api_data=$(cat "${cachefile}") + else + api_data="$(fetch "${url}" \ + || true)" + + if [ -n "${api_data}" ]; then + echo "${api_data}" > ${cachefile} + else + echo "using ${name} info from stale cache ${cachefile}" >&2 + api_data=$(cat "${cachefile}") + fi + fi + echo "${api_data}" +} + +get_service_data() { + # Determine the service ID from the name of the symlink + SERVICE_ID="$(echo "${0}" | sed -n 's/^.*internode_usage_//p')" + if [ -z "${SERVICE_ID}" ]; then + # Otherwise, get the first service in the list + API_XML="$(get_cached_api ${internode_api_url} API_XML)" + if [ -z "${API_XML}" ]; then + echo "unable to determine service ID for user ${internode_api_login}" >&2 + exit 1 + fi + SERVICE_ID="$(echo "${API_XML}" | xpath_extract "internode/api/services/service")" + fi + + CURRENT_TIMESTAMP="$(date +%s)" SERVICE_USERNAME='n/a' SERVICE_QUOTA='n/a' @@ -113,7 +158,7 @@ get_data() { SERVICE_ROLLOVER='n/a' IDEAL_USAGE='' USAGE_CRITICAL='' - SERVICE_XML="$(fetch "${internode_api_url}/${SERVICE_ID}/service" \ + SERVICE_XML="$(get_cached_api "${internode_api_url}/${SERVICE_ID}/service" SERVICE_XML \ || true)" if [ -n "${SERVICE_XML}" ]; then SERVICE_USERNAME="$(echo "${SERVICE_XML}" | xpath_extract "internode/api/service/username")" @@ -130,6 +175,9 @@ get_data() { USAGE_CRITICAL="${SERVICE_QUOTA}" fi +} + +get_data() { DAILY_TIMESTAMP=N DAILY_USAGE=U HISTORY_XML="$(fetch "${internode_api_url}/${SERVICE_ID}/history" \ @@ -235,18 +283,16 @@ graph_data() { main() { case ${1:-} in config) - if [ ! -z "${host_name:-}" ]; then + if [ -n "${host_name:-}" ]; then echo "host_name ${host_name}" fi graph_config graph_config usage graph_config daily graph_config current - if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then - main - fi ;; *) + get_data graph_data graph_data usage graph_data daily @@ -255,19 +301,6 @@ main() { esac } -# Determine the service ID from the name of the symlink -SERVICE_ID="$(echo "${0}" | sed -n 's/^.*internode_usage_//p')" -if [ -z "${SERVICE_ID}" ]; then - # Otherwise, get the first service in the list - API_XML="$(fetch "${internode_api_url}" \ - || true)" - if [ -z "${API_XML}" ]; then - echo "unable to determine service ID for user ${internode_api_login}" >&2 - exit 1 - fi - SERVICE_ID="$(echo "${API_XML}" | xpath_extract "internode/api/services/service")" -fi - -get_data +get_service_data main "${1:-}"