Module: check_mk
Branch: master
Commit: b7bfd1a8095680d484891b4b965c169507444407
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=b7bfd1a8095680…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Thu Jul 4 17:15:36 2013 +0200
Livestatus: experimental speedup of statehist table
---
livestatus/src/Column.h | 4 --
livestatus/src/Filter.h | 10 ++---
livestatus/src/Query.cc | 2 +-
livestatus/src/Query.h | 1 +
livestatus/src/Table.cc | 1 -
livestatus/src/TableStateHistory.cc | 84 +++++++++++++++++++++++++++++------
livestatus/src/TableStateHistory.h | 2 +-
livestatus/src/module.c | 5 +++
8 files changed, 84 insertions(+), 25 deletions(-)
diff --git a/livestatus/src/Column.h b/livestatus/src/Column.h
index eba28fe..5fe9b33 100644
--- a/livestatus/src/Column.h
+++ b/livestatus/src/Column.h
@@ -46,7 +46,6 @@ class Column
{
string _name;
string _description;
- Table *_table;
public:
int _indirect_offset;
int _extra_offset;
@@ -63,9 +62,6 @@ public:
virtual Filter *createFilter(int opid __attribute__ ((__unused__)), char *value
__attribute__ ((__unused__))) { return 0; }
void *shiftPointer(void *data);
void setExtraOffset(int o) { _extra_offset = o; }
- void setTable(Table *t) { _table = t; }
- Table *table() { return _table; }
-
};
#endif // Column_h
diff --git a/livestatus/src/Filter.h b/livestatus/src/Filter.h
index d7beef8..5162058 100644
--- a/livestatus/src/Filter.h
+++ b/livestatus/src/Filter.h
@@ -33,27 +33,27 @@
using namespace std;
class Query;
-class Table;
+class Column;
class Filter
{
string _error_message; // Error in constructor
unsigned _error_code;
- Table *_table;
+ Column *_column;
protected:
Query *_query; // needed by TimeOffsetFilter (currently)
void setError(unsigned code, const char *format, ...);
public:
- Filter() : _query(0) {}
+ Filter() : _query(0), _column(0) {}
virtual ~Filter() {}
string errorMessage() { return _error_message; }
unsigned errorCode() { return _error_code; }
bool hasError() { return _error_message != ""; }
void setQuery(Query *q) { _query = q; }
- void setTable(Table *t) { _table = t; }
- Table *table() { return _table; }
+ void setColumn(Column *c) { _column = c; }
+ Column *column() { return _column; }
virtual bool accepts(void *data) = 0;
virtual void *indexFilter(const char *columnname __attribute__ ((__unused__))) {
return 0; }
virtual void findIntLimits(const char *columnname __attribute__ ((__unused__)), int
*lower __attribute__ ((__unused__)), int *upper __attribute__ ((__unused__))) {}
diff --git a/livestatus/src/Query.cc b/livestatus/src/Query.cc
index 0fccb09..138ce94 100644
--- a/livestatus/src/Query.cc
+++ b/livestatus/src/Query.cc
@@ -249,7 +249,7 @@ Filter *Query::createFilter(Column *column, int operator_id, char
*value)
}
else {
filter->setQuery(this);
- filter->setTable(column->table());
+ filter->setColumn(column);
}
return filter;
}
diff --git a/livestatus/src/Query.h b/livestatus/src/Query.h
index d8c05ef..82b864a 100644
--- a/livestatus/src/Query.h
+++ b/livestatus/src/Query.h
@@ -130,6 +130,7 @@ public:
void findIntLimits(const char *columnname, int *lower, int *upper);
void optimizeBitmask(const char *columnname, uint32_t *bitmask);
int timezoneOffset() { return _timezone_offset; }
+ AndingFilter *filter() { return &_filter; }
private:
bool doStats();
diff --git a/livestatus/src/Table.cc b/livestatus/src/Table.cc
index a64abb3..9c5c23d 100644
--- a/livestatus/src/Table.cc
+++ b/livestatus/src/Table.cc
@@ -40,7 +40,6 @@ void Table::addColumn(Column *col)
}
else {
_columns.insert(make_pair(col->name(), col));
- col->setTable(this);
}
}
diff --git a/livestatus/src/TableStateHistory.cc b/livestatus/src/TableStateHistory.cc
index c56a942..2041511 100644
--- a/livestatus/src/TableStateHistory.cc
+++ b/livestatus/src/TableStateHistory.cc
@@ -28,6 +28,7 @@
#include <unistd.h>
#include <stddef.h>
#include <stdarg.h>
+#include <list>
#include "nagios.h"
#include "logger.h"
@@ -48,6 +49,8 @@
#include "Timeperiod.h"
#endif
+int g_disable_statehist_filtering = 0;
+
typedef pair<string, string> HostServiceKey;
@@ -256,6 +259,38 @@ LogEntry *TableStateHistory::getNextLogentry()
void TableStateHistory::answerQuery(Query *query)
{
+ // Create a partial filter, that contains only such filters that
+ // check attributes of current hosts and services
+ typedef deque<Filter *> object_filter_t;
+ object_filter_t object_filter;
+ AndingFilter *orig_filter = query->filter();
+
+ if (!g_disable_statehist_filtering) {
+ deque<Filter *>::iterator it = orig_filter->begin();
+ while (it != orig_filter->end()) {
+ Filter *filter = *it;
+ Column *column = filter->column();
+ if (column) {
+ const char *column_name = column->name();
+ if (!strncmp(column_name, "current_", 8)
+ || !strncmp(column_name, "host_", 5)
+ || !strncmp(column_name, "service_", 8))
+ {
+ object_filter.push_back(filter);
+ // logger(LOG_NOTICE, "Nehme Column: %s", column_name);
+ }
+ else {
+ // logger(LOG_NOTICE, "Column geht nciht: %s",
column_name);
+ }
+ }
+ else {
+ // logger(LOG_NOTICE, "Mist: Filter ohne Column");
+ }
+ ++it;
+ }
+ }
+
+
g_store->logCache()->lockLogCache();
g_store->logCache()->logCachePreChecks();
@@ -390,22 +425,42 @@ void TableStateHistory::answerQuery(Query *query)
state_info_t::iterator it_hst = state_info.find(key);
if (it_hst == state_info.end())
{
- // No state found. Now check if this host/services is filtered out
- if (objectFilteredOut(entry->_host_name, entry->_svc_desc)) {
- object_blacklist.insert(key);
- continue;
+ // Create state object that we also need for filtering right now
+ state = new HostServiceState();
+ state->_is_host = entry->_svc_desc == 0;
+ state->_host = entry->_host;
+ state->_service = entry->_service;
+ state->_host_name = key.first.c_str();
+ state->_service_description = key.second.c_str();
+
+ // No state found. Now check if this host/services is filtered out.
+ // Note: we currently do not filter out hosts since they might be
+ // needed for service states
+ if (entry->_svc_desc)
+ {
+ bool filtered_out = false;
+ for (object_filter_t::iterator it = object_filter.begin();
+ it != object_filter.end();
+ ++it)
+ {
+ Filter *filter = *it;
+ if (!filter->accepts(state)) {
+ // logger(LOG_NOTICE, "kann ich rausschmeissen:
%s/%s", key.first.c_str(), key.second.c_str());
+ filtered_out = true;
+ break;
+ }
+ }
+
+ if (filtered_out) {
+ object_blacklist.insert(key);
+ delete state;
+ continue;
+ }
}
- state = new HostServiceState();
+ // Store this state object for tracking state transitions
state_info.insert(std::make_pair(key, state));
-
- state->_is_host = entry->_svc_desc == 0;
state->_from = _since;
- state->_host = entry->_host;
- state->_service = entry->_service;
-
- state->_host_name = key.first.c_str();
- state->_service_description = key.second.c_str();
// Get notification period of host/service
// If this host/service is no longer availabe in nagios -> set to
""
@@ -524,8 +579,11 @@ void TableStateHistory::answerQuery(Query *query)
g_store->logCache()->unlockLogCache();
}
-bool TableStateHistory::objectFilteredOut(const char *host_name, const char
*service_description)
+bool TableStateHistory::objectFilteredOut(Query *query, void *entry)
{
+
+
+
return false;
}
diff --git a/livestatus/src/TableStateHistory.h b/livestatus/src/TableStateHistory.h
index 5c0b82e..69b9536 100644
--- a/livestatus/src/TableStateHistory.h
+++ b/livestatus/src/TableStateHistory.h
@@ -68,7 +68,7 @@ private:
LogEntry* getPreviousLogentry();
LogEntry* getNextLogentry();
void process(Query *query, HostServiceState *hs_state);
- bool objectFilteredOut(const char *host_name, const char *service_description);
+ bool objectFilteredOut(Query *, void *entry);
};
diff --git a/livestatus/src/module.c b/livestatus/src/module.c
index 47c66a6..a3f9cd8 100644
--- a/livestatus/src/module.c
+++ b/livestatus/src/module.c
@@ -84,6 +84,7 @@ int g_num_clientthreads = 10; /* allow 10 concurrent connections per
default
int g_num_queued_connections = 0; /* current number of queued connections (for
statistics) */
int g_num_active_connections = 0; /* current number of active connections (for
statistics) */
size_t g_thread_stack_size = 65536; /* stack size of threads */
+extern int g_disable_statehist_filtering;
#define false 0
#define true 1
@@ -760,6 +761,10 @@ void livestatus_parse_arguments(const char *args_orig)
else if (!strcmp(left, "num_livecheck_helpers")) {
g_num_livehelpers = atoi(right);
}
+ else if (!strcmp(left, "disable_statehist_filtering"))
+ {
+ g_disable_statehist_filtering = atoi(right);
+ }
else {
logger(LG_INFO, "Ignoring invalid option %s=%s", left, right);
}