#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2016             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk 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 in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA

# Special thanks to Rene Stolle (r.stolle@funkemedien.de)

#   .--agent output--------------------------------------------------------.
#   |                           _                 _               _        |
#   |     __ _  __ _  ___ _ __ | |_    ___  _   _| |_ _ __  _   _| |_      |
#   |    / _` |/ _` |/ _ \ '_ \| __|  / _ \| | | | __| '_ \| | | | __|     |
#   |   | (_| | (_| |  __/ | | | |_  | (_) | |_| | |_| |_) | |_| | |_      |
#   |    \__,_|\__, |\___|_| |_|\__|  \___/ \__,_|\__| .__/ \__,_|\__|     |
#   |          |___/                                 |_|                   |
#   '----------------------------------------------------------------------'

# <<<varnish>>>
# client_conn           13687134         4.41 Client connections accepted
# client_drop                  0         0.00 Connection dropped, no sess/wrk
# client_req            22397280         7.21 Client requests received
# cache_hit                 3678         0.00 Cache hits
# cache_hitpass                0         0.00 Cache hits for pass
# cache_miss                5687         0.00 Cache misses
# backend_conn           6870153         2.21 Backend conn. success
# backend_unhealthy            0         0.00 Backend conn. not attempted
# backend_busy                 0         0.00 Backend conn. too many
# backend_fail                 0         0.00 Backend conn. failures
# backend_reuse         15528248         5.00 Backend conn. reuses
# backend_toolate           6235         0.00 Backend conn. was closed
# backend_recycle       15534489         5.00 Backend conn. recycles
# backend_retry               46         0.00 Backend conn. retry
# fetch_head                2026         0.00 Fetch head
# fetch_length            262203         0.08 Fetch with Length
# fetch_chunked         15034709         4.84 Fetch chunked
# fetch_eof                    0         0.00 Fetch EOF
# fetch_bad                    0         0.00 Fetch had bad headers
# fetch_close                  0         0.00 Fetch wanted close
# fetch_oldhttp                0         0.00 Fetch pre HTTP/1.1 closed
# fetch_zero                   0         0.00 Fetch zero len
# fetch_failed                 0         0.00 Fetch failed
# fetch_1xx                    0         0.00 Fetch no body (1xx)
# fetch_204                    0         0.00 Fetch no body (204)
# fetch_304               242534         0.08 Fetch no body (304)
# n_sess_mem              100000          .   N struct sess_mem
# n_sess                  205470          .   N struct sess
# n_object                     5          .   N struct object
# n_vampireobject              0          .   N unresurrected objects
# n_objectcore               101          .   N struct objectcore
# n_objecthead               104          .   N struct objecthead
# n_waitinglist             1655          .   N struct waitinglist
# n_vbc                       60          .   N struct vbc
# n_wrk                     1000          .   N worker threads
# n_wrk_create              1000         0.00 N worker threads created
# n_wrk_failed                 0         0.00 N worker threads not created
# n_wrk_max                  893         0.00 N worker threads limited
# n_wrk_lqueue                 0         0.00 work request queue length
# n_wrk_queued                21         0.00 N queued work requests
# n_wrk_drop                   0         0.00 N dropped work requests
# n_backend                    2          .   N backends
# n_expired                 5680          .   N expired objects
# n_lru_nuked                  0          .   N LRU nuked objects
# n_lru_moved               1031          .   N LRU moved objects
# losthdr                      0         0.00 HTTP header overflows
# n_objsendfile                0         0.00 Objects sent with sendfile
# n_objwrite            15303178         4.93 Objects sent with write
# n_objoverflow                0         0.00 Objects overflowing workspace
# s_sess                13687207         4.41 Total Sessions
# s_req                 22397280         7.21 Total Requests
# s_pipe                 6856634         2.21 Total pipe
# s_pass                15536150         5.00 Total pass
# s_fetch               15535049         5.00 Total fetch
# s_hdrbytes          2623427334       844.71 Total header bytes
# s_bodybytes        64229472478     20681.18 Total body bytes
# sess_closed           13154452         4.24 Session Closed
# sess_pipeline                0         0.00 Session Pipeline
# sess_readahead               0         0.00 Session Read Ahead
# sess_linger           15526026         5.00 Session Linger
# sess_herd             14211876         4.58 Session herd
# shm_records         1455193814       468.56 SHM records
# shm_writes           117694273        37.90 SHM writes
# shm_flushes                  0         0.00 SHM flushes due to overflow
# shm_cont               1081665         0.35 SHM MTX contention
# shm_cycles                 646         0.00 SHM cycles through buffer
# sms_nreq                  1919         0.00 SMS allocator requests
# sms_nobj                     0          .   SMS outstanding allocations
# sms_nbytes                   0          .   SMS outstanding bytes
# sms_balloc              708111          .   SMS bytes allocated
# sms_bfree               708111          .   SMS bytes freed
# backend_req           15541595         5.00 Backend requests made
# n_vcl                        1         0.00 N vcl total
# n_vcl_avail                  1         0.00 N vcl available
# n_vcl_discard                0         0.00 N vcl discarded
# n_ban                        1          .   N total active bans
# n_ban_add                    1         0.00 N new bans added
# n_ban_retire                 0         0.00 N old bans deleted
# n_ban_obj_test               0         0.00 N objects tested
# n_ban_re_test                0         0.00 N regexps tested against
# n_ban_dups                   0         0.00 N duplicate bans removed
# hcb_nolock                9355         0.00 HCB Lookups without lock
# hcb_lock                  5679         0.00 HCB Lookups with lock
# hcb_insert                5535         0.00 HCB Inserts
# esi_errors                   0         0.00 ESI parse errors (unlock)
# esi_warnings                 0         0.00 ESI parse warnings (unlock)
# accept_fail                  0         0.00 Accept failures
# client_drop_late             0         0.00 Connection dropped late
# uptime                 3105696         1.00 Client uptime
# dir_dns_lookups              0         0.00 DNS director lookups
# dir_dns_failed               0         0.00 DNS director failed lookups
# dir_dns_hit                  0         0.00 DNS director cached lookups hit
# dir_dns_cache_full           0         0.00 DNS director full dnscache
# vmods                        1          .   Loaded VMODs
# n_gzip                       0         0.00 Gzip operations
# n_gunzip                 82386         0.03 Gunzip operations
# LCK.sms.creat                1         0.00 Created locks
# LCK.sms.destroy              0         0.00 Destroyed locks
# LCK.sms.locks             5757         0.00 Lock Operations
# LCK.sms.colls                0         0.00 Collisions
# LCK.smp.creat                0         0.00 Created locks
# LCK.smp.destroy              0         0.00 Destroyed locks
# LCK.smp.locks                0         0.00 Lock Operations
# LCK.smp.colls                0         0.00 Collisions
# LCK.sma.creat                2         0.00 Created locks
# LCK.sma.destroy              0         0.00 Destroyed locks
# LCK.sma.locks         76782194        24.72 Lock Operations
# LCK.sma.colls                0         0.00 Collisions
# LCK.smf.creat                0         0.00 Created locks
# LCK.smf.destroy              0         0.00 Destroyed locks
# LCK.smf.locks                0         0.00 Lock Operations
# LCK.smf.colls                0         0.00 Collisions
# LCK.hsl.creat                0         0.00 Created locks
# LCK.hsl.destroy              0         0.00 Destroyed locks
# LCK.hsl.locks                0         0.00 Lock Operations
# LCK.hsl.colls                0         0.00 Collisions
# LCK.hcb.creat                1         0.00 Created locks
# LCK.hcb.destroy              0         0.00 Destroyed locks
# LCK.hcb.locks            28463         0.01 Lock Operations
# LCK.hcb.colls                0         0.00 Collisions
# LCK.hcl.creat                0         0.00 Created locks
# LCK.hcl.destroy              0         0.00 Destroyed locks
# LCK.hcl.locks                0         0.00 Lock Operations
# LCK.hcl.colls                0         0.00 Collisions
# LCK.vcl.creat                1         0.00 Created locks
# LCK.vcl.destroy              0         0.00 Destroyed locks
# LCK.vcl.locks             2849         0.00 Lock Operations
# LCK.vcl.colls                0         0.00 Collisions
# LCK.stat.creat               1         0.00 Created locks
# LCK.stat.destroy             0         0.00 Destroyed locks
# LCK.stat.locks          100000         0.03 Lock Operations
# LCK.stat.colls               0         0.00 Collisions
# LCK.sessmem.creat            1         0.00 Created locks
# LCK.sessmem.destroy            0         0.00 Destroyed locks
# LCK.sessmem.locks       13787845         4.44 Lock Operations
# LCK.sessmem.colls              0         0.00 Collisions
# LCK.wstat.creat                1         0.00 Created locks
# LCK.wstat.destroy              0         0.00 Destroyed locks
# LCK.wstat.locks          9610148         3.09 Lock Operations
# LCK.wstat.colls                0         0.00 Collisions
# LCK.herder.creat               1         0.00 Created locks
# LCK.herder.destroy             0         0.00 Destroyed locks
# LCK.herder.locks               1         0.00 Lock Operations
# LCK.herder.colls               0         0.00 Collisions
# LCK.wq.creat                   2         0.00 Created locks
# LCK.wq.destroy                 0         0.00 Destroyed locks
# LCK.wq.locks            60930521        19.62 Lock Operations
# LCK.wq.colls                   0         0.00 Collisions
# LCK.objhdr.creat            5628         0.00 Created locks
# LCK.objhdr.destroy          5528         0.00 Destroyed locks
# LCK.objhdr.locks           50484         0.02 Lock Operations
# LCK.objhdr.colls               0         0.00 Collisions
# LCK.exp.creat                  1         0.00 Created locks
# LCK.exp.destroy                0         0.00 Destroyed locks
# LCK.exp.locks            3116794         1.00 Lock Operations
# LCK.exp.colls                  0         0.00 Collisions
# LCK.lru.creat                  2         0.00 Created locks
# LCK.lru.destroy                0         0.00 Destroyed locks
# LCK.lru.locks               5685         0.00 Lock Operations
# LCK.lru.colls                  0         0.00 Collisions
# LCK.cli.creat                  1         0.00 Created locks
# LCK.cli.destroy                0         0.00 Destroyed locks
# LCK.cli.locks            1034578         0.33 Lock Operations
# LCK.cli.colls                  0         0.00 Collisions
# LCK.ban.creat                  1         0.00 Created locks
# LCK.ban.destroy                0         0.00 Destroyed locks
# LCK.ban.locks            3116799         1.00 Lock Operations
# LCK.ban.colls                  0         0.00 Collisions
# LCK.vbp.creat                  1         0.00 Created locks
# LCK.vbp.destroy                0         0.00 Destroyed locks
# LCK.vbp.locks                  0         0.00 Lock Operations
# LCK.vbp.colls                  0         0.00 Collisions
# LCK.vbe.creat                  1         0.00 Created locks
# LCK.vbe.destroy                0         0.00 Destroyed locks
# LCK.vbe.locks           13740586         4.42 Lock Operations
# LCK.vbe.colls                  0         0.00 Collisions
# LCK.backend.creat              2         0.00 Created locks
# LCK.backend.destroy            0         0.00 Destroyed locks
# LCK.backend.locks       51685293        16.64 Lock Operations
# LCK.backend.colls              0         0.00 Collisions
# SMA.s0.c_req               13215         0.00 Allocator requests
# SMA.s0.c_fail                  0         0.00 Allocator failures
# SMA.s0.c_bytes         959888353       309.07 Bytes allocated
# SMA.s0.c_freed         959475615       308.94 Bytes freed
# SMA.s0.g_alloc                12          .   Allocations outstanding
# SMA.s0.g_bytes            412738          .   Bytes outstanding
# SMA.s0.g_space         268022718          .   Bytes available
# SMA.Transient.c_req     30821613         9.92 Allocator requests
# SMA.Transient.c_fail           0         0.00 Allocator failures
# SMA.Transient.c_bytes 2049827454520    660021.93 Bytes allocated
# SMA.Transient.c_freed 2049827454520    660021.93 Bytes freed
# SMA.Transient.g_alloc            0          .   Allocations outstanding
# SMA.Transient.g_bytes            0          .   Bytes outstanding
# SMA.Transient.g_space            0          .   Bytes available
# VBE.default(127.0.0.1,,81).vcls            1          .   VCL references
# VBE.default(127.0.0.1,,81).happy           0          .   Happy health probes
# VBE.name(xxx.xxx.xxx.xxx,,80).vcls            1          .   VCL references
# VBE.name(xxx.xxx.xxx.xxx,,80).happy           0          .   Happy health probes

