#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2014             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.

# Author: Lars Michelsen <lm@mathias-kettner.de>

# Example output from agent:
#
# <<<postfix_mailq>>>
# -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
# CA29995448EB     4638 Fri Jul  2 14:39:01  nagios
#                                          donatehosts@mathias-kettner.de
#
# E085095448EC      240 Fri Jul  2 14:40:01  root
#                                          lm@mathias-kettner.de
#
# D9EBC95448EE     4804 Fri Jul  2 14:40:03  nagios
#                                          donatehosts@mathias-kettner.de
#
# -- 9 Kbytes in 3 Requests.
#
#
# **************
#
# <<<postfix_mailq>>>
# -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
# 748C8C3D4AB     1436 Fri Jul  2 16:39:10  lm@mathias-kettner.de
#      (connect to mail.larsmichelsen.com[78.46.117.178]:25: Connection refused)
#                                          lm@larsmichelsen.com
#
# -- 1 Kbytes in 1 Request.
#
# Yet another one (I believe, this is from sendmail, though:)
# <<<postfix_mailq>>>
#       8BITMIME   (Deferred: Connection refused by mail.gargl.com.)
#                                          <franz@gargle.com>
# q1L4ovDO002485     3176 Tue Feb 21 05:50 MAILER-DAEMON
#                  (Deferred: 451 Try again later)
#                                          <wrdlpfrmpft@karl-valentin.com>
#                 Total requests: 2
#
# **************
# new format
# <<<postfix_mailq>>>
# QUEUE_deferred 60 1
# QUEUE_active 4 0

factory_settings['postfix_mailq_default_levels'] = {
    "deferred" : (10, 20),
    "active"   : (200, 300), # may become large for big mailservers
}

def inventory_postfix_mailq(info):
    if len(info) > 0 and info[0] != '':
        return [(None, {})]

def postfix_mailq_to_bytes(value, uom):
    uom = uom.lower()
    if uom == 'kbytes':
        return value * 1024
    elif uom == 'mbytes':
        return value * 1024 * 1024
    elif uom == 'gbytes':
        return value * 1024 * 1024 * 1024

def check_postfix_mailq(_no_item, params, info):
    if type(params) != dict:
        params = {
            "deferred" : params,
        }
    for line in info:
        state = 0
        # new extended version of agent output
        if line[0].startswith("QUEUE_"):
            queue = line[0].split("_")[1]

            # Deal with old agent (pre 1.2.8) which did not send size
            # infos in case of different error cases
            if len(line) == 2:
                size   = 0
                length = int(line[1]) # number of mails
            else:
                size   = int(line[1]) # in bytes
                length = int(line[2]) # number of mails
            infotext = "%s queue length is %d" % (queue, length)
            if queue == "deferred":
                length_var = "length"
                size_var = "size"
            else:
                length_var = "mail_queue_%s_length" % queue
                size_var = "mail_queue_%s_size" % queue
            if queue in params:
                warn, crit = params[queue]
                if length >= crit:
                    state = 2
                elif length >= warn:
                    state = 1
                if state:
                    infotext += " (Levels at %d/%d)" % (warn, crit)
                perfdata = [ (length_var, length, warn, crit) ]
            else:
                perfdata = [ (length_var, length) ]

            perfdata.append((size_var, size))

            yield state, infotext, perfdata

        # old output of mailq command for empty queue
        elif " ".join(line[-2:]) == 'is empty':
            warn, crit = params["deferred"]
            infotext = 'The mailqueue is empty'
            perfdata = [ ('length', 0, warn, crit),
                         ('size', 0) ]
            yield 0, infotext, perfdata

        # old output of mailq command
        elif line[0] == '--' or line[0:2] == [ 'Total', 'requests:']:
            warn, crit = params["deferred"]
            if line[0] == '--':
                size    = postfix_mailq_to_bytes(float(line[1]), line[2])
                length  = int(line[4])
            else:
                size    = 0
                length  = int(line[2])

            infotext = 'Mailqueue length is %d' % length
            perfdata = [ ('length', length, warn, crit),
                         ('size', size) ]

            if length >= crit:
                state = 2
            elif length >= warn:
                state = 1
            if state:
                infotext += " (warn/crit at %d/%d)" % (warn, crit)

            yield state, infotext, perfdata

check_info["postfix_mailq"] = {
    'check_function'          : check_postfix_mailq,
    'inventory_function'      : inventory_postfix_mailq,
    'service_description'     : 'Postfix Queue',
    'default_levels_variable' : 'postfix_mailq_default_levels',
    'group'                   : 'mailqueue_length',
    'has_perfdata'            : True,
}
