Implement StatsFunction Registry for features.

Refs #5622
This commit is contained in:
Michael Friedrich 2014-02-17 16:34:18 +01:00
parent 7c280bcfff
commit 84be5e3413
36 changed files with 352 additions and 20 deletions

View File

@ -25,11 +25,20 @@
#include "base/utility.h"
#include "base/logger_fwd.h"
#include "base/exception.h"
#include "base/statsfunction.h"
#include <boost/foreach.hpp>
using namespace icinga;
REGISTER_TYPE(CheckerComponent);
REGISTER_STATSFUNCTION(CheckerComponentStats, &CheckerComponent::StatsFunc);
Value CheckerComponent::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
status->Set("checkercomponent_", 1);
return 0;
}
void CheckerComponent::OnConfigLoaded(void)
{

View File

@ -71,6 +71,8 @@ public:
virtual void Start(void);
virtual void Stop(void);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
private:
boost::mutex m_Mutex;
boost::condition_variable m_CV;

View File

@ -31,12 +31,22 @@
#include "base/application.h"
#include "base/convert.h"
#include "base/context.h"
#include "base/statsfunction.h"
#include <fstream>
using namespace icinga;
REGISTER_TYPE(ClusterListener);
REGISTER_STATSFUNCTION(ClusterListenerStats, &ClusterListener::StatsFunc);
Value ClusterListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
status->Set("clusterlistener_", 1);
return 0;
}
/**
* Starts the component.
*/
@ -1637,22 +1647,11 @@ Dictionary::Ptr ClusterListener::GetClusterStatus(void)
bag->Set("not_conn_endpoints", not_connected_endpoints);
/* features */
bag->Set("feature_CheckerComponent", SupportsChecks() ? 1 : 0);
bag->Set("feature_NotificationComponent", SupportsNotifications() ? 1 : 0);
/* XXX find a more generic way of getting features as a list */
bag->Set("feature_IdoMysqlConnection", SupportsFeature("IdoMysqlConnection") ? 1 : 0);
bag->Set("feature_IdoPgsqlConnection", SupportsFeature("IdoPgsqlConnection") ? 1 : 0);
bag->Set("feature_StatusDataWriter", SupportsFeature("StatusDataWriter") ? 1 : 0);
bag->Set("feature_CompatLogger", SupportsFeature("CompatLogger") ? 1 : 0);
bag->Set("feature_ExternalCommandListener", SupportsFeature("ExternalCommandListener") ? 1 : 0);
bag->Set("feature_CheckResultReader", SupportsFeature("CheckResultReader") ? 1 : 0);
bag->Set("feature_LivestatusListener", SupportsFeature("LivestatusListener") ? 1 : 0);
bag->Set("feature_GraphiteWriter", SupportsFeature("GraphiteWriter") ? 1 : 0);
bag->Set("feature_PerfdataWriter", SupportsFeature("PerfdataWriter") ? 1 : 0);
bag->Set("feature_FileLogger", SupportsFeature("FileLogger") ? 1 : 0);
bag->Set("feature_SyslogLogger", SupportsFeature("SyslogLogger") ? 1 : 0);
std::pair<Dictionary::Ptr, Dictionary::Ptr> stats = CIB::GetFeatureStats();
/* XXX find a more clean way */
bag->Set("feature_status", stats.first);
bag->Set("feature_perfdata", stats.second);
/* icinga stats */
double interval = Utility::GetTime() - Application::GetStartTime();

View File

@ -45,6 +45,8 @@ public:
DECLARE_PTR_TYPEDEFS(ClusterListener);
DECLARE_TYPENAME(ClusterListener);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
virtual void Start(void);
virtual void Stop(void);

View File

@ -29,12 +29,23 @@
#include "base/utility.h"
#include "base/exception.h"
#include "base/context.h"
#include "base/statsfunction.h"
#include <fstream>
using namespace icinga;
REGISTER_TYPE(CheckResultReader);
REGISTER_STATSFUNCTION(CheckResultReaderStats, &CheckResultReader::StatsFunc);
Value CheckResultReader::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("checkresultreader_", 1);
return 0;
}
/**
* @threadsafety Always.
*/

View File

@ -38,6 +38,8 @@ public:
DECLARE_PTR_TYPEDEFS(CheckResultReader);
DECLARE_TYPENAME(CheckResultReader);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);

View File

@ -34,6 +34,7 @@
#include "base/application.h"
#include "base/utility.h"
#include "base/scriptfunction.h"
#include "base/statsfunction.h"
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
@ -42,6 +43,16 @@ using namespace icinga;
REGISTER_TYPE(CompatLogger);
REGISTER_SCRIPTFUNCTION(ValidateRotationMethod, &CompatLogger::ValidateRotationMethod);
REGISTER_STATSFUNCTION(CompatLoggerStats, &CompatLogger::StatsFunc);
Value CompatLogger::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("compatlogger_", 1);
return 0;
}
/**
* @threadsafety Always.
*/