#.
#   .--uptime--------------------------------------------------------------.
#   |                              _   _                                   |
#   |                  _   _ _ __ | |_(_)_ __ ___   ___                    |
#   |                 | | | | '_ \| __| | '_ ` _ \ / _ \                   |
#   |                 | |_| | |_) | |_| | | | | | |  __/                   |
#   |                  \__,_| .__/ \__|_|_| |_| |_|\___|                   |
#   |                       |_|                                            |
#   +----------------------------------------------------------------------+
#   |                             main check                               |
#   '----------------------------------------------------------------------'


def parse_varnish(info):
    parsed = {}
    for line in info:
        if "." in line[0]:
            what, what_item = line[0].split(".", 1)
        elif "_" in line[0]:
            what, what_item = line[0].split("_", 1)
        else:
            what, what_item = line[0], None

        if what.lower() == line[3].lower():
            descr = " ".join(line[4:]).replace("/", " ")
        else:
            descr = " ".join(line[3:]).replace("/", " ")

        if what_item:
            parsed.setdefault(what, {})
            parsed[what].setdefault(what_item, (float(line[1]), descr))
        else:
            parsed.setdefault(what, (float(line[1]), descr))

    return parsed


def inventory_varnish_uptime(parsed):
    if "uptime" in parsed:
        return [(None, None)]


