[icinga-checkins] icinga.org: icinga2/master: Implement the "Stats" header.

git at icinga.org git at icinga.org
Sun Mar 10 17:54:50 CET 2013


Module: icinga2
Branch: master
Commit: fbf08257ad67bbcee82c679b6042889a0499d1af
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=fbf08257ad67bbcee82c679b6042889a0499d1af

Author: Gunnar Beutner <gunnar at beutner.name>
Date:   Sun Mar 10 17:54:46 2013 +0100

Implement the "Stats" header.

---

 components/livestatus/query.cpp |   81 +++++++++++++++++++++++++++++----------
 1 files changed, 60 insertions(+), 21 deletions(-)

diff --git a/components/livestatus/query.cpp b/components/livestatus/query.cpp
index 7c90b04..3876246 100644
--- a/components/livestatus/query.cpp
+++ b/components/livestatus/query.cpp
@@ -65,7 +65,7 @@ Query::Query(const vector<String>& lines)
 			m_Columns = params.Split(is_any_of(" "));
 		else if (header == "ColumnHeaders")
 			m_ColumnHeaders = (params == "on");
-		else if (header == "Filter") {
+		else if (header == "Filter" || header == "Stats") {
 			vector<String> tokens = params.Split(is_any_of(" "));
 
 			if (tokens.size() < 3) {
@@ -97,29 +97,46 @@ Query::Query(const vector<String>& lines)
 			if (negate)
 				filter = boost::make_shared<NegateFilter>(filter);
 
-			filters.push_back(filter);
+			deque<Filter::Ptr>& deq = (header == "Filter") ? filters : stats;
+			deq.push_back(filter);
 		} else if (header == "Or" || header == "And") {
+			deque<Filter::Ptr>& deq = (header == "Or" || header == "And") ? filters : stats;
+
 			int num = Convert::ToLong(params);
 			CombinerFilter::Ptr filter;
 
-			if (header == "Or")
+			if (header == "Or" || header == "StatsOr")
 				filter = boost::make_shared<OrFilter>();
 			else
 				filter = boost::make_shared<AndFilter>();
 
-			while (!filters.empty() && num--) {
-				filter->AddSubFilter(filters.back());
-				filters.pop_back();
+			if (num > deq.size()) {
+				m_Verb = "ERROR";
+				m_ErrorCode = 451;
+				m_ErrorMessage = "Or/StatsOr is referencing " + Convert::ToString(num) + " filters; stack only contains " + Convert::ToString(deq.size()) + " filters";
+				return;
+			}
+
+			while (num--) {
+				filter->AddSubFilter(deq.back());
+				deq.pop_back();
 			}
 
-			filters.push_back(filter);
-		} else if (header == "Negate") {
-			if (!filters.empty()) {
-				Filter::Ptr filter = filters.back();
-				filters.pop_back();
+			deq.push_back(filter);
+		} else if (header == "Negate" || header == "StatsNegate") {
+			deque<Filter::Ptr>& deq = (header == "Negate") ? filters : stats;
 
-				filters.push_back(boost::make_shared<NegateFilter>(filter));
+			if (deq.empty()) {
+				m_Verb = "ERROR";
+				m_ErrorCode = 451;
+				m_ErrorMessage = "Negate/StatsNegate used, however the filter stack is empty";
+				return;
 			}
+
+			Filter::Ptr filter = deq.back();
+			filters.pop_back();
+
+			deq.push_back(boost::make_shared<NegateFilter>(filter));
 		}
 	}
 
@@ -196,22 +213,44 @@ void Query::ExecuteGetHelper(const Stream::Ptr& stream)
 
 	Array::Ptr rs = boost::make_shared<Array>();
 
-	BOOST_FOREACH(const Object::Ptr& object, objects) {
-		Array::Ptr row = boost::make_shared<Array>();
+	if (m_Stats.empty()) {
+		BOOST_FOREACH(const Object::Ptr& object, objects) {
+			Array::Ptr row = boost::make_shared<Array>();
 
-		BOOST_FOREACH(const String& column, columns) {
-			Table::ColumnAccessor accessor = table->GetColumn(column);
+			BOOST_FOREACH(const String& column, columns) {
+				Table::ColumnAccessor accessor = table->GetColumn(column);
 
-			if (accessor.empty()) {
-				SendResponse(stream, 450, "Column '" + column + "' does not exist.");
+				if (accessor.empty()) {
+					SendResponse(stream, 450, "Column '" + column + "' does not exist.");
 
-				return;
+					return;
+				}
+
+				row->Add(accessor(object));
 			}
 
-			row->Add(accessor(object));
+			rs->Add(row);
+		}
+	} else {
+		vector<int> stats(m_Stats.size(), 0);
+
+		BOOST_FOREACH(const Object::Ptr& object, objects) {
+			int index = 0;
+			BOOST_FOREACH(const Filter::Ptr filter, m_Stats) {
+				if (filter->Apply(table, object))
+					stats[index]++;
+
+				index++;
+			}
 		}
 
+		Array::Ptr row = boost::make_shared<Array>();
+		for (int i = 0; i < m_Stats.size(); i++)
+			row->Add(stats[i]);
+
 		rs->Add(row);
+
+		m_ColumnHeaders = false;
 	}
 
 	stringstream result;
@@ -229,7 +268,7 @@ void Query::ExecuteCommandHelper(const Stream::Ptr& stream)
 
 void Query::ExecuteErrorHelper(const Stream::Ptr& stream)
 {
-	PrintFixed16(stream, m_ErrorCode, m_ErrorMessage);
+	SendResponse(stream, m_ErrorCode, m_ErrorMessage);
 }
 
 void Query::SendResponse(const Stream::Ptr& stream, int code, const String& data)





More information about the icinga-checkins mailing list