View File

@ -39,6 +39,8 @@ public:
DECLARE_PTR_TYPEDEFS(CompatLogger);
DECLARE_TYPENAME(CompatLogger);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
static void ValidateRotationMethod(const String& location, const Dictionary::Ptr& attrs);
protected:

View File

@ -23,11 +23,22 @@
#include "base/logger_fwd.h"
#include "base/exception.h"
#include "base/application.h"
#include "base/statsfunction.h"
using namespace icinga;
REGISTER_TYPE(ExternalCommandListener);
REGISTER_STATSFUNCTION(ExternalCommandListenerStats, &ExternalCommandListener::StatsFunc);
Value ExternalCommandListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("externalcommandlisterner_", 1);
return 0;
}
/**
* Starts the component.
*/

View File

@ -38,6 +38,8 @@ class ExternalCommandListener : public ObjectImpl<ExternalCommandListener>
public:
DECLARE_PTR_TYPEDEFS(ExternalCommandListener);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);

View File

@ -34,6 +34,7 @@
#include "base/exception.h"
#include "base/application.h"
#include "base/context.h"
#include "base/statsfunction.h"
#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/algorithm/string/replace.hpp>
@ -43,6 +44,16 @@ using namespace icinga;
REGISTER_TYPE(StatusDataWriter);
REGISTER_STATSFUNCTION(StatusDataWriterStats, &StatusDataWriter::StatsFunc);
Value StatusDataWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("statusdatawriter_", 1);
return 0;
}
/**
* Hint: The reason why we're using "\n" rather than std::endl is because
* std::endl also _flushes_ the output stream which severely degrades

View File

@ -42,6 +42,8 @@ class StatusDataWriter : public ObjectImpl<StatusDataWriter>
public:
DECLARE_PTR_TYPEDEFS(StatusDataWriter);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);

View File

@ -24,6 +24,7 @@
#include "base/application.h"
#include "base/dynamictype.h"
#include "base/exception.h"
#include "base/statsfunction.h"
#include "db_ido/dbtype.h"
#include "db_ido/dbvalue.h"
#include "db_ido_mysql/idomysqlconnection.h"
@ -32,10 +33,19 @@
using namespace icinga;
REGISTER_TYPE(IdoMysqlConnection);
#define SCHEMA_VERSION "1.11.0"
REGISTER_TYPE(IdoMysqlConnection);
REGISTER_STATSFUNCTION(IdoMysqlConnectionStats, &IdoMysqlConnection::StatsFunc);
Value IdoMysqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("ido_mysql_version_req", SCHEMA_VERSION);
return 0;
}
void IdoMysqlConnection::Start(void)
{
DbConnection::Start();

View File

@ -41,6 +41,8 @@ class IdoMysqlConnection : public ObjectImpl<IdoMysqlConnection>
public:
DECLARE_PTR_TYPEDEFS(IdoMysqlConnection);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);
virtual void Stop(void);

View File

@ -25,6 +25,7 @@
#include "base/dynamictype.h"
#include "base/exception.h"
#include "base/context.h"
#include "base/statsfunction.h"
#include "db_ido/dbtype.h"
#include "db_ido/dbvalue.h"
#include "db_ido_pgsql/idopgsqlconnection.h"
@ -33,9 +34,19 @@
using namespace icinga;
#define SCHEMA_VERSION "1.11.0"
REGISTER_TYPE(IdoPgsqlConnection);
#define SCHEMA_VERSION "1.11.0"
REGISTER_STATSFUNCTION(IdoPgsqlConnectionStats, &IdoPgsqlConnection::StatsFunc);
Value IdoPgsqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("ido_pgsql_version_req", SCHEMA_VERSION);
return 0;
}
void IdoPgsqlConnection::Start(void)
{

View File

@ -41,6 +41,8 @@ class IdoPgsqlConnection : public ObjectImpl<IdoPgsqlConnection>
public:
DECLARE_PTR_TYPEDEFS(IdoPgsqlConnection);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);
virtual void Stop(void);

View File

@ -29,6 +29,7 @@
#include "base/networkstream.h"
#include "base/application.h"
#include "base/scriptfunction.h"
#include "base/statsfunction.h"
#include "base/convert.h"
using namespace icinga;
@ -40,6 +41,16 @@ static int l_ClientsConnected = 0;
static int l_Connections = 0;
static boost::mutex l_ComponentMutex;
REGISTER_STATSFUNCTION(LivestatusListenerStats, &LivestatusListener::StatsFunc);
Value LivestatusListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("livestatus_connections", l_Connections);
return 0;
}
/**
* Starts the component.
*/