def check_varnish_uptime(_no_item, _no_params, parsed):
    if "uptime" in parsed:
        return check_uptime_seconds(_no_params, parsed["uptime"][0])


check_info["varnish"] = {
    "parse_function"        : parse_varnish,
    "inventory_function"    : inventory_varnish_uptime,
    "check_function"        : check_varnish_uptime,
    "service_description"   : "Varnish Uptime",
    "has_perfdata"          : True,
    "includes"              : [ "uptime.include" ],
}


#.
#   .--common--------------------------------------------------------------.
#   |                                                                      |
#   |               ___ ___  _ __ ___  _ __ ___   ___  _ __                |
#   |              / __/ _ \| '_ ` _ \| '_ ` _ \ / _ \| '_ \               |
#   |             | (_| (_) | | | | | | | | | | | (_) | | | |              |
#   |              \___\___/|_| |_| |_|_| |_| |_|\___/|_| |_|              |
#   |                                                                      |
#   '----------------------------------------------------------------------'


def inventory_varnish(parsed, what, needed_keys):
    if what in parsed:
        needed_keys_avail = True
        for needed_key in needed_keys:
            if needed_key not in parsed[what]:
                needed_keys_avail = False
        if needed_keys_avail == True:
            return [ (None, {}) ]


# use selection to get list of keys from parsed[what] or in case of None all keys
def check_varnish_stats(_no_item, params, parsed, what, selection):
    if what in parsed:
        this_time = time.time()

        whatitemlist = parsed[what]
        if selection:
            whatitemlist = [ whatitem
                for key in selection
                for whatitem in whatitemlist
                if whatitem.startswith(key)
            ]

        for whatitem in whatitemlist:
            state = 0
            reading, descr = parsed[what][whatitem]
            rate = get_rate("varnish.%s.%s" % (what, whatitem), this_time, reading)
            infotext = "%0.1f %s/s" % (rate, descr)

            perfvar = "varnish_%s_%s_rate" % (what, whatitem)
            if perfvar.startswith("varnish_n_wrk"):
                perfvar = perfvar.replace("n_wrk", "worker")
            elif perfvar.startswith("varnish_n_"):
                perfvar = perfvar.replace("n_", "objects_")
            perfdata = []

            if params.get(whatitem):
                warn, crit = params[whatitem]
                if rate >= crit:
                    state = 2
                elif rate >= warn:
                    state = 1
                if state > 0:
                    infotext += " (warn/crit at %s/%s)" % (warn, crit)
                perfdata.append((perfvar, rate, warn, crit))
            else:
                perfdata.append((perfvar, rate))

            yield state, infotext, perfdata


