Module: check_mk
Branch: master
Commit: e9fde3be951de115c858f125f355f39dddbc2ae1
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=e9fde3be951de1…
Author: Simon Betz <si(a)mathias-kettner.de>
Date: Thu Aug 25 09:59:04 2016 +0200
3780 availability: now limit of fetched logfile rows is configurable.
---
.werks/3780 | 9 ++++++++
ChangeLog | 1 +
web/htdocs/availability.py | 44 ++++++++++++++++++++++++++++++++-----
web/plugins/views/availability.py | 17 +++++++++++---
4 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/.werks/3780 b/.werks/3780
new file mode 100644
index 0000000..ef79d9e
--- /dev/null
+++ b/.werks/3780
@@ -0,0 +1,9 @@
+Title: availability: now limit of fetched logfile rows is configurable.
+Level: 1
+Component: multisite
+Compatible: compat
+Version: 1.4.0i1
+Date: 1472111747
+Class: feature
+
+
diff --git a/ChangeLog b/ChangeLog
index bc606c0..6df1a19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -371,6 +371,7 @@
* 3141 added user interfaces and permissions to view and acknowledge failed
notifications
* 3640 new filter option for status details: can now be negated
* 3713 new filter: hosts with certain service problems
+ * 3780 availability: now limit of fetched logfile rows is configurable.
* 3059 FIX: Fixed highlighting of availability timeline time slices
* 3175 FIX: Fix timeranges of graphs that are embedded in a dashboard...
* 3076 FIX: fixed broken views in check_mk raw edition
diff --git a/web/htdocs/availability.py b/web/htdocs/availability.py
index be04b12..cdfc2ee 100644
--- a/web/htdocs/availability.py
+++ b/web/htdocs/availability.py
@@ -475,7 +475,6 @@ def get_avoption_entries(what):
label = _("Show timeline of each object directly in table")),
),
- # Timelimit
( "timelimit",
"single",
False,
@@ -486,7 +485,18 @@ def get_avoption_entries(what):
unit = _("sec"),
default_value = 30,
),
- )
+ ),
+
+ ( "logrow_limit",
+ "single",
+ True,
+ Integer(
+ title = _("Log row limit"),
+ help = _("Limit the fetched rows of logfile in order to avoid "
+ "a hanging system. A value of zero means no limit."),
+ default_value = 5000,
+ ),
+ ),
]
def get_default_avoptions():
@@ -508,6 +518,7 @@ def get_default_avoptions():
"summary" : "sum",
"show_timeline" : False,
"timelimit" : 30,
+ "logrow_limit" : 5000,
"downtimes" : {
"include" : "honor",
@@ -581,8 +592,11 @@ def get_availability_rawdata(what, filterheaders, only_sites,
av_object, include
else:
av_filter += "Filter: service_description =\n"
- query = "GET statehist\n" + av_filter
+ query = "GET statehist\n" + av_filter
query += "Timelimit: %d\n" % avoptions["timelimit"]
+ logrow_limit = avoptions["logrow_limit"]
+ if logrow_limit:
+ query += "Limit: %d\n" % (logrow_limit + 1)
# Add Columns needed for object identification
columns = [ "host_name", "service_description" ]
@@ -612,11 +626,20 @@ def get_availability_rawdata(what, filterheaders, only_sites,
av_object, include
sites.live().set_prepend_site(False)
columns = ["site"] + columns
spans = [ dict(zip(columns, span)) for span in data ]
- return spans_by_object(spans)
+
+ # Now we find out if the log row limit was exceeded or
+ # if the log's length is the limit by accident.
+ # If this limit was exceeded then we cut off the last element
+ # in spans_by_object because it might be incomplete.
+ logrow_limit_reached_entry = None
+ if logrow_limit and len(data) >= logrow_limit + 1:
+ logrow_limit_reached_entry = dict(zip(columns, data[-1]))
+
+ return spans_by_object(spans, logrow_limit_reached_entry)
# Sort the raw spans into a tree of dicts, so that we
# have easy access to the timeline of each object
-def spans_by_object(spans):
+def spans_by_object(spans, logrow_limit_reached_entry):
# Sort by site/host and service, while keeping native order
av_rawdata = {}
for span in spans:
@@ -624,7 +647,16 @@ def spans_by_object(spans):
service = span["service_description"]
av_rawdata.setdefault(site_host, {})
av_rawdata[site_host].setdefault(service, []).append(span)
- return av_rawdata
+
+ if logrow_limit_reached_entry:
+ site_host = (logrow_limit_reached_entry["site"],
logrow_limit_reached_entry["host_name"])
+ if logrow_limit_reached_entry["service_description"]:
+ del
av_rawdata[site_host][logrow_limit_reached_entry["service_description"]]
+ else:
+ del av_rawdata[site_host]
+
+ # We have to remember if rawdata was modified
+ return av_rawdata, logrow_limit_reached_entry != None
# Compute an availability table. what is one of "bi", "host",
"service".
diff --git a/web/plugins/views/availability.py b/web/plugins/views/availability.py
index b990f86..317d50a 100644
--- a/web/plugins/views/availability.py
+++ b/web/plugins/views/availability.py
@@ -136,6 +136,7 @@ def render_availability_options(what):
# is (currently) called by views.py, when showing a view but
# availability mode is activated.
def render_availability_page(view, datasource, filterheaders, only_sites, limit):
+
if handle_edit_annotations():
return
@@ -187,8 +188,9 @@ def render_availability_page(view, datasource, filterheaders,
only_sites, limit)
# Now compute all data, we need this also for CSV export
if not html.has_user_errors():
- av_rawdata = availability.get_availability_rawdata(what, filterheaders,
only_sites,
- av_object, av_mode ==
"timeline", avoptions)
+ av_rawdata, has_reached_logrow_limit = \
+ availability.get_availability_rawdata(what, filterheaders, only_sites,
+ av_object, av_mode ==
"timeline", avoptions)
av_data = availability.compute_availability(what, av_rawdata, avoptions)
# Do CSV ouput
@@ -206,7 +208,6 @@ def render_availability_page(view, datasource, filterheaders,
only_sites, limit)
html.write(confirmation_html_code)
-
# Remove variables for editing annotations, otherwise they will make it into the
uris
html.del_all_vars("editanno_")
html.del_all_vars("anno_")
@@ -237,6 +238,16 @@ def render_availability_page(view, datasource, filterheaders,
only_sites, limit)
avoptions = render_availability_options(what)
if not html.has_user_errors():
+ # If we abolish the limit we have to fetch the data again
+ # with changed logrow_limit = 0, which means no limit
+ if has_reached_logrow_limit:
+ text = _("Your query matched more than %d log entries. "
+ "<b>Note:</b> The number of shown rows does not
necessarily reflect the "
+ "matched entries and the result might be incomplete. ") %
avoptions["logrow_limit"]
+ text += '<a href="%s">%s</a>' % \
+ (html.makeuri([("avo_logrow_limit", 0)]), _('Repeat
query without limit.'))
+ html.show_warning(text)
+
do_render_availability(what, av_rawdata, av_data, av_mode, av_object, avoptions)
if DisplayOptions.enabled(DisplayOptions.Z):