]> granicus.if.org Git - icinga2/commitdiff
Implement status api handler
authorJean-Marcel Flach <jean-marcel.flach@netways.de>
Mon, 21 Sep 2015 09:44:58 +0000 (11:44 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Wed, 23 Sep 2015 14:59:07 +0000 (16:59 +0200)
Global statistics, features, etc.

fixes #10116

23 files changed:
doc/9-icinga2-api.md
lib/base/filelogger.cpp
lib/base/sysloglogger.cpp
lib/checker/checkercomponent.cpp
lib/compat/checkresultreader.cpp
lib/compat/compatlogger.cpp
lib/compat/externalcommandlistener.cpp
lib/compat/statusdatawriter.cpp
lib/db_ido_mysql/idomysqlconnection.cpp
lib/db_ido_pgsql/idopgsqlconnection.cpp
lib/icinga/cib.cpp
lib/icinga/cib.hpp
lib/icinga/icingaapplication.cpp
lib/icinga/icingastatuswriter.cpp
lib/livestatus/livestatuslistener.cpp
lib/notification/notificationcomponent.cpp
lib/perfdata/graphitewriter.cpp
lib/perfdata/opentsdbwriter.cpp
lib/perfdata/perfdatawriter.cpp
lib/remote/CMakeLists.txt
lib/remote/apilistener.cpp
lib/remote/statushandler.cpp [new file with mode: 0644]
lib/remote/statushandler.hpp [new file with mode: 0644]

index 929f643aa84f6e88af7d9a5815d6af0987544d60..4f6edbdb07c0e51fc46390344e7ed417aaf25b15 100644 (file)
@@ -123,9 +123,10 @@ Once the API user is configured make sure to restart Icinga 2:
 
 Now pass the basic auth information to curl and send a GET request to the API:
 
-    $ curl -u root:icinga -k -s 'https://nbmif.int.netways.de:5665/v1'
+    $ curl -u root:icinga -k -s 'https://localhost:5665/v1'
 
-In case you will get `Unauthorized` make sure to check the API user credentials.
+In case you will get an `Unauthorized` error message make sure to
+check the API user credentials.
 
 ### <a id="icinga2-api-permissions"></a> Permissions
 
@@ -187,26 +188,27 @@ The Icinga 2 API provides multiple url endpoints
   /v1/actions  | Endpoint for running specific [API actions](9-icinga2-api.md#icinga2-api-actions).
   /v1/config    | Endpoint for [managing configuration modules](9-icinga2-api.md#icinga2-api-config-management).
   /v1/events   | Endpoint for subscribing to [API events](9-icinga2-api.md#icinga2-api-actions).
-  /v1/types    | Endpoint for listing Icinga 2 configuration object types and their attributes.
+  /v1/status   | Endpoint for receiving icinga2 [status and statistics](9-icinga2-api.md#icinga2-api-status).
+  /v1/types    | Endpoint for listing Icinga 2 configuration object types and their attributes.
 
 Additionally there are endpoints for each [config object type](6-object-types.md#object-types):
 
 **TODO** Update
 
   Url Endpoints                | Description
-  ----------------------|----------------------------------------------------
-  /v1/hosts            | Endpoint for retreiving and updating [Host](6-object-types.md#objecttype-host) objects.
+  ------------------|----------------------------------------------------
+  /v1/hosts                    | Endpoint for retreiving and updating [Host](6-object-types.md#objecttype-host) objects.
   /v1/services         | Endpoint for retreiving and updating [Service](6-object-types.md#objecttype-service) objects.
   /v1/notifications    | Endpoint for retreiving and updating [Notification](6-object-types.md#objecttype-notification) objects.
   /v1/dependencies     | Endpoint for retreiving and updating [Dependency](6-object-types.md#objecttype-dependency) objects.
-  /v1/users            | Endpoint for retreiving and updating [User](6-object-types.md#objecttype-user) objects.
+  /v1/users                    | Endpoint for retreiving and updating [User](6-object-types.md#objecttype-user) objects.
   /v1/checkcommands    | Endpoint for retreiving and updating [CheckCommand](6-object-types.md#objecttype-checkcommand) objects.
   /v1/eventcommands    | Endpoint for retreiving and updating [EventCommand](6-object-types.md#objecttype-eventcommand) objects.
   /v1/notificationcommands | Endpoint for retreiving and updating [NotificationCommand](6-object-types.md#objecttype-notificationcommand) objects.
   /v1/hostgroups       | Endpoint for retreiving and updating [HostGroup](6-object-types.md#objecttype-hostgroup) objects.
   /v1/servicegroups    | Endpoint for retreiving and updating [ServiceGroup](6-object-types.md#objecttype-servicegroup) objects.
   /v1/usergroups       | Endpoint for retreiving and updating [UserGroup](6-object-types.md#objecttype-usergroup) objects.
-  /v1/zones            | Endpoint for retreiving and updating [Zone](6-object-types.md#objecttype-zone) objects.
+  /v1/zones                    | Endpoint for retreiving and updating [Zone](6-object-types.md#objecttype-zone) objects.
   /v1/endpoints                | Endpoint for retreiving and updating [Endpoint](6-object-types.md#objecttype-endpoint) objects.
   /v1/timeperiods      | Endpoint for retreiving and updating [TimePeriod](6-object-types.md#objecttype-timeperiod) objects.
 
@@ -295,6 +297,56 @@ Reschedule a service check for all services in NOT-OK state:
 
 **TODO** https://dev.icinga.org/issues/9078
 
+## <a id="icinga2-api-status"></a> Status and Statistics
+
+Contains a list of sub url endpoints which provide the status and statistics
+of available and enabled features. Any filters are ignored.
+
+Example for the main url endpoint `/v1/status`:
+
+    $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status' | python -m json.tool
+    {
+        "results": [
+            {
+                "name": "ApiListener"
+            },
+            ...
+            {
+                "name": "Collection"
+            },
+            ...
+        ]
+    }
+
+`/v1/status/Collection` is always available as virtual status url endpoint.
+It provides all feature status information into a collected overview.
+
+Example for the icinga application url endpoint `/v1/status/IcingaApplication`:
+
+    $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication' | python -m json.tool
+    {
+        "results": [
+            {
+                "perfdata": [],
+                "status": {
+                    "icingaapplication": {
+                        "app": {
+                            "enable_event_handlers": true,
+                            "enable_flapping": true,
+                            "enable_host_checks": true,
+                            "enable_notifications": true,
+                            "enable_perfdata": true,
+                            "enable_service_checks": true,
+                            "node_name": "mbmif.int.netways.de",
+                            "pid": 59819.0,
+                            "program_start": 1443019345.093372,
+                            "version": "v2.3.0-573-g380a131"
+                        }
+                    }
+                }
+            }
+        ]
+    }
 
 
 ## <a id="icinga2-api-objects"></a> API Objects
index afd4c606b941430736860f6a056392c67d076896..7fa3197f055cb639381e75f6377fbe418ed26cae 100644 (file)
@@ -28,7 +28,7 @@ using namespace icinga;
 
 REGISTER_TYPE(FileLogger);
 
-REGISTER_STATSFUNCTION(FileLoggerStats, &FileLogger::StatsFunc);
+REGISTER_STATSFUNCTION(FileLogger, &FileLogger::StatsFunc);
 
 void FileLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index b94cc4f674d51b9f8a26e85ea314ae2ef91eea70..912cef04c5d2b40beac41b0d57b7a1e07257f4df 100644 (file)
@@ -28,7 +28,7 @@ using namespace icinga;
 
 REGISTER_TYPE(SyslogLogger);
 
-REGISTER_STATSFUNCTION(SyslogLoggerStats, &SyslogLogger::StatsFunc);
+REGISTER_STATSFUNCTION(SyslogLogger, &SyslogLogger::StatsFunc);
 
 void SyslogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index fa7bf978af95cb6db29cc23900ad463948c67c5a..dd752256238bed57ec410ae3465fe9be0ba8a1da 100644 (file)
@@ -36,7 +36,7 @@ using namespace icinga;
 
 REGISTER_TYPE(CheckerComponent);
 
-REGISTER_STATSFUNCTION(CheckerComponentStats, &CheckerComponent::StatsFunc);
+REGISTER_STATSFUNCTION(CheckerComponent, &CheckerComponent::StatsFunc);
 
 void CheckerComponent::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
 {
index eb344ee70ed0ed9312b3d6606edc41505cfe5830..3301f9fc4fdd7104e8cbd51a92d794fdc923c277 100644 (file)
@@ -38,7 +38,7 @@ using namespace icinga;
 
 REGISTER_TYPE(CheckResultReader);
 
-REGISTER_STATSFUNCTION(CheckResultReaderStats, &CheckResultReader::StatsFunc);
+REGISTER_STATSFUNCTION(CheckResultReader, &CheckResultReader::StatsFunc);
 
 void CheckResultReader::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index b23622f7ac2f8d24d5058c255a85cd430a3e6160..46692088e233bbba3d759380acbb6d023b4814e7 100644 (file)
@@ -41,7 +41,7 @@ using namespace icinga;
 
 REGISTER_TYPE(CompatLogger);
 
-REGISTER_STATSFUNCTION(CompatLoggerStats, &CompatLogger::StatsFunc);
+REGISTER_STATSFUNCTION(CompatLogger, &CompatLogger::StatsFunc);
 
 void CompatLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index ec5beca15ecc7a1dd5524cb66719d4e75857b0e7..eefe4649f3dda288a45be0c733e1f5414a48dea5 100644 (file)
@@ -30,7 +30,7 @@ using namespace icinga;
 
 REGISTER_TYPE(ExternalCommandListener);
 
-REGISTER_STATSFUNCTION(ExternalCommandListenerStats, &ExternalCommandListener::StatsFunc);
+REGISTER_STATSFUNCTION(ExternalCommandListener, &ExternalCommandListener::StatsFunc);
 
 void ExternalCommandListener::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index 893f517ec3e0d81d3a32de566dc7d24361c47e77..8f71cefccd8ee27ab9fb36793bc2b1f171a1ad90 100644 (file)
@@ -48,7 +48,7 @@ using namespace icinga;
 
 REGISTER_TYPE(StatusDataWriter);
 
-REGISTER_STATSFUNCTION(StatusDataWriterStats, &StatusDataWriter::StatsFunc);
+REGISTER_STATSFUNCTION(StatusDataWriter, &StatusDataWriter::StatsFunc);
 
 void StatusDataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index 7e9c2c1b82e22c29f1d26b374769e04eb80c6533..c04e374d950e3002b1bdf4e1e961132a004277c6 100644 (file)
@@ -36,7 +36,7 @@
 using namespace icinga;
 
 REGISTER_TYPE(IdoMysqlConnection);
-REGISTER_STATSFUNCTION(IdoMysqlConnectionStats, &IdoMysqlConnection::StatsFunc);
+REGISTER_STATSFUNCTION(IdoMysqlConnection, &IdoMysqlConnection::StatsFunc);
 
 IdoMysqlConnection::IdoMysqlConnection(void)
        : m_QueryQueue(500000)
index c9e171bf2a016cc8d59c8587d7537b21faf3ae9c..d04a616964d0962714e2a800b2b058f9595a4515 100644 (file)
@@ -38,7 +38,7 @@ using namespace icinga;
 
 REGISTER_TYPE(IdoPgsqlConnection);
 
-REGISTER_STATSFUNCTION(IdoPgsqlConnectionStats, &IdoPgsqlConnection::StatsFunc);
+REGISTER_STATSFUNCTION(IdoPgsqlConnection, &IdoPgsqlConnection::StatsFunc);
 
 IdoPgsqlConnection::IdoPgsqlConnection(void)
        : m_QueryQueue(500000)
index 5f8aabd3ae8f532286a0f0c32730af326ae93d96..af9c8bf05c4ff872df956fb1c2b7e8c538f4f418 100644 (file)
@@ -20,6 +20,7 @@
 #include "icinga/cib.hpp"
 #include "icinga/host.hpp"
 #include "icinga/service.hpp"
+#include "icinga/perfdatavalue.hpp"
 #include "base/objectlock.hpp"
 #include "base/utility.hpp"
 #include "base/configtype.hpp"
@@ -256,3 +257,62 @@ std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats(void)
        return std::make_pair(status, perfdata);
 }
 
+REGISTER_STATSFUNCTION(CIB, &CIB::StatsFunc);
+
+void CIB::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) {
+       double interval = Utility::GetTime() - Application::GetStartTime();
+
+       if (interval > 60)
+               interval = 60;
+
+       status->Set("active_host_checks", GetActiveHostChecksStatistics(interval) / interval);
+       status->Set("passive_host_checks", GetPassiveHostChecksStatistics(interval) / interval);
+       status->Set("active_host_checks_1min", GetActiveHostChecksStatistics(60));
+       status->Set("passive_host_checks_1min", GetPassiveHostChecksStatistics(60));
+       status->Set("active_host_checks_5min", GetActiveHostChecksStatistics(60 * 5));
+       status->Set("passive_host_checks_5min", GetPassiveHostChecksStatistics(60 * 5));
+       status->Set("active_host_checks_15min", GetActiveHostChecksStatistics(60 * 15));
+       status->Set("passive_host_checks_15min", GetPassiveHostChecksStatistics(60 * 15));
+
+       status->Set("active_service_checks", GetActiveServiceChecksStatistics(interval) / interval);
+       status->Set("passive_service_checks", GetPassiveServiceChecksStatistics(interval) / interval);
+       status->Set("active_service_checks_1min", GetActiveServiceChecksStatistics(60));
+       status->Set("passive_service_checks_1min", GetPassiveServiceChecksStatistics(60));
+       status->Set("active_service_checks_5min", GetActiveServiceChecksStatistics(60 * 5));
+       status->Set("passive_service_checks_5min", GetPassiveServiceChecksStatistics(60 * 5));
+       status->Set("active_service_checks_15min", GetActiveServiceChecksStatistics(60 * 15));
+       status->Set("passive_service_checks_15min", GetPassiveServiceChecksStatistics(60 * 15));
+
+       CheckableCheckStatistics scs = CalculateServiceCheckStats();
+
+       status->Set("min_latency", scs.min_latency);
+       status->Set("max_latency", scs.max_latency);
+       status->Set("avg_latency", scs.avg_latency);
+       status->Set("min_execution_time", scs.min_latency);
+       status->Set("max_execution_time", scs.max_latency);
+       status->Set("avg_execution_time", scs.avg_execution_time);
+
+       ServiceStatistics ss = CalculateServiceStats();
+
+       status->Set("num_services_ok", ss.services_ok);
+       status->Set("num_services_warning", ss.services_warning);
+       status->Set("num_services_critical", ss.services_critical);
+       status->Set("num_services_unknown", ss.services_unknown);
+       status->Set("num_services_pending", ss.services_pending);
+       status->Set("num_services_unreachable", ss.services_unreachable);
+       status->Set("num_services_flapping", ss.services_flapping);
+       status->Set("num_services_in_downtime", ss.services_in_downtime);
+       status->Set("num_services_acknowledged", ss.services_acknowledged);
+
+       double uptime = Utility::GetTime() - Application::GetStartTime();
+       status->Set("uptime", uptime);
+
+       HostStatistics hs = CalculateHostStats();
+
+       status->Set("num_hosts_up", hs.hosts_up);
+       status->Set("num_hosts_down", hs.hosts_down);
+       status->Set("num_hosts_unreachable", hs.hosts_unreachable);
+       status->Set("num_hosts_flapping", hs.hosts_flapping);
+       status->Set("num_hosts_in_downtime", hs.hosts_in_downtime);
+       status->Set("num_hosts_acknowledged", hs.hosts_acknowledged);
+}
index 13f02ad9646cacce648cb68b8ec247fdabf244db..15afedb9f5215db07e8c1826e790d2a5d0e20401 100644 (file)
@@ -87,6 +87,8 @@ public:
 
        static std::pair<Dictionary::Ptr, Array::Ptr> GetFeatureStats(void);
 
+       static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
+
 private:
        CIB(void);
 
index 743e12e7991eb5e88a32ea246ced5a175e454ed4..6f531e1017b58ac1909da01f216559c1ef787223 100644 (file)
@@ -60,7 +60,7 @@ void IcingaApplication::StaticInitialize(void)
        ScriptGlobal::Set("ApplicationType", "IcingaApplication");
 }
 
-REGISTER_STATSFUNCTION(IcingaApplicationStats, &IcingaApplication::StatsFunc);
+REGISTER_STATSFUNCTION(IcingaApplication, &IcingaApplication::StatsFunc);
 
 void IcingaApplication::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
 {
index 12b211b85f8e0ee19920a5b583baba9289a22658..d9be27dfcca79d2f75fa49f5fad604b77730ab58 100644 (file)
@@ -34,7 +34,7 @@ using namespace icinga;
 
 REGISTER_TYPE(IcingaStatusWriter);
 
-REGISTER_STATSFUNCTION(IcingaStatusWriterStats, &IcingaStatusWriter::StatsFunc);
+REGISTER_STATSFUNCTION(IcingaStatusWriter, &IcingaStatusWriter::StatsFunc);
 
 void IcingaStatusWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
 {
index da55f6f9025f4fa0b29de8302cf998a6f61526ff..747c2c9a0362ee1729ca21605a98a3b972ade6ee 100644 (file)
@@ -41,7 +41,7 @@ static int l_ClientsConnected = 0;
 static int l_Connections = 0;
 static boost::mutex l_ComponentMutex;
 
-REGISTER_STATSFUNCTION(LivestatusListenerStats, &LivestatusListener::StatsFunc);
+REGISTER_STATSFUNCTION(LivestatusListener, &LivestatusListener::StatsFunc);
 
 void LivestatusListener::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
 {
index b85e8ecd4d8497449141ef8a0931c97e1244d878..9660bfca1b335a9ff8961a38692a131af460a356 100644 (file)
@@ -33,7 +33,7 @@ using namespace icinga;
 
 REGISTER_TYPE(NotificationComponent);
 
-REGISTER_STATSFUNCTION(NotificationComponentStats, &NotificationComponent::StatsFunc);
+REGISTER_STATSFUNCTION(NotificationComponent, &NotificationComponent::StatsFunc);
 
 void NotificationComponent::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index 4bd3291cd6d1ff53d1666bf85c3229d7adf10291..3e7640e5d4fb2038b4eff1abbf1d49f3fb6608bf 100644 (file)
@@ -45,7 +45,7 @@ using namespace icinga;
 
 REGISTER_TYPE(GraphiteWriter);
 
-REGISTER_STATSFUNCTION(GraphiteWriterStats, &GraphiteWriter::StatsFunc);
+REGISTER_STATSFUNCTION(GraphiteWriter, &GraphiteWriter::StatsFunc);
 
 void GraphiteWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index 101fa8f411e9ef9f7337c0e2db85a386b7725aec..84607ab01374024aa0a081b6526e6420128b83d5 100644 (file)
@@ -45,7 +45,7 @@ using namespace icinga;
 
 REGISTER_TYPE(OpenTsdbWriter);
 
-REGISTER_STATSFUNCTION(OpenTsdbWriterStats, &OpenTsdbWriter::StatsFunc);
+REGISTER_STATSFUNCTION(OpenTsdbWriter, &OpenTsdbWriter::StatsFunc);
 
 void OpenTsdbWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index 44e000d0296f52781d1902528d24b1c3f411ae04..257b0e9599c81e92b116281769c21beb08becc30 100644 (file)
@@ -36,7 +36,7 @@ using namespace icinga;
 
 REGISTER_TYPE(PerfdataWriter);
 
-REGISTER_STATSFUNCTION(PerfdataWriterStats, &PerfdataWriter::StatsFunc);
+REGISTER_STATSFUNCTION(PerfdataWriter, &PerfdataWriter::StatsFunc);
 
 void PerfdataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 {
index 8e90966a4bf16d3f75bdce5468a2a743932034e3..f802bbb3990502da0d6ce8885f6c9f2e2c8f18ab 100644 (file)
@@ -29,7 +29,7 @@ set(remote_SOURCES
   endpoint.cpp endpoint.thpp filterutility.cpp
   httpchunkedencoding.cpp httpclientconnection.cpp httpserverconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp
   httputility.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp
-  messageorigin.cpp modifyobjecthandler.cpp statusqueryhandler.cpp typequeryhandler.cpp
+  messageorigin.cpp modifyobjecthandler.cpp statushandler.cpp statusqueryhandler.cpp typequeryhandler.cpp
   url.cpp zone.cpp zone.thpp
 )
 
index 7e45995e80f0e958191871e114359d15675a4475..4c9c87dfd5ec5020d7d4f7d89b9fa932e23a203c 100644 (file)
@@ -42,7 +42,7 @@ REGISTER_TYPE(ApiListener);
 
 boost::signals2::signal<void(bool)> ApiListener::OnMasterChanged;
 
-REGISTER_STATSFUNCTION(ApiListenerStats, &ApiListener::StatsFunc);
+REGISTER_STATSFUNCTION(ApiListener, &ApiListener::StatsFunc);
 
 REGISTER_APIFUNCTION(Hello, icinga, &ApiListener::HelloAPIHandler);
 
@@ -833,7 +833,6 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client)
 
 void ApiListener::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
 {
-       Dictionary::Ptr nodes = new Dictionary();
        std::pair<Dictionary::Ptr, Dictionary::Ptr> stats;
 
        ApiListener::Ptr listener = ApiListener::GetInstance();
diff --git a/lib/remote/statushandler.cpp b/lib/remote/statushandler.cpp
new file mode 100644 (file)
index 0000000..c6c9bf9
--- /dev/null
@@ -0,0 +1,101 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2015 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 "remote/statushandler.hpp"
+#include "remote/httputility.hpp"
+#include "base/serializer.hpp"
+#include "base/statsfunction.hpp"
+
+using namespace icinga;
+
+REGISTER_URLHANDLER("/v1/status", StatusHandler);
+
+bool StatusHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
+{
+       Dictionary::Ptr result = new Dictionary();
+
+       if (request.RequestMethod != "GET") {
+               response.SetStatus(400, "Bad request");
+               result->Set("info", "Request must be type GET");
+               HttpUtility::SendJsonBody(response, result);
+               return true;
+       }
+
+       if (request.RequestUrl->GetPath().size() < 2) {
+               response.SetStatus(400, "Bad request");
+               HttpUtility::SendJsonBody(response, result);
+               return true;
+       }
+
+       Array::Ptr results = new Array();
+       Dictionary::Ptr resultInner = new Dictionary();
+
+       if (request.RequestUrl->GetPath().size() > 2) {
+
+               StatsFunction::Ptr funcptr = StatsFunctionRegistry::GetInstance()->GetItem(request.RequestUrl->GetPath()[2]);
+               resultInner = new Dictionary();
+
+               if (!funcptr)
+                       return false;
+
+               results->Add(resultInner);
+
+               Dictionary::Ptr status = new Dictionary();
+               Array::Ptr perfdata = new Array();
+               funcptr->Invoke(status, perfdata);
+
+               resultInner->Set("status", status);
+               resultInner->Set("perfdata", perfdata);
+       } else {
+               typedef std::pair<String, StatsFunction::Ptr> kv_pair;
+               BOOST_FOREACH(const kv_pair& kv, StatsFunctionRegistry::GetInstance()->GetItems()) {
+                       resultInner = new Dictionary();
+                       resultInner->Set("name", kv.first);
+                       results->Add(resultInner);
+               }
+       }
+
+       result->Set("results", results);
+
+       response.SetStatus(200, "OK");
+       HttpUtility::SendJsonBody(response, result);
+
+       return true;
+}
+
+REGISTER_STATSFUNCTION(Collection, &StatusHandler::StatsFunc);
+
+void StatusHandler::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
+{
+       typedef std::pair<String, StatsFunction::Ptr> kv_pair;
+       BOOST_FOREACH(const kv_pair& kv, StatsFunctionRegistry::GetInstance()->GetItems()) {
+               if (kv.first == "Collection") //TODO Find a better name
+                       continue;
+
+               Dictionary::Ptr funcStatus = new Dictionary();
+               Array::Ptr funcPData = new Array();
+               kv.second->Invoke(funcStatus, funcPData);
+
+               Dictionary::Ptr result = new Dictionary();
+               result->Set("status", funcStatus);
+               result->Set("perfdata", funcPData);
+               status->Set(kv.first, result);
+       }
+}
+
diff --git a/lib/remote/statushandler.hpp b/lib/remote/statushandler.hpp
new file mode 100644 (file)
index 0000000..0e3192a
--- /dev/null
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2015 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 STATUSHANDLER_H
+#define STATUSHANDLER_H
+
+#include "remote/httphandler.hpp"
+
+namespace icinga
+{
+
+class I2_REMOTE_API StatusHandler : public HttpHandler
+{
+public:
+       DECLARE_PTR_TYPEDEFS(StatusHandler);
+
+       virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response) override;
+       static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
+};
+
+}
+
+#endif /* STATUSHANDLER_H */