def check_varnish_ratio(_no_item, params, parsed, what, ratio_info):
    if what in parsed:
        state = 0
        ratio = 0.0
        total = parsed[what][ratio_info[0]][0] + parsed[what][ratio_info[1]][0]
        if total > 0:
            ratio = parsed[what][ratio_info[0]][0] / total * 100

        infotext   = "%.1f%%" % ratio
        warn, crit = params["levels_lower"]

        if ratio < crit:
            state = 2
        elif ratio < warn:
            state = 1
        if state > 0:
            infotext += " (warn/crit below %.1f%%/%.1f%%)" % (warn, crit)

        return state, infotext, [(ratio_info[2], ratio, warn, crit)]


#.
#   .--cache---------------------------------------------------------------.
#   |                                     _                                |
#   |                       ___ __ _  ___| |__   ___                       |
#   |                      / __/ _` |/ __| '_ \ / _ \                      |
#   |                     | (_| (_| | (__| | | |  __/                      |
#   |                      \___\__,_|\___|_| |_|\___|                      |
#   |                                                                      |
#   '----------------------------------------------------------------------'


check_info["varnish.cache"] = {
    "inventory_function"      : lambda parsed: \
        inventory_varnish(parsed, "cache", ["miss"]),
    "check_function"          : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "cache", None),
    "service_description"     : "Varnish Cache",
    "group"                   : "varnish_cache",
    "has_perfdata"            : True,
}


