I needed a quick and dirty check for the pfSense’s "State Table" via SNMP as I sometimes have the strange problem that it gets full and then I lose internet-connection. If the thresholds are hit and I am alerted, I hope I have time to investigate what is going wrong.
The Check
The default values for the searches is much too low – you can set it by a rule later to about 1000000/2000000. Perfdata graphs can be optionally turned on or off.
#!/usr/bin/env python
#
# Copyright 2020, Clemens Steinkogler <c.steinkogler[at]steinkogler.org>
#
# 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, either version 3 of the License, or
# (at your option) any later version.
# 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, see <http://www.gnu.org/licenses/>.
#
# pfStateTable .1.3.6.1.4.1.12325.1.200.1.3
# pfStateTableCount .1.3.6.1.4.1.12325.1.200.1.3.1
# pfStateTableSearches .1.3.6.1.4.1.12325.1.200.1.3.2
# pfStateTableInserts .1.3.6.1.4.1.12325.1.200.1.3.3
# pfStateTableRemovals .1.3.6.1.4.1.12325.1.200.1.3.4
from pprint import pprint
# factory_settings ... is part of version/share/check_mk/modules/check_mk.py
# ((warn, crit), perfdata)
factory_settings["check_pfsense_state_table_default_values"] = {
'config': ((10000, 20000), False)
}
def inventory_check_pfsense_state_table(info):
# debug
# print(info[0])
# we check for 4 values
if len(info[0]) == 4:
# return the different tablestates-names with warn/crit tuples set to None
return (
("count", "check_pfsense_state_table_default_values"),
("searches", "check_pfsense_state_table_default_values"),
("inserts", "check_pfsense_state_table_default_values"),
("removals", "check_pfsense_state_table_default_values")
)
# endif
# enddef
def check_pfsense_state_table(item, params, info):
state = 0
check_state_output = []
perfdata = None
# debug
#print(item)
#pprint(params)
# value_type can be "gauge" (default) or "counter"
def check_state(item_name, item_value, item_params, value_type="gauge"):
item_value = int(item_value)
diff_item_value = 0
item_warn_value = item_params['config'][0][0]
item_crit_value = item_params['config'][0][1]
item_perfdata_switch = item_params['config'][1]
# debug
#print(value_type)
if value_type == "gauge":
# debug
#pprint(item_params)
#pprint(item_warn_value)
#pprint(item_crit_value)
#pprint(item_perfdata_switch)
if item_perfdata_switch:
perfdata_part = [(item_name, item_value, item_warn_value, item_crit_value)]
else:
perfdata_part = None
# endif
else:
# * we get the last value from the counter-file if possible into var last_counter_value
# * else we save it in counter-file and return no perfdata
# * if new value is smaller than old value, the firewall must have been reset, we add the current value to last one
# * if new value is larger than old value, we calculate the difference between them
# * at the end we save the current value
first_value = False
last_counter_value = get_item_state(item_name)
if last_counter_value is None:
set_item_state(item_name, item_value)
first_value = True
perfdata_part = None
else:
# debug
#pprint(last_counter_value)
if item_value < last_counter_value:
diff_item_value = item_value + last_counter_value
else:
diff_item_value = item_value - last_counter_value
# endif
set_item_state(item_name, item_value)
# we replace the real item_value with the calculated difference
item_value = diff_item_value
# debug
#print(perfdata_part)
# endif
if item_perfdata_switch:
if not first_value:
perfdata_part = [(item_name, diff_item_value, item_warn_value, item_crit_value)]
else:
perfdata_part = None
# endif
# endif
if item_value >= item_crit_value:
state = 2
elif item_warn_value <= item_value < item_crit_value:
state = 1
elif item_value < item_warn_value:
state = 0
else:
state = 3
# endif
if state == 0:
message_part = "%s %d %s" % (item_name, item_value, "(.)")
elif state == 1:
message_part = "%s %d %s" % (item_name, item_value, "(!)")
elif state == 2:
message_part = "%s %d %s" % (item_name, item_value, "(!!)")
else:
message_part = "%s %d %s" % (item_name, item_value, "(?)")
# endif
# debug
#print(message_part)
return state, message_part, perfdata_part
# enddef
if len(info[0]) == 4:
info_i = {"count": 0, "searches": 1, "inserts": 2, "removals": 3}
if item == "count":
check_state_output = check_state(item, info[0][info_i[item]], params, "gauge")
else:
check_state_output = check_state(item, info[0][info_i[item]], params, "counter")
# endif
# endif
# debug
#print(check_state_output[1])
state = check_state_output[0]
message = check_state_output[1]
perfdata = check_state_output[2]
return state, message, perfdata
# enddef
check_info["check_pfsense_state_table"] = {
"has_perfdata": True,
"default_levels_variable": "check_pfsense_state_table_default_values",
"group": "check_pfsense_state_table",
"check_function": check_pfsense_state_table,
"inventory_function": inventory_check_pfsense_state_table,
"service_description": "pfSense StateTable",
"snmp_info": (".1.3.6.1.4.1.12325.1.200.1.3", ["1", "2", "3", "4"])
}
The WATO-Parameters Config
# Copyright 2020, Clemens Steinkogler <c.steinkogler[at]steinkogler.org>
#
# 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, either version 3 of the License, or
# (at your option) any later version.
# 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, see <http://www.gnu.org/licenses/>.
group = "checkparams"
subgroup_applications = _("Applications, Processes & Services")
register_check_parameters(
subgroup_applications,
"check_pfsense_state_table",
_("pfSense State Table Levels"),
Dictionary(
elements=[
("config",
Tuple(
title=_("Config for Service"),
elements=[
Optional(
Tuple(
elements=[
Integer(
title=_("Warning Level"),
default_value=10000
),
Integer(
title=_("Critical Level"),
default_value=20000
),
]
),
label=_("Warn-/Crit-Levels"),
none_label=_("Using default values"),
none_value=(10000, 20000)
),
DropdownChoice(
title=_("Create graph"),
choices=[
(False, _("No")),
(True, _("Yes")),
],
default_value=False
),
]
),
),
]
),
TextAscii(
title=_("Service description"),
allow_empty=False,
),
"dict"
)
Kommentare