]> granicus.if.org Git - icinga2/commitdiff
livestatus: add sum aggregator, refactor Filter/Stats handling
authorMichael Friedrich <michael.friedrich@netways.de>
Thu, 11 Jul 2013 15:52:06 +0000 (17:52 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Thu, 11 Jul 2013 15:54:36 +0000 (17:54 +0200)
refs #4398

components/livestatus/Makefile.am
components/livestatus/livestatus.vcxproj
components/livestatus/livestatus.vcxproj.filters
components/livestatus/query.cpp
components/livestatus/sumaggregator.cpp [new file with mode: 0644]
components/livestatus/sumaggregator.h [new file with mode: 0644]

index 3699921c6f3b12853d3d4f0432e4d3a5eaf74524..aaac41339c15b0e1b314e932cf5caf84a83a1fbc 100644 (file)
@@ -55,6 +55,8 @@ liblivestatus_la_SOURCES = \
        servicestable.h \
        statustable.cpp \
        statustable.h \
+       sumaggregator.cpp \
+       sumaggregator.h \
        timeperiodstable.cpp \
        timeperiodstable.h \
        table.cpp \
index 2c9440eb510d31c43c9e8a9f19dd59a9d78b9bf7..96c391fdb9bf2ad949ec1d7aafa207df493e015d 100644 (file)
@@ -19,6 +19,9 @@
     </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="aggregator.h" />
+    <ClInclude Include="countaggregator.h" />
+    <ClInclude Include="sumaggregator.h" />
     <ClInclude Include="andfilter.h" />
     <ClInclude Include="attributefilter.h" />
     <ClInclude Include="column.h" />
@@ -44,6 +47,9 @@
     <ClInclude Include="table.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="aggregator.cpp" />
+    <ClCompile Include="countaggregator.cpp" />
+    <ClCompile Include="sumaggregator.cpp" />
     <ClCompile Include="andfilter.cpp" />
     <ClCompile Include="attributefilter.cpp" />
     <ClCompile Include="column.cpp" />
index 68f87a242be2ceca039ce056440afc2c7ed2c89c..f65abb3d8a15d84fc7ebe7ed83b9bb0a3b92714b 100644 (file)
     <ClInclude Include="orfilter.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="aggregator.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="countaggregator.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="sumaggregator.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
     <ClInclude Include="andfilter.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
     <ClCompile Include="andfilter.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="aggregator.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="countaggregator.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="sumaggregator.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
     <ClCompile Include="attributefilter.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
index 02ce92f4ec02cc75d740346d00f50c25f3b93cf2..56f56013df6f1bafb6e1c7f2c8d8306004a4c347 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "livestatus/query.h"
 #include "livestatus/countaggregator.h"
+#include "livestatus/sumaggregator.h"
 #include "livestatus/attributefilter.h"
 #include "livestatus/negatefilter.h"
 #include "livestatus/orfilter.h"
@@ -81,10 +82,10 @@ Query::Query(const std::vector<String>& lines)
                        boost::algorithm::split(m_Columns, params, boost::is_any_of(" "));
                else if (header == "ColumnHeaders")
                        m_ColumnHeaders = (params == "on");
-               else if (header == "Filter" || header == "Stats") {
+               else if (header == "Filter") {
 
                        Filter::Ptr filter = ParseFilter(params);
-                       
+
                        if (!filter) {
                                m_Verb = "ERROR";
                                m_ErrorCode = 452;
@@ -92,14 +93,57 @@ Query::Query(const std::vector<String>& lines)
                                return;
                        }
 
-                       std::deque<Filter::Ptr>& deq = (header == "Filter") ? filters : stats;
+                       std::deque<Filter::Ptr>& deq = filters;
                        deq.push_back(filter);
-                       
-                       if (deq == stats) {
+               }
+               else if (header == "Stats") {
+
+                       std::vector<String> tokens;
+                       boost::algorithm::split(tokens, params, boost::is_any_of(" "));
+
+                       String aggregate_arg = tokens[0];
+                       String aggregate_attr = tokens[1];
+
+                       if (aggregate_arg == "sum") {
+                               Aggregator::Ptr aggregator = boost::make_shared<SumAggregator>(aggregate_attr);
+                               aggregators.push_back(aggregator);
+                       }
+                       else if(aggregate_arg == "min") {
+                               /* TODO */
+                       }
+                       else if (aggregate_arg == "max") {
+                               /* TODO */
+                       }
+                       else if (aggregate_arg == "avg") {
+                               /* TODO */
+                       }
+                       else if (aggregate_arg == "std") {
+                               /* TODO */
+                       }
+                       else if (aggregate_arg == "suminv") {
+                               /* TODO */
+                       }
+                       else if (aggregate_arg == "avginv") {
+                               /* TODO */
+
+                       } else {
+                               Filter::Ptr filter = ParseFilter(params);
+
+                               if (!filter) {
+                                       m_Verb = "ERROR";
+                                       m_ErrorCode = 452;
+                                       m_ErrorMessage = "Invalid filter specification.";
+                                       return;
+                               }
+
+                               std::deque<Filter::Ptr>& deq = stats;
+                               deq.push_back(filter);
+
                                Aggregator::Ptr aggregator = boost::make_shared<CountAggregator>();
                                aggregator->SetFilter(filter);
                                aggregators.push_back(aggregator);
                        }
+
                } else if (header == "Or" || header == "And") {
                        std::deque<Filter::Ptr>& deq = (header == "Or" || header == "And") ? filters : stats;
 
@@ -138,7 +182,7 @@ Query::Query(const std::vector<String>& lines)
                        filters.pop_back();
 
                        deq.push_back(boost::make_shared<NegateFilter>(filter));
-                       
+
                        if (deq == stats) {
                                Aggregator::Ptr aggregator = aggregators.back();
                                aggregator->SetFilter(filter);
diff --git a/components/livestatus/sumaggregator.cpp b/components/livestatus/sumaggregator.cpp
new file mode 100644 (file)
index 0000000..8004a69
--- /dev/null
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program 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; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * This program is distributed in the hope that it will be useful,            *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
+ * GNU General Public License for more details.                               *
+ *                                                                            *
+ * You should have received a copy of the GNU General Public License          *
+ * along with this program; if not, write to the Free Software Foundation     *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
+ ******************************************************************************/
+
+#include "livestatus/sumaggregator.h"
+
+using namespace livestatus;
+
+SumAggregator::SumAggregator(const String& attr)
+    : m_Sum(0)
+{
+       m_SumAttr = attr;
+}
+
+void SumAggregator::Apply(const Table::Ptr& table, const Value& row)
+{
+       Column column = table->GetColumn(m_SumAttr);
+
+       Value value = column.ExtractValue(row);
+
+       m_Sum += value;
+}
+
+double SumAggregator::GetResult(void) const
+{
+       return m_Sum;
+}
diff --git a/components/livestatus/sumaggregator.h b/components/livestatus/sumaggregator.h
new file mode 100644 (file)
index 0000000..1c7142b
--- /dev/null
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program 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; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * This program is distributed in the hope that it will be useful,            *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
+ * GNU General Public License for more details.                               *
+ *                                                                            *
+ * You should have received a copy of the GNU General Public License          *
+ * along with this program; if not, write to the Free Software Foundation     *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
+ ******************************************************************************/
+
+#ifndef SUMAGGREGATOR_H
+#define SUMAGGREGATOR_H
+
+#include "livestatus/table.h"
+#include "livestatus/aggregator.h"
+
+namespace livestatus
+{
+
+/**
+ * @ingroup livestatus
+ */
+class SumAggregator : public Aggregator
+{
+public:
+       DECLARE_PTR_TYPEDEFS(SumAggregator);
+
+       SumAggregator(const String& attr);
+
+       virtual void Apply(const Table::Ptr& table, const Value& row);
+       virtual double GetResult(void) const;
+
+private:
+       double m_Sum;
+       String m_SumAttr;
+};
+
+}
+
+#endif /* SUMAGGREGATOR_H */