#.
#   .--client--------------------------------------------------------------.
#   |                            _ _            _                          |
#   |                        ___| (_) ___ _ __ | |_                        |
#   |                       / __| | |/ _ \ '_ \| __|                       |
#   |                      | (__| | |  __/ | | | |_                        |
#   |                       \___|_|_|\___|_| |_|\__|                       |
#   |                                                                      |
#   '----------------------------------------------------------------------'


check_info["varnish.client"] = {
    "inventory_function"  : lambda parsed: \
        inventory_varnish(parsed, "client", ["req"]),
    "check_function"      : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "client", None),
    "service_description" : "Varnish Client",
    "group"               : "varnish_client",
    "has_perfdata"        : True,
}


#.
#   .--backend-------------------------------------------------------------.
#   |                _                _                  _                 |
#   |               | |__   __ _  ___| | _____ _ __   __| |                |
#   |               | '_ \ / _` |/ __| |/ / _ \ '_ \ / _` |                |
#   |               | |_) | (_| | (__|   <  __/ | | | (_| |                |
#   |               |_.__/ \__,_|\___|_|\_\___|_| |_|\__,_|                |
#   |                                                                      |
#   '----------------------------------------------------------------------'


check_info["varnish.backend"] = {
    "inventory_function"  : lambda parsed: \
        inventory_varnish(parsed, "backend", ["fail", "unhealthy", "busy"]),
    "check_function"      : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "backend", None),
    "service_description" : "Varnish Backend",
    "group"               : "varnish_backend",
    "has_perfdata"        : True,
}


#.
#   .--fetch---------------------------------------------------------------.
#   |                        __      _       _                             |
#   |                       / _| ___| |_ ___| |__                          |
#   |                      | |_ / _ \ __/ __| '_ \                         |
#   |                      |  _|  __/ || (__| | | |                        |
#   |                      |_|  \___|\__\___|_| |_|                        |
#   |                                                                      |
#   '----------------------------------------------------------------------'


check_info["varnish.fetch"] = {
    "inventory_function"  : lambda parsed: \
        inventory_varnish(parsed, "fetch", ["1xx", "204", "304", "bad", "eof", "failed", "zero"]),
    "check_function"      : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "fetch", None),
    "service_description" : "Varnish Fetch",
    "group"               : "varnish_fetch",
    "has_perfdata"        : True,
}


