From 4ef9761fee75f2931319e50a77d64757c382a438 Mon Sep 17 00:00:00 2001 From: Jean-Marcel Flach Date: Mon, 21 Sep 2015 11:44:58 +0200 Subject: [PATCH] Implement status api handler Global statistics, features, etc. fixes #10116 --- doc/9-icinga2-api.md | 66 ++++++++++++-- lib/base/filelogger.cpp | 2 +- lib/base/sysloglogger.cpp | 2 +- lib/checker/checkercomponent.cpp | 2 +- lib/compat/checkresultreader.cpp | 2 +- lib/compat/compatlogger.cpp | 2 +- lib/compat/externalcommandlistener.cpp | 2 +- lib/compat/statusdatawriter.cpp | 2 +- lib/db_ido_mysql/idomysqlconnection.cpp | 2 +- lib/db_ido_pgsql/idopgsqlconnection.cpp | 2 +- lib/icinga/cib.cpp | 60 ++++++++++++ lib/icinga/cib.hpp | 2 + lib/icinga/icingaapplication.cpp | 2 +- lib/icinga/icingastatuswriter.cpp | 2 +- lib/livestatus/livestatuslistener.cpp | 2 +- lib/notification/notificationcomponent.cpp | 2 +- lib/perfdata/graphitewriter.cpp | 2 +- lib/perfdata/opentsdbwriter.cpp | 2 +- lib/perfdata/perfdatawriter.cpp | 2 +- lib/remote/CMakeLists.txt | 2 +- lib/remote/apilistener.cpp | 3 +- lib/remote/statushandler.cpp | 101 +++++++++++++++++++++ lib/remote/statushandler.hpp | 39 ++++++++ 23 files changed, 279 insertions(+), 26 deletions(-) create mode 100644 lib/remote/statushandler.cpp create mode 100644 lib/remote/statushandler.hpp diff --git a/doc/9-icinga2-api.md b/doc/9-icinga2-api.md index 929f643aa..4f6edbdb0 100644 --- a/doc/9-icinga2-api.md +++ b/doc/9-icinga2-api.md @@ -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. ### 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 +## 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" + } + } + } + } + ] + } ## API Objects diff --git a/lib/base/filelogger.cpp b/lib/base/filelogger.cpp index afd4c606b..7fa3197f0 100644 --- a/lib/base/filelogger.cpp +++ b/lib/base/filelogger.cpp @@ -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&) { diff --git a/lib/base/sysloglogger.cpp b/lib/base/sysloglogger.cpp index b94cc4f67..912cef04c 100644 --- a/lib/base/sysloglogger.cpp +++ b/lib/base/sysloglogger.cpp @@ -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&) { diff --git a/lib/checker/checkercomponent.cpp b/lib/checker/checkercomponent.cpp index fa7bf978a..dd7522562 100644 --- a/lib/checker/checkercomponent.cpp +++ b/lib/checker/checkercomponent.cpp @@ -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) { diff --git a/lib/compat/checkresultreader.cpp b/lib/compat/checkresultreader.cpp index eb344ee70..3301f9fc4 100644 --- a/lib/compat/checkresultreader.cpp +++ b/lib/compat/checkresultreader.cpp @@ -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&) { diff --git a/lib/compat/compatlogger.cpp b/lib/compat/compatlogger.cpp index b23622f7a..46692088e 100644 --- a/lib/compat/compatlogger.cpp +++ b/lib/compat/compatlogger.cpp @@ -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&) { diff --git a/lib/compat/externalcommandlistener.cpp b/lib/compat/externalcommandlistener.cpp index ec5beca15..eefe4649f 100644 --- a/lib/compat/externalcommandlistener.cpp +++ b/lib/compat/externalcommandlistener.cpp @@ -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&) { diff --git a/lib/compat/statusdatawriter.cpp b/lib/compat/statusdatawriter.cpp index 893f517ec..8f71cefcc 100644 --- a/lib/compat/statusdatawriter.cpp +++ b/lib/compat/statusdatawriter.cpp @@ -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&) { diff --git a/lib/db_ido_mysql/idomysqlconnection.cpp b/lib/db_ido_mysql/idomysqlconnection.cpp index 7e9c2c1b8..c04e374d9 100644 --- a/lib/db_ido_mysql/idomysqlconnection.cpp +++ b/lib/db_ido_mysql/idomysqlconnection.cpp @@ -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) diff --git a/lib/db_ido_pgsql/idopgsqlconnection.cpp b/lib/db_ido_pgsql/idopgsqlconnection.cpp index c9e171bf2..d04a61696 100644 --- a/lib/db_ido_pgsql/idopgsqlconnection.cpp +++ b/lib/db_ido_pgsql/idopgsqlconnection.cpp @@ -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) diff --git a/lib/icinga/cib.cpp b/lib/icinga/cib.cpp index 5f8aabd3a..af9c8bf05 100644 --- a/lib/icinga/cib.cpp +++ b/lib/icinga/cib.cpp @@ -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 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); +} diff --git a/lib/icinga/cib.hpp b/lib/icinga/cib.hpp index 13f02ad96..15afedb9f 100644 --- a/lib/icinga/cib.hpp +++ b/lib/icinga/cib.hpp @@ -87,6 +87,8 @@ public: static std::pair GetFeatureStats(void); + static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); + private: CIB(void); diff --git a/lib/icinga/icingaapplication.cpp b/lib/icinga/icingaapplication.cpp index 743e12e79..6f531e101 100644 --- a/lib/icinga/icingaapplication.cpp +++ b/lib/icinga/icingaapplication.cpp @@ -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) { diff --git a/lib/icinga/icingastatuswriter.cpp b/lib/icinga/icingastatuswriter.cpp index 12b211b85..d9be27dfc 100644 --- a/lib/icinga/icingastatuswriter.cpp +++ b/lib/icinga/icingastatuswriter.cpp @@ -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) { diff --git a/lib/livestatus/livestatuslistener.cpp b/lib/livestatus/livestatuslistener.cpp index da55f6f90..747c2c9a0 100644 --- a/lib/livestatus/livestatuslistener.cpp +++ b/lib/livestatus/livestatuslistener.cpp @@ -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) { diff --git a/lib/notification/notificationcomponent.cpp b/lib/notification/notificationcomponent.cpp index b85e8ecd4..9660bfca1 100644 --- a/lib/notification/notificationcomponent.cpp +++ b/lib/notification/notificationcomponent.cpp @@ -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&) { diff --git a/lib/perfdata/graphitewriter.cpp b/lib/perfdata/graphitewriter.cpp index 4bd3291cd..3e7640e5d 100644 --- a/lib/perfdata/graphitewriter.cpp +++ b/lib/perfdata/graphitewriter.cpp @@ -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&) { diff --git a/lib/perfdata/opentsdbwriter.cpp b/lib/perfdata/opentsdbwriter.cpp index 101fa8f41..84607ab01 100644 --- a/lib/perfdata/opentsdbwriter.cpp +++ b/lib/perfdata/opentsdbwriter.cpp @@ -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&) { diff --git a/lib/perfdata/perfdatawriter.cpp b/lib/perfdata/perfdatawriter.cpp index 44e000d02..257b0e959 100644 --- a/lib/perfdata/perfdatawriter.cpp +++ b/lib/perfdata/perfdatawriter.cpp @@ -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&) { diff --git a/lib/remote/CMakeLists.txt b/lib/remote/CMakeLists.txt index 8e90966a4..f802bbb39 100644 --- a/lib/remote/CMakeLists.txt +++ b/lib/remote/CMakeLists.txt @@ -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 ) diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 7e45995e8..4c9c87dfd 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -42,7 +42,7 @@ REGISTER_TYPE(ApiListener); boost::signals2::signal 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 stats; ApiListener::Ptr listener = ApiListener::GetInstance(); diff --git a/lib/remote/statushandler.cpp b/lib/remote/statushandler.cpp new file mode 100644 index 000000000..c6c9bf982 --- /dev/null +++ b/lib/remote/statushandler.cpp @@ -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 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 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 index 000000000..0e3192ae5 --- /dev/null +++ b/lib/remote/statushandler.hpp @@ -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 */ -- 2.40.0