View File

@ -38,6 +38,8 @@ class LivestatusListener : public ObjectImpl<LivestatusListener>
public:
DECLARE_PTR_TYPEDEFS(LivestatusListener);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
static int GetClientsConnected(void);
static int GetConnections(void);

View File

@ -24,12 +24,23 @@
#include "base/logger_fwd.h"
#include "base/utility.h"
#include "base/exception.h"
#include "base/statsfunction.h"
#include <boost/foreach.hpp>
using namespace icinga;
REGISTER_TYPE(NotificationComponent);
REGISTER_STATSFUNCTION(NotificationComponentStats, &NotificationComponent::StatsFunc);
Value NotificationComponent::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("notification_", 1);
return 0;
}
/**
* Starts the component.
*/

View File

@ -36,6 +36,8 @@ class NotificationComponent : public ObjectImpl<NotificationComponent>
public:
DECLARE_PTR_TYPEDEFS(NotificationComponent);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
virtual void Start(void);
private:

View File

@ -34,6 +34,7 @@
#include "base/networkstream.h"
#include "base/bufferedstream.h"
#include "base/exception.h"
#include "base/statsfunction.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/foreach.hpp>
@ -44,6 +45,16 @@ using namespace icinga;
REGISTER_TYPE(GraphiteWriter);
REGISTER_STATSFUNCTION(GraphiteWriterStats, &GraphiteWriter::StatsFunc);
Value GraphiteWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("graphite_writer_", 1);
return 0;
}
void GraphiteWriter::Start(void)
{
DynamicObject::Start();

View File

@ -41,6 +41,8 @@ public:
DECLARE_PTR_TYPEDEFS(GraphiteWriter);
DECLARE_TYPENAME(GraphiteWriter);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);

View File

@ -28,11 +28,22 @@
#include "base/utility.h"
#include "base/context.h"
#include "base/application.h"
#include "base/statsfunction.h"
using namespace icinga;
REGISTER_TYPE(PerfdataWriter);
REGISTER_STATSFUNCTION(PerfdataWriterStats, &PerfdataWriter::StatsFunc);
Value PerfdataWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("perfdatawriter_", 1);
return 0;
}
void PerfdataWriter::Start(void)
{
DynamicObject::Start();

View File

@ -40,6 +40,8 @@ public:
DECLARE_PTR_TYPEDEFS(PerfdataWriter);
DECLARE_TYPENAME(PerfdataWriter);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void Start(void);

View File

@ -31,7 +31,7 @@ add_library(base SHARED
process-unix.cpp process-windows.cpp qstring.cpp ringbuffer.cpp script.cpp
script.th scriptfunction.cpp scriptfunctionwrapper.cpp scriptinterpreter.cpp
scriptlanguage.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
stdiostream.cpp stream_bio.cpp stream.cpp streamlogger.cpp streamlogger.th
statsfunction.cpp stdiostream.cpp stream_bio.cpp stream.cpp streamlogger.cpp streamlogger.th
sysloglogger.cpp sysloglogger.th tcpsocket.cpp threadpool.cpp timer.cpp
tlsstream.cpp tlsutility.cpp type.cpp unixsocket.cpp utility.cpp value.cpp
workqueue.cpp zlibstream.cpp

View File

@ -59,7 +59,7 @@ struct DictionaryKeyLessComparer
};
/**
* Restrieves a value from a dictionary.
* Retrieves a value from a dictionary.
*
* @param key The key whose value should be retrieved.
* @returns The value of an empty value if the key was not found.

View File

@ -19,12 +19,23 @@
#include "base/filelogger.h"
#include "base/dynamictype.h"
#include "base/statsfunction.h"
#include <fstream>
using namespace icinga;
REGISTER_TYPE(FileLogger);
REGISTER_STATSFUNCTION(FileLoggerStats, &FileLogger::StatsFunc);
Value FileLogger::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("filelogger_", 1);
return 0;
}
/**
* Constructor for the FileLogger class.
*/

View File

@ -36,6 +36,8 @@ class I2_BASE_API FileLogger : public ObjectImpl<FileLogger>
public:
DECLARE_PTR_TYPEDEFS(FileLogger);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
virtual void Start(void);
};

View File

@ -0,0 +1,45 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-present 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 "base/statsfunction.h"
#include "base/registry.h"
#include "base/singleton.h"
using namespace icinga;
StatsFunction::StatsFunction(const Callback& function)
: m_Callback(function)
{ }
Value StatsFunction::Invoke(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
return m_Callback(status, perfdata);
}
RegisterStatsFunctionHelper::RegisterStatsFunctionHelper(const String& name, const StatsFunction::Callback& function)
{
StatsFunction::Ptr func = make_shared<StatsFunction>(function);
StatsFunctionRegistry::GetInstance()->Register(name, func);
}
StatsFunctionRegistry *StatsFunctionRegistry::GetInstance(void)
{
return Singleton<StatsFunctionRegistry>::GetInstance();
}