#.
#   .--ESI-----------------------------------------------------------------.
#   |                           _____ ____ ___                             |
#   |                          | ____/ ___|_ _|                            |
#   |                          |  _| \___ \| |                             |
#   |                          | |___ ___) | |                             |
#   |                          |_____|____/___|                            |
#   |                                                                      |
#   '----------------------------------------------------------------------'


factory_settings["varnish_esi_default_levels"] = {
    'errors': (1.0, 2.0)
}


check_info["varnish.esi"] = {
    "inventory_function"      : lambda parsed: \
        inventory_varnish(parsed, "esi", ["errors"]),
    "check_function"          : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "esi", None),
    "service_description"     : "Varnish ESI",
    "default_levels_variable" : "varnish_esi_default_levels",
    "group"                   : "varnish_esi",
    "has_perfdata"            : True,
}


#.
#   .--objects-------------------------------------------------------------.
#   |                         _     _           _                          |
#   |                    ___ | |__ (_) ___  ___| |_ ___                    |
#   |                   / _ \| '_ \| |/ _ \/ __| __/ __|                   |
#   |                  | (_) | |_) | |  __/ (__| |_\__ \                   |
#   |                   \___/|_.__// |\___|\___|\__|___/                   |
#   |                            |__/                                      |
#   '----------------------------------------------------------------------'


check_info["varnish.objects"] = {
    "inventory_function"  : lambda parsed: \
        inventory_varnish(parsed, "n", ["expired", "lru_nuked"]),
    "check_function"      : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "n", ["expired", "lru_"]),
    "service_description" : "Varnish Objects",
    "group"               : "varnish_objects",
    "has_perfdata"        : True,
}


#.
#   .--worker--------------------------------------------------------------.
#   |                                     _                                |
#   |                 __      _____  _ __| | _____ _ __                    |
#   |                 \ \ /\ / / _ \| '__| |/ / _ \ '__|                   |
#   |                  \ V  V / (_) | |  |   <  __/ |                      |
#   |                   \_/\_/ \___/|_|  |_|\_\___|_|                      |
#   |                                                                      |
#   '----------------------------------------------------------------------'


check_info["varnish.worker"] = {
    "inventory_function"  : lambda parsed: \
        inventory_varnish(parsed, "n", ["wrk_failed", "wrk_queued", "wrk_drop"]),
    "check_function"      : lambda item, params, parsed: \
        check_varnish_stats(item, params, parsed, "n", ["wrk"]),
    "service_description" : "Varnish Worker",
    "group"               : "varnish_worker",
    "has_perfdata"        : True,
}


#.
#   .--cache hit ratio-----------------------------------------------------.
#   |                  _            _     _ _               _   _          |
#   |    ___ __ _  ___| |__   ___  | |__ (_) |_   _ __ __ _| |_(_) ___     |
#   |   / __/ _` |/ __| '_ \ / _ \ | '_ \| | __| | '__/ _` | __| |/ _ \    |
#   |  | (_| (_| | (__| | | |  __/ | | | | | |_  | | | (_| | |_| | (_) |   |
#   |   \___\__,_|\___|_| |_|\___| |_| |_|_|\__| |_|  \__,_|\__|_|\___/    |
#   |                                                                      |
#   '----------------------------------------------------------------------'


factory_settings["varnish_cache_hit_ratio_default_levels"] = {
    'levels_lower': (70.0, 60.0)
}


check_info["varnish.cache_hit_ratio"] = {
    "inventory_function"      : lambda parsed: \
        inventory_varnish(parsed, "cache", ["hit", "miss"]),
    "check_function"          : lambda item, params, parsed: \
        check_varnish_ratio(item, params, parsed, 'cache', ('hit', 'miss', 'cache_hit_ratio')),
    "default_levels_variable" : "varnish_cache_hit_ratio_default_levels",
	"service_description"     : "Varnish Cache Hit Ratio",
    "group"                   : "varnish_cache_hit_ratio",
    "has_perfdata"            : True,
}


