From 1e2387474a449452b78520b9ad96a8b4b5e99722 Mon Sep 17 00:00:00 2001 From: Harald Pfeiffer Date: Wed, 17 Apr 2019 19:07:19 +0200 Subject: initial commit of source fetch --- .../check_varnish/varnish-nagios/check_varnish.c | 383 +++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 nagios-plugins-contrib-24.20190301~bpo9+1/check_varnish/varnish-nagios/check_varnish.c (limited to 'nagios-plugins-contrib-24.20190301~bpo9+1/check_varnish/varnish-nagios/check_varnish.c') diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_varnish/varnish-nagios/check_varnish.c b/nagios-plugins-contrib-24.20190301~bpo9+1/check_varnish/varnish-nagios/check_varnish.c new file mode 100644 index 0000000..809657c --- /dev/null +++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_varnish/varnish-nagios/check_varnish.c @@ -0,0 +1,383 @@ +/*- + * Copyright (c) 2007-2011 Varnish Software AS + * All rights reserved. + * + * Author: Cecilie Fritzvold + * Author: Tollef Fog Heen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + * + * Nagios plugin for Varnish + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_VARNISHAPI_4) || defined(HAVE_VARNISHAPI_4_1) +#include +#include +#elif defined(HAVE_VARNISHAPI_3) +#include "vsc.h" +#include "varnishapi.h" +#endif + +static int verbose = 0; + +struct range { + intmax_t lo; + intmax_t hi; + int inverted:1; + int defined:1; +}; + +static struct range critical; +static struct range warning; + +enum { + NAGIOS_OK = 0, + NAGIOS_WARNING = 1, + NAGIOS_CRITICAL = 2, + NAGIOS_UNKNOWN = 3, +}; + +static const char *status_text[] = { + [NAGIOS_OK] = "OK", + [NAGIOS_WARNING] = "WARNING", + [NAGIOS_CRITICAL] = "CRITICAL", + [NAGIOS_UNKNOWN] = "UNKNOWN", +}; + +/* + * Parse a range specification + */ +static int +parse_range(const char *spec, struct range *range) +{ + const char *delim; + char *end; + + /* @ means invert the range */ + if (*spec == '@') { + ++spec; + range->inverted = 1; + } else { + range->inverted = 0; + } + + /* empty spec... */ + if (*spec == '\0') + return (-1); + + if ((delim = strchr(spec, ':')) != NULL) { + /* + * The Nagios plugin documentation says nothing about how + * to interpret ":N", so we disallow it. Allowed forms + * are "~:N", "~:", "M:" and "M:N". + */ + if (delim - spec == 1 && *spec == '~') { + range->lo = INTMAX_MIN; + } else { + range->lo = strtoimax(spec, &end, 10); + if (end != delim) + return (-1); + } + if (*(delim + 1) != '\0') { + range->hi = strtoimax(delim + 1, &end, 10); + if (*end != '\0') + return (-1); + } else { + range->hi = INTMAX_MAX; + } + } else { + /* + * Allowed forms are N + */ + range->lo = 0; + range->hi = strtol(spec, &end, 10); + if (*end != '\0') + return (-1); + } + + /* + * Sanity + */ + if (range->lo > range->hi) + return (-1); + + range->defined = 1; + return (0); +} + +/* + * Check if a given value is within a given range. + */ +static int +inside_range(intmax_t value, const struct range *range) +{ + + if (range->inverted) + return (value < range->lo || value > range->hi); + return (value >= range->lo && value <= range->hi); +} + +/* + * Check if the thresholds against the value and return the appropriate + * status code. + */ +static int +check_thresholds(intmax_t value) +{ + + if (!warning.defined && !critical.defined) + return (NAGIOS_UNKNOWN); + if (critical.defined && !inside_range(value, &critical)) + return (NAGIOS_CRITICAL); + if (warning.defined && !inside_range(value, &warning)) + return (NAGIOS_WARNING); + return (NAGIOS_OK); +} + +struct stat_priv { + char *param; + const char *info; + intmax_t value; + int found; + intmax_t cache_hit; + intmax_t cache_miss; +}; + +static int +check_stats_cb(void *priv, const struct VSC_point * const pt) +{ + struct stat_priv *p; + char tmp[1024]; + + if (pt == NULL) + return(0); + +#if defined(HAVE_VARNISHAPI_4_1) || defined(HAVE_VARNISHAPI_4) + assert(sizeof(tmp) > (strlen(pt->section->fantom->type) + 1 + + strlen(pt->section->fantom->ident) + 1 + + strlen(pt->desc->name) + 1)); + snprintf(tmp, sizeof(tmp), "%s%s%s%s%s", + (pt->section->fantom->type[0] == 0 ? "" : pt->section->fantom->type), + (pt->section->fantom->type[0] == 0 ? "" : "."), + (pt->section->fantom->ident[0] == 0 ? "" : pt->section->fantom->ident), + (pt->section->fantom->ident[0] == 0 ? "" : "."), + pt->desc->name); + p = priv; +#endif +#if defined(HAVE_VARNISHAPI_4_1) + assert(!strcmp(pt->desc->ctype, "uint64_t")); +#elif defined(HAVE_VARNISHAPI_4) + assert(!strcmp(pt->desc->fmt, "uint64_t")); +#elif defined(HAVE_VARNISHAPI_3) + assert(sizeof(tmp) > (strlen(pt->class) + 1 + + strlen(pt->ident) + 1 + + strlen(pt->name) + 1)); + snprintf(tmp, sizeof(tmp), "%s%s%s%s%s", + (pt->class[0] == 0 ? "" : pt->class), + (pt->class[0] == 0 ? "" : "."), + (pt->ident[0] == 0 ? "" : pt->ident), + (pt->ident[0] == 0 ? "" : "."), + pt->name); + p = priv; + assert(!strcmp(pt->fmt, "uint64_t")); +#endif + if (strcmp(tmp, p->param) == 0) { + p->found = 1; +#if defined(HAVE_VARNISHAPI_4) || defined(HAVE_VARNISHAPI_4_1) + p->info = pt->desc->sdesc; +#elif defined(HAVE_VARNISHAPI_3) + p->info = pt->desc; +#endif + p->value = *(const volatile uint64_t*)pt->ptr; + } else if (strcmp(p->param, "ratio") == 0) { + if (strcmp(tmp, "cache_hit") == 0 || strcmp(tmp, "MAIN.cache_hit") == 0) { + p->found = 1; + p->cache_hit = *(const volatile uint64_t*)pt->ptr; + } else if (strcmp(tmp, "cache_miss") == 0 || strcmp(tmp, "MAIN.cache_miss") == 0) { + p->cache_miss = *(const volatile uint64_t*)pt->ptr; + } + } + return (0); +} + +/* + * Check the statistics for the requested parameter. + */ +static void +check_stats(struct VSM_data *vd, char *param) +{ + int status; + struct stat_priv priv; + + priv.found = 0; + priv.param = param; + +#if defined(HAVE_VARNISHAPI_4) || defined(HAVE_VARNISHAPI_4_1) + (void)VSC_Iter(vd, NULL, check_stats_cb, &priv); +#elif defined(HAVE_VARNISHAPI_3) + (void)VSC_Iter(vd, check_stats_cb, &priv); +#endif + if (strcmp(param, "ratio") == 0) { + intmax_t total = priv.cache_hit + priv.cache_miss; + priv.value = total ? (100 * priv.cache_hit / total) : 0; + priv.info = "Cache hit ratio"; + } + if (priv.found != 1) { + printf("Unknown parameter '%s'\n", param); + exit(1); + } + + status = check_thresholds(priv.value); + printf("VARNISH %s: %s (%'jd)|%s=%jd\n", status_text[status], + priv.info, priv.value, param, priv.value); + exit(status); +} + +/*-------------------------------------------------------------------------------*/ + +static void +help(void) +{ + + fprintf(stderr, "usage: " + "check_varnish [-lv] [-n varnish_name] [-p param_name [-c N] [-w N]]\n" + "\n" + "-v Increase verbosity.\n" + "-n varnish_name Specify the Varnish instance name\n" + "-p param_name Specify the parameter to check (see below).\n" + " The default is 'ratio'.\n" + "-c [@][lo:]hi Set critical threshold\n" + "-w [@][lo:]hi Set warning threshold\n" + "\n" + "All items reported by varnishstat(1) are available - use the\n" + "identifier listed in the left column by 'varnishstat -l'.\n" + "\n" + "Examples for Varnish 3.x:\n" + "\n" + "uptime How long the cache has been running (in seconds)\n" + "ratio The cache hit ratio expressed as a percentage of hits to\n" + " hits + misses. Default thresholds are 95 and 90.\n" + "usage Cache file usage as a percentage of the total cache space.\n" + "\n" + "Examples for Varnish 4.x:\n" + "\n" + "ratio The cache hit ratio expressed as a percentage of hits to\n" + " hits + misses. Default thresholds are 95 and 90.\n" + "MAIN.uptime How long the cache has been running (in seconds).\n" + "MAIN.n_purges Number of purge operations executed.\n" + ); + exit(0); +} + +static void +usage(void) +{ + + fprintf(stderr, "usage: " + "check_varnish [-lv] [-n varnish_name] [-p param_name [-c N] [-w N]]\n"); + exit(3); +} + + +int +main(int argc, char **argv) +{ + struct VSM_data *vd; + char *param = NULL; + int opt; + + setlocale(LC_ALL, ""); + + vd = VSM_New(); +#if defined(HAVE_VARNISHAPI_3) + VSC_Setup(vd); +#endif + + while ((opt = getopt(argc, argv, VSC_ARGS "c:hn:p:vw:")) != -1) { + switch (opt) { + case 'c': + if (parse_range(optarg, &critical) != 0) + usage(); + break; + case 'h': + help(); + break; + case 'n': + VSC_Arg(vd, opt, optarg); + break; + case 'p': + param = strdup(optarg); + break; + case 'v': + ++verbose; + break; + case 'w': + if (parse_range(optarg, &warning) != 0) + usage(); + break; + default: + if (VSC_Arg(vd, opt, optarg) > 0) + break; + usage(); + } + } + +#if defined(HAVE_VARNISHAPI_4) || defined(HAVE_VARNISHAPI_4_1) + if (VSM_Open(vd)) + exit(1); +#elif defined(HAVE_VARNISHAPI_3) + if (VSC_Open(vd, 1)) + exit(1); +#endif + + /* Default: if no param specified, check hit ratio. If no warning + * and critical values are specified either, set these to default. + */ + if (param == NULL) { + param = strdup("ratio"); + if (!warning.defined) + parse_range("95:", &warning); + if (!critical.defined) + parse_range("90:", &critical); + } + + if (!param) + usage(); + + check_stats(vd, param); + + exit(0); +} -- cgit v1.2.3