81
lib/base/statsfunction.h Normal file
View File

@ -0,0 +1,81 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-present 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 STATSFUNCTION_H
#define STATSFUNCTION_H
#include "base/i2-base.h"
#include "base/registry.h"
#include "base/singleton.h"
#include "base/value.h"
#include "base/dictionary.h"
#include <vector>
#include <boost/function.hpp>
namespace icinga
{
/**
* A stats function that can be used to execute a stats task.
*
* @ingroup base
*/
class I2_BASE_API StatsFunction : public Object
{
public:
DECLARE_PTR_TYPEDEFS(StatsFunction);
typedef boost::function<Value (Dictionary::Ptr& status, Dictionary::Ptr& perfdata)> Callback;
StatsFunction(const Callback& function);
Value Invoke(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
private:
Callback m_Callback;
};
/**
* A registry for script functions.
*
* @ingroup base
*/
class I2_BASE_API StatsFunctionRegistry : public Registry<StatsFunctionRegistry, StatsFunction::Ptr>
{
public:
static StatsFunctionRegistry *GetInstance(void);
};
/**
* Helper class for registering StatsFunction implementation classes.
*
* @ingroup base
*/
class I2_BASE_API RegisterStatsFunctionHelper
{
public:
RegisterStatsFunctionHelper(const String& name, const StatsFunction::Callback& function);
};
#define REGISTER_STATSFUNCTION(name, callback) \
I2_EXPORT icinga::RegisterStatsFunctionHelper g_RegisterSF_ ## name(#name, callback)
}
#endif /* STATSFUNCTION_H */

View File

@ -19,12 +19,23 @@
#include "base/sysloglogger.h"
#include "base/dynamictype.h"
#include "base/statsfunction.h"
#ifndef _WIN32
using namespace icinga;
REGISTER_TYPE(SyslogLogger);
REGISTER_STATSFUNCTION(SyslogLoggerStats, &SyslogLogger::StatsFunc);
Value SyslogLogger::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("sysloglogger_", 1);
return 0;
}
/**
* Processes a log entry and outputs it to syslog.
*

View File

@ -37,6 +37,8 @@ class I2_BASE_API SyslogLogger : public ObjectImpl<SyslogLogger>
public:
DECLARE_PTR_TYPEDEFS(SyslogLogger);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
protected:
virtual void ProcessLogEntry(const LogEntry& entry);
};

View File

@ -22,7 +22,9 @@
#include "base/objectlock.h"
#include "base/utility.h"
#include "base/dynamictype.h"
#include "base/statsfunction.h"
#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>
using namespace icinga;
@ -166,3 +168,24 @@ HostStatistics CIB::CalculateHostStats(void)
return hs;
}
std::pair<Dictionary::Ptr, Dictionary::Ptr> CIB::GetFeatureStats(void)
{
Dictionary::Ptr status = make_shared<Dictionary>();
Dictionary::Ptr perfdata = make_shared<Dictionary>();
String name;
Value ret;
BOOST_FOREACH(boost::tie(name, boost::tuples::ignore), StatsFunctionRegistry::GetInstance()->GetItems()) {
StatsFunction::Ptr func = StatsFunctionRegistry::GetInstance()->GetItem(name);
if (!func)
BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + name + "' does not exist."));
ret = func->Invoke(status, perfdata);
}
return std::make_pair(status, perfdata);
}

View File

@ -22,6 +22,7 @@
#include "icinga/i2-icinga.h"
#include "base/ringbuffer.h"
#include "base/dictionary.h"
namespace icinga
{
@ -76,6 +77,8 @@ public:
static ServiceStatistics CalculateServiceStats(void);
static HostStatistics CalculateHostStats(void);
static std::pair<Dictionary::Ptr, Dictionary::Ptr> GetFeatureStats(void);
private:
CIB(void);

View File

@ -27,6 +27,7 @@
#include "base/timer.h"
#include "base/scriptvariable.h"
#include "base/initialize.h"
#include "base/statsfunction.h"
using namespace icinga;
@ -45,6 +46,16 @@ void IcingaApplication::StaticInitialize(void)
ScriptVariable::Set("IcingaNodeName", Utility::GetHostName());
}
REGISTER_STATSFUNCTION(IcingaApplicationStats, &IcingaApplication::StatsFunc);
Value IcingaApplication::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
{
/* FIXME */
status->Set("icingaapplication_", 1);
return 0;
}
/**
* The entry point for the Icinga application.
*

View File

@ -42,6 +42,8 @@ public:
int Main(void);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
static IcingaApplication::Ptr GetInstance(void);
String GetPidPath(void) const;