#.
#   .--backend success ratio-----------------------------------------------.
#   |                _                _                  _                 |
#   |               | |__   __ _  ___| | _____ _ __   __| |                |
#   |               | '_ \ / _` |/ __| |/ / _ \ '_ \ / _` |                |
#   |               | |_) | (_| | (__|   <  __/ | | | (_| |                |
#   |               |_.__/ \__,_|\___|_|\_\___|_| |_|\__,_|                |
#   |                                                                      |
#   |                                                   _   _              |
#   |       ___ _   _  ___ ___ ___  ___ ___   _ __ __ _| |_(_) ___         |
#   |      / __| | | |/ __/ __/ _ \/ __/ __| | '__/ _` | __| |/ _ \        |
#   |      \__ \ |_| | (_| (_|  __/\__ \__ \ | | | (_| | |_| | (_) |       |
#   |      |___/\__,_|\___\___\___||___/___/ |_|  \__,_|\__|_|\___/        |
#   |                                                                      |
#   '----------------------------------------------------------------------'


factory_settings["varnish_backend_success_ratio_default_levels"] = {
    'levels_lower': (70.0, 60.0)
}


check_info["varnish.backend_success_ratio"] = {
    "inventory_function"      : lambda parsed: \
        inventory_varnish(parsed, "backend", ["fail", "conn"]),
    "check_function"          : lambda item, params, parsed: \
        check_varnish_ratio(item, params, parsed, 'backend', ('conn', 'fail', 'varnish_backend_success_ratio')),
    "default_levels_variable" : "varnish_backend_success_ratio_default_levels",
	"service_description"     : "Varnish Backend Success Ratio",
    "group"                   : "varnish_backend_success_ratio",
    "has_perfdata"            : True,
}


#.
#   .--worker thread ratio-------------------------------------------------.
#   |                     _               _   _                        _   |
#   | __      _____  _ __| | _____ _ __  | |_| |__  _ __ ___  __ _  __| |  |
#   | \ \ /\ / / _ \| '__| |/ / _ \ '__| | __| '_ \| '__/ _ \/ _` |/ _` |  |
#   |  \ V  V / (_) | |  |   <  __/ |    | |_| | | | | |  __/ (_| | (_| |  |
#   |   \_/\_/ \___/|_|  |_|\_\___|_|     \__|_| |_|_|  \___|\__,_|\__,_|  |
#   |                                                                      |
#   |                                  _   _                               |
#   |                        _ __ __ _| |_(_) ___                          |
#   |                       | '__/ _` | __| |/ _ \                         |
#   |                       | | | (_| | |_| | (_) |                        |
#   |                       |_|  \__,_|\__|_|\___/                         |
#   |                                                                      |
#   '----------------------------------------------------------------------'


factory_settings["varnish_worker_thread_ratio_default_levels"] = {
    'levels_lower' : (70.0, 60.0)
}


def check_varnish_worker_thread_ratio(_no_item, params, parsed):
    if "n" in parsed:
        state = 0
        ratio = 0.0

        if parsed["n"]["wrk_create"][0] > 0:
            ratio = parsed["n"]["wrk"][0] / parsed["n"]["wrk_create"][0] * 100

        infotext = "%.1f%%" % ratio
        warn, crit = params["levels_lower"]

        if ratio < crit:
            state = 2
        elif ratio < warn:
            state = 1
        if state > 0:
            infotext += " (warn/crit below %.1f%%/%.1f%%)" % (warn, crit)

        return state, infotext, [("varnish_worker_thread_ratio", ratio, warn, crit)]


check_info["varnish.worker_thread_ratio"] = {
    "inventory_function"      : lambda parsed: \
        inventory_varnish(parsed, "n", ["wrk", "wrk_create"]),
    "check_function"          : check_varnish_worker_thread_ratio,
    "service_description"     : "Varnish Worker Thread Ratio",
    "default_levels_variable" : "varnish_worker_thread_ratio_default_levels",
    "group"                   : "varnish_worker_thread_ratio",
    "has_perfdata"            : True,
}
