Module: check_mk
Branch: master
Commit: ac3ae91d9c47f972ab691347545966ae4e669b4a
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=ac3ae91d9c47f9…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Mon May 18 10:01:08 2015 +0200
#2229 Do not fail on non-existing Livestatus columns any longer, output None or null
instead
When you ask for a column that does not exist in your Livestatus version, now this is not
considered as a fatal error any longer but just being logged as a warning. Instead
an empty string (CSV), <tt>None</tt> (Python) or <tt>null</tt>
(JSON) is being returned.
This makes it easier for GUIs to maintain compatibility with existing Livestatus version
when new features are implemented that make use of new Livestatus columns.
---
.werks/2229 | 13 +++++++++++++
ChangeLog | 1 +
livestatus/src/Column.h | 1 +
livestatus/src/Makefile.am | 2 +-
livestatus/src/NullColumn.cc | 31 +++++++++++++++++++++++++++++++
livestatus/src/NullColumn.h | 41 +++++++++++++++++++++++++++++++++++++++++
livestatus/src/Query.cc | 34 +++++++++++++++++++++-------------
livestatus/src/Query.h | 1 +
8 files changed, 110 insertions(+), 14 deletions(-)
diff --git a/.werks/2229 b/.werks/2229
new file mode 100644
index 0000000..9546287
--- /dev/null
+++ b/.werks/2229
@@ -0,0 +1,13 @@
+Title: Do not fail on non-existing Livestatus columns any longer, output None or null
instead
+Level: 1
+Component: livestatus
+Compatible: compat
+Version: 1.2.7i1
+Date: 1431935942
+Class: feature
+
+When you ask for a column that does not exist in your Livestatus version, now this is
not
+considered as a fatal error any longer but just being logged as a warning. Instead
+an empty string (CSV), <tt>None</tt> (Python) or <tt>null</tt>
(JSON) is being returned.
+This makes it easier for GUIs to maintain compatibility with existing Livestatus version
+when new features are implemented that make use of new Livestatus columns.
diff --git a/ChangeLog b/ChangeLog
index 598dc78..0ff2f45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -549,6 +549,7 @@
* 2151 FIX: Fixed wrong time in events when forwarding logwatch to EC between
timezones...
Livestatus:
+ * 2229 Do not fail on non-existing Livestatus columns any longer, output None or null
instead...
* 2208 FIX: Add missing Livestatus column service_period...
HW/SW-Inventory:
diff --git a/livestatus/src/Column.h b/livestatus/src/Column.h
index 036cd98..1045dd8 100644
--- a/livestatus/src/Column.h
+++ b/livestatus/src/Column.h
@@ -38,6 +38,7 @@ using namespace std;
#define COLTYPE_TIME 4
#define COLTYPE_DICT 5
#define COLTYPE_BLOB 6
+#define COLTYPE_NULL 7
class Filter;
class Query;
diff --git a/livestatus/src/Makefile.am b/livestatus/src/Makefile.am
index 151a34c..660769b 100644
--- a/livestatus/src/Makefile.am
+++ b/livestatus/src/Makefile.am
@@ -31,7 +31,7 @@ pkglib_LIBRARIES = livestatus.so
livestatus_so_SOURCES = \
AndingFilter.cc ClientQueue.cc Column.cc ColumnsColumn.cc CustomVarsExplicitColumn.cc \
ContactsColumn.cc CustomVarsColumn.cc CustomVarsFilter.cc DoubleColumn.cc \
- DoubleColumnFilter.cc DowntimeOrComment.cc DownCommColumn.cc EmptyColumn.cc \
+ DoubleColumnFilter.cc DowntimeOrComment.cc DownCommColumn.cc EmptyColumn.cc
NullColumn.cc \
Filter.cc GlobalCountersColumn.cc HostContactsColumn.cc HostgroupsColumn.cc \
HostlistColumn.cc HostlistColumnFilter.cc HostlistStateColumn.cc MetricsColumn.cc \
HostSpecialIntColumn.cc ServiceSpecialIntColumn.cc InputBuffer.cc IntColumn.cc
IntColumnFilter.cc \
diff --git a/livestatus/src/NullColumn.cc b/livestatus/src/NullColumn.cc
new file mode 100644
index 0000000..a439e2b
--- /dev/null
+++ b/livestatus/src/NullColumn.cc
@@ -0,0 +1,31 @@
+// +------------------------------------------------------------------+
+// | ____ _ _ __ __ _ __ |
+// | / ___| |__ ___ ___| | __ | \/ | |/ / |
+// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+// | | |___| | | | __/ (__| < | | | | . \ |
+// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+// | |
+// | Copyright Mathias Kettner 2014 mk(a)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-
+// ails. 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.
+
+#include "NullColumn.h"
+#include "Query.h"
+
+void NullColumn::output(void *data __attribute__ ((__unused__)), Query *query)
+{
+ query->outputNull();
+}
diff --git a/livestatus/src/NullColumn.h b/livestatus/src/NullColumn.h
new file mode 100644
index 0000000..6e7add1
--- /dev/null
+++ b/livestatus/src/NullColumn.h
@@ -0,0 +1,41 @@
+// +------------------------------------------------------------------+
+// | ____ _ _ __ __ _ __ |
+// | / ___| |__ ___ ___| | __ | \/ | |/ / |
+// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+// | | |___| | | | __/ (__| < | | | | . \ |
+// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+// | |
+// | Copyright Mathias Kettner 2014 mk(a)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-
+// ails. 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.
+
+#ifndef NullColumn_h
+#define NullColumn_h
+
+#include "config.h"
+
+#include "Column.h"
+
+class NullColumn : public Column
+{
+public:
+ NullColumn(string name, string description) :
+ Column(name, description, -1) {}
+ int type() { return COLTYPE_NULL; }
+ void output(void *data, Query *);
+};
+
+#endif // NullColumn_h
diff --git a/livestatus/src/Query.cc b/livestatus/src/Query.cc
index 77fde0c..8bb3b93 100644
--- a/livestatus/src/Query.cc
+++ b/livestatus/src/Query.cc
@@ -36,7 +36,7 @@
#include "Query.h"
#include "Filter.h"
#include "Column.h"
-#include "EmptyColumn.h"
+#include "NullColumn.h"
#include "OutputBuffer.h"
#include "InputBuffer.h"
#include "StatsColumn.h"
@@ -199,7 +199,7 @@ Query::~Query()
Column *Query::createDummyColumn(const char *name)
{
- Column *col = new EmptyColumn(name, "Dummy column");
+ Column *col = new NullColumn(name, "Non existing column");
_dummy_columns.push_back(col);
return col;
}
@@ -543,8 +543,12 @@ void Query::parseColumnsLine(char *line)
if (column)
_columns.push_back(column);
else {
- _output->setError(RESPONSE_CODE_INVALID_HEADER,
- "Table '%s' has no column '%s'",
_table->name(), column_name);
+ logger(LOG_WARNING, "Replacing non-existing column '%s' with
null column", column_name);
+ // Do not fail any longer. We might want to make this configurable.
+ // But not failing has the advantage that an updated GUI, that expects new
columns,
+ // will be able to keep compatibility with older Livestatus versions.
+ // _output->setError(RESPONSE_CODE_INVALID_HEADER,
+ // "Table '%s' has no column '%s'",
_table->name(), column_name);
Column *col = createDummyColumn(column_name);
_columns.push_back(col);
}
@@ -1052,15 +1056,8 @@ void Query::outputCounter(counter_t value)
void Query::outputDouble(double value)
{
- if (isnan(value)) {
- if (_output_format == OUTPUT_FORMAT_CSV) {
- // output empty cell
- }
- else if (_output_format == OUTPUT_FORMAT_PYTHON)
- _output->addBuffer("None", 4);
- else
- _output->addBuffer("null", 4); // JSON
- }
+ if (isnan(value))
+ outputNull();
else {
char buf[64];
int l = snprintf(buf, sizeof(buf), "%.10e", value);
@@ -1068,6 +1065,17 @@ void Query::outputDouble(double value)
}
}
+void Query::outputNull()
+{
+ if (_output_format == OUTPUT_FORMAT_CSV) {
+ // output empty cell
+ }
+ else if (_output_format == OUTPUT_FORMAT_PYTHON)
+ _output->addBuffer("None", 4);
+ else
+ _output->addBuffer("null", 4); // JSON
+}
+
void Query::outputAsciiEscape(char value)
{
char buf[8];
diff --git a/livestatus/src/Query.h b/livestatus/src/Query.h
index 752a859..a15bd6b 100644
--- a/livestatus/src/Query.h
+++ b/livestatus/src/Query.h
@@ -115,6 +115,7 @@ public:
void outputUnsignedLong(unsigned long);
void outputCounter(counter_t);
void outputDouble(double);
+ void outputNull();
void outputAsciiEscape(char value);
void outputUnicodeEscape(unsigned value);
void outputString(const char *, int size=-1);