Module: check_mk
Branch: master
Commit: c155d8fac5f065d39747676fc643f5e73b3d11c0
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=c155d8fac5f065…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Fri Aug 21 12:29:43 2015 +0200
#2541 FIX Round last state change of network interfaces to one day, avoid history spam
This avoid massive changes in inventory every time the inventory is being run - thus
avoiding spamming the inventory history.
---
.werks/2541 | 11 +++++++++++
ChangeLog | 1 +
inventory/if | 10 +++++++++-
web/plugins/views/inventory.py | 22 +++++++++++++++++++++-
web/plugins/visuals/inventory.py | 29 +++++++++++++++++++++++------
5 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/.werks/2541 b/.werks/2541
new file mode 100644
index 0000000..f741268
--- /dev/null
+++ b/.werks/2541
@@ -0,0 +1,11 @@
+Title: Round last state change of network interfaces to one day, avoid history spam
+Level: 2
+Component: inv
+Class: fix
+Compatible: compat
+State: unknown
+Version: 1.2.7i3
+Date: 1440152923
+
+This avoid massive changes in inventory every time the inventory is being run - thus
+avoiding spamming the inventory history.
diff --git a/ChangeLog b/ChangeLog
index d1f39d7..6b5c485 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -209,6 +209,7 @@
* 2367 FIX: win_system: Fixed exception when non-UTF-8 sequences are contained agent
output
* 2483 FIX: win_exefiles: more gracefully handle incomplete lines, avoid execption
* 2454 FIX: lnx_distro: Fixed inventory for SuSE installations with patchlevel 0
+ * 2541 FIX: Round last state change of network interfaces to one day, avoid history
spam...
1.2.7i2:
diff --git a/inventory/if b/inventory/if
index 30ea0bc..78ff6c6 100644
--- a/inventory/if
+++ b/inventory/if
@@ -25,6 +25,12 @@
# Boston, MA 02110-1301 USA.
def inv_if(info, params):
+ def round_to_day(ts):
+ broken = time.localtime(ts)
+ return time.mktime((broken.tm_year, broken.tm_mon, broken.tm_mday, 0, 0, 0,
broken.tm_wday, broken.tm_yday, broken.tm_isdst))
+
+ now = time.time()
+
port_info, uptime_info = info
uptime = parse_snmp_uptime(uptime_info[0][0])
@@ -72,6 +78,8 @@ def inv_if(info, params):
# Assume point of time of boot as last state change.
state_age = uptime
+ last_change_timestamp = round_to_day(now - state_age)
+
node.append({
"index" : int(if_index),
"description" : if_descr,
@@ -81,7 +89,7 @@ def inv_if(info, params):
"oper_status" : int(if_oper_status),
"admin_status" : int(if_admin_status), # 1(up) or 2(down)
"port_type" : int(if_type),
- "state_age" : state_age,
+ "last_change" : int(last_change_timestamp),
})
diff --git a/web/plugins/views/inventory.py b/web/plugins/views/inventory.py
index af1beba..2aaeb0a 100644
--- a/web/plugins/views/inventory.py
+++ b/web/plugins/views/inventory.py
@@ -515,6 +515,26 @@ def inv_paint_age(age):
else:
return "", ""
+def inv_paint_timestamp_as_age(timestamp):
+ age = time.time() - timestamp
+ return inv_paint_age(age)
+
+def round_to_day(ts):
+ broken = time.localtime(ts)
+ return int(time.mktime((broken.tm_year, broken.tm_mon, broken.tm_mday, 0, 0, 0,
broken.tm_wday, broken.tm_yday, broken.tm_isdst)))
+
+def inv_paint_timestamp_as_age_days(timestamp):
+ now_day = round_to_day(time.time())
+ change_day = round_to_day(timestamp)
+ age_days = (now_day - change_day) / 86400
+
+ if age_days == 0:
+ return "", _("today")
+ elif age_days == 1:
+ return "", _("yesterday")
+ else:
+ return "", "%d %s ago" % (int(age_days),
_("days"))
+
inventory_displayhints.update({
"." : { "title" :
_("Inventory") },
".hardware." : { "title" :
_("Hardware"), "icon" : "hardware", },
@@ -636,7 +656,7 @@ inventory_displayhints.update({
".networking.interfaces:*.available" : { "title" :
_("Port Usage"), "short" : _("Used"), "paint" :
"if_available", "filter" : visuals.FilterInvtableAvailable },
".networking.interfaces:*.speed" : { "title" :
_("Speed"), "paint" : "nic_speed", },
".networking.interfaces:*.port_type" : { "title" :
_("Type"), "paint" : "if_port_type", "filter" :
visuals.FilterInvtableInterfaceType },
- ".networking.interfaces:*.state_age" : { "title" :
_("State Age"), "paint" : "age", "filter" :
visuals.FilterInvtableAge },
+ ".networking.interfaces:*.last_change" : { "title" :
_("Last Change"), "paint" : "timestamp_as_age_days",
"filter" : visuals.FilterInvtableTimestampAsAge },
})
# create painters for node with a display hint
diff --git a/web/plugins/visuals/inventory.py b/web/plugins/visuals/inventory.py
index d09597f..909f857 100644
--- a/web/plugins/visuals/inventory.py
+++ b/web/plugins/visuals/inventory.py
@@ -69,7 +69,7 @@ class FilterInvtableText(Filter):
# Filter for choosing a range in which an age lies
class FilterInvtableAge(Filter):
- def __init__(self, infoname, name, title):
+ def __init__(self, infoname, name, title, only_days=False):
name = infoname + "_" + name
Filter.__init__(self, name, title, infoname + "s", [name +
"_from", name + "_to"], [])
@@ -77,17 +77,20 @@ class FilterInvtableAge(Filter):
html.write("<table><tr><td style='vertical-align:
middle;'>")
html.write("%s:" % _("from"))
html.write("</td><td>")
- Age().render_input(self.name + "_from", 0)
+ Age(display=["days"]).render_input(self.name + "_from", 0)
html.write("</td></tr><tr><td
style='vertical-align: middle;'>")
html.write("%s:" % _("to"))
html.write("</td><td>")
- Age().render_input(self.name + "_to", 0)
+ Age(display=["days"]).render_input(self.name + "_to", 0)
html.write("</tr></table>")
def double_height(self):
return True
def filter_table(self, rows):
+ return filter_table_with_conversion(self, rows, lambda age: age)
+
+ def filter_table_with_conversion(self, rows, conv):
from_value = Age().from_html_vars(self.name + "_from")
to_value = Age().from_html_vars(self.name + "_to")
@@ -98,15 +101,27 @@ class FilterInvtableAge(Filter):
for row in rows:
value = row.get(self.name, None)
if value != None:
- if from_value and value < from_value:
+ age = conv(value)
+ if from_value and age < from_value:
continue
- if to_value and value > to_value:
+ if to_value and age > to_value:
continue
newrows.append(row)
return newrows
+class FilterInvtableTimestampAsAge(FilterInvtableAge):
+ def __init__(self, infoname, name, title, only_days=True):
+ FilterInvtableAge.__init__(self, infoname, name, title, only_days)
+
+
+ def filter_table(self, rows):
+ now = time.time()
+ return self.filter_table_with_conversion(rows, lambda timestamp: now -
timestamp)
+
+
+
# Filter for choosing a range in which a certain integer lies
class FilterInvtableIDRange(Filter):
@@ -149,9 +164,11 @@ class FilterInvtableOperStatus(Filter):
def display(self):
html.begin_checkbox_group()
for state, state_name in sorted(interface_oper_states.items()):
+ if state >= 8:
+ continue # skip artificial state 8 (degraded) and 9 (admin down)
varname = self.name + "_" + str(state)
html.checkbox(varname, True, label=state_name)
- if state == 4:
+ if state in (4, 7):
html.write("<br>")
html.end_checkbox_group()