The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit ed0d3654 authored by Alessio Netti's avatar Alessio Netti
Browse files

Merge remote-tracking branch 'remotes/origin/development'

parents 7142e0f0 47da1a33
......@@ -220,7 +220,7 @@ void OperatorManager::unloadPlugin(const string& id) {
_plugins.clear();
}
bool OperatorManager::init(boost::asio::io_service& io, const string& plugin) {
bool OperatorManager::init(const string& plugin) {
if(_status != LOADED) {
LOG(error) << "Cannot init, OperatorManager is not loaded!";
return false;
......@@ -232,12 +232,12 @@ bool OperatorManager::init(boost::asio::io_service& io, const string& plugin) {
out = true;
LOG(info) << "Init " << p.id << " operator plugin";
for (const auto &op : p.configurator->getOperators())
op->init(io);
op->init(_io);
}
return out;
}
bool OperatorManager::reload(boost::asio::io_service& io, const string& plugin) {
bool OperatorManager::reload(const string& plugin) {
if(_status != LOADED) {
LOG(error) << "Cannot reload, OperatorManager is not loaded!";
return false;
......@@ -259,7 +259,7 @@ bool OperatorManager::reload(boost::asio::io_service& io, const string& plugin)
return false;
} else
for (const auto &op : p.configurator->getOperators())
op->init(io);
op->init(_io);
}
return out;
}
......
......@@ -82,8 +82,9 @@ public:
/**
* @brief Class constructor
* @param io Boost ASIO service to be used
*/
OperatorManager() { _status = CLEAR; }
OperatorManager(boost::asio::io_context& io) : _io(io) { _status = CLEAR; }
/**
* @brief Class destructor
......@@ -130,11 +131,10 @@ public:
* This method must be called after "load", and before "start". It will prepare operators for
* operation, and initialize the related sensors and caches.
*
* @param io Boost ASIO service to be used
* @param plugin Name of the plugin on which the action must be performed. If none, all plugins will be affected
* @return true if successful, false otherwise
*/
bool init(boost::asio::io_service& io, const string& plugin="");
bool init(const string& plugin="");
/**
* @brief Reload one or more plugins
......@@ -142,11 +142,10 @@ public:
* This method will cause all running operators of a plugin to be stopped and destroyed. The
* configuration file is then read once again, and new operators are created and initialized.
*
* @param io Boost ASIO service to be used
* @param plugin Name of the plugin on which the action must be performed. If none, all plugins will be affected
* @return true if successful, false otherwise
*/
bool reload(boost::asio::io_service& io, const string& plugin="");
bool reload(const string& plugin="");
/**
* @brief Start one or more stored plugins
......@@ -452,6 +451,7 @@ private:
*/
void PUT_analytics_operator(endpointArgs);
boost::asio::io_context& _io;
};
#endif //PROJECT_ANALYTICSMANAGER_H
......@@ -237,7 +237,7 @@ public:
virtual void init(boost::asio::io_service& io) final override {
OperatorInterface::init(io);
for(const auto u : _units)
for(const auto& u : _units)
u->init(_interval, _queueSize);
this->execOnInit();
......
......@@ -180,11 +180,11 @@ public:
* @param interval Sampling interval in milliseconds
*/
void init(unsigned int interval, unsigned int queueSize) override {
for(const auto s : _outputs)
for(const auto &s : _outputs)
if (!s->isInit())
s->initSensor(interval, queueSize);
for (const auto &su : _subUnits)
for (const auto s : su->getOutputs())
for (const auto &s : su->getOutputs())
if (!s->isInit())
s->initSensor(interval, queueSize);
}
......
......@@ -219,7 +219,7 @@ void CARestAPI::POST_write(endpointArgs) {
DCDB::SensorId sid;
if (sid.mqttTopicConvert(mqttTopic)) {
_sensorCache->storeSensor(sid, ts.getRaw(), value);
_sensorDataStore->insert(&sid, ts.getRaw(), value);
_sensorDataStore->insert(sid, ts.getRaw(), value);
_influxCounter++;
if (_influxSettings->publish && (_influxSensors.find(sid.getId()) == _influxSensors.end())) {
......@@ -267,7 +267,7 @@ void CARestAPI::PUT_analytics_reload(endpointArgs) {
// Wait until controller is paused in order to reload plugins
_analyticsController->halt(true);
if (!_analyticsController->getManager()->reload(_analyticsController->getIoService(), plugin)) {
if (!_analyticsController->getManager()->reload(plugin)) {
res.body() = "Plugin not found or reload failed, please check the config files and MQTT topics!\n";
res.result(http::status::not_found);
} else if (!_analyticsController->getManager()->start(plugin)) {
......@@ -297,7 +297,7 @@ void CARestAPI::PUT_analytics_load(endpointArgs) {
res.body() = "Operator plugin " + plugin + " successfully loaded!\n";
res.result(http::status::ok);
_analyticsController->getManager()->init(_analyticsController->getIoService(), plugin);
_analyticsController->getManager()->init(plugin);
} else {
res.body() = "Failed to load operator plugin " + plugin + "!\n";
res.result(http::status::internal_server_error);
......
......@@ -86,16 +86,6 @@ bool AnalyticsController::initialize(Configuration& settings) {
if(!_queryEngine.updating.is_lock_free())
LOG(warning) << "This machine does not support lock-free atomics. Performance may be degraded.";
LOG(info) << "Creating threads...";
// Dummy to keep io service alive even if no tasks remain (e.g. because all sensors have been stopped over REST API)
// Inherited from DCDB Pusher
_keepAliveWork = make_shared<boost::asio::io_service::work>(_io);
// Create pool of threads which handle the sensors
for(size_t i = 0; i < _settings.threads; i++) {
_threads.create_thread(bind(static_cast< size_t (boost::asio::io_service::*) () >(&boost::asio::io_service::run), &_io));
}
LOG(info) << "Threads created!";
_initialized = true;
return true;
}
......@@ -106,7 +96,7 @@ void AnalyticsController::run() {
return;
LOG(info) << "Init operators...";
_manager->init(_io);
_manager->init();
LOG(info) << "Starting operators...";
_manager->start();
LOG(info) << "Sensors started!";
......
......@@ -65,10 +65,10 @@ public:
* @param dcdbCfg SensorConfig object to be used to retrieve sensor meta-data from Cassandra
* @param dcdbStore SensorDataStore object to be used to insert sensor readings into Cassandra
*/
AnalyticsController(DCDB::SensorConfig *dcdbCfg, DCDB::SensorDataStore *dcdbStore) {
_dcdbCfg = dcdbCfg;
_dcdbStore = dcdbStore;
_manager = make_shared<OperatorManager>();
AnalyticsController(DCDB::SensorConfig *dcdbCfg, DCDB::SensorDataStore *dcdbStore, boost::asio::io_context& io)
: _dcdbCfg(dcdbCfg),
_dcdbStore(dcdbStore) {
_manager = make_shared<OperatorManager>(io);
_navigator = nullptr;
_sensorCache = nullptr;
_metadataStore = nullptr;
......@@ -179,13 +179,6 @@ public:
*/
uint64_t getReadingCtr() { uint64_t ctr=_readingCtr; _readingCtr=0; return ctr; }
/**
* @brief Return the io_service used by the analytics controller.
*
* @return Reference to this object's boost::asio::io_service.
*/
boost::asio::io_service& getIoService() { return _io; }
/**
* @brief Rebuilds the internal sensor navigator.
*
......@@ -227,8 +220,6 @@ private:
// Main management thread for the analytics controller
boost::thread _mainThread;
// IO service for the operators
boost::asio::io_service _io;
// Underlying thread pool
boost::thread_group _threads;
// Dummy task to keep thread pool alive
......
......@@ -54,6 +54,7 @@
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <dcdb/libconfig.h>
#include <dcdb/connection.h>
#include <dcdb/sensordatastore.h>
#include <dcdb/jobdatastore.h>
......@@ -92,6 +93,7 @@ uint64_t msgCtr;
uint64_t readingCtr;
uint64_t dbQueryCtr;
uint64_t cachedQueryCtr;
uint64_t missesQueryCtr;
SensorCache mySensorCache;
AnalyticsController* analyticsController;
DCDB::Connection* dcdbConn;
......@@ -103,6 +105,7 @@ MetadataStore *metadataStore;
CARestAPI* httpsServer = nullptr;
DCDB::SCError err;
QueryEngine& queryEngine = QueryEngine::getInstance();
boost::shared_ptr<boost::asio::io_context::work> keepAliveWork;
logger_t lg;
bool jobQueryCallback(const string& jobId, const uint64_t startTs, const uint64_t endTs, vector<qeJobData>& buffer, const bool rel, const bool range, const string& domainId) {
......@@ -202,6 +205,8 @@ bool sensorGroupQueryCallback(const std::vector<string>& names, const uint64_t s
reading.timestamp = r.timeStamp.getRaw();
buffer.push_back(reading);
}
} else {
missesQueryCtr += topics.size();
}
}
catch (const std::exception &e) {}
......@@ -271,6 +276,8 @@ void sigHandler(int sig)
LOG(fatal) << "Received SIGUSR1 via REST API";
retCode = !httpsServer ? EXIT_SUCCESS : httpsServer->getReturnCode();
}
keepAliveWork.reset();
keepRunning = 0;
}
......@@ -670,6 +677,9 @@ int main(int argc, char* const argv[]) {
}
}
libConfig.init();
libConfig.setTempDir(pluginSettings.tempdir);
//set up logger to file
if (settings.logLevelFile >= 0) {
auto fileSink = setupFileLogger(pluginSettings.tempdir, std::string("collectagent"));
......@@ -755,7 +765,10 @@ int main(int argc, char* const argv[]) {
}
publicSensors.clear();
analyticsController = new AnalyticsController(mySensorConfig, mySensorDataStore);
boost::asio::io_context io;
boost::thread_group threads;
analyticsController = new AnalyticsController(mySensorConfig, mySensorDataStore, io);
analyticsController->setCache(&mySensorCache);
analyticsController->setMetadataStore(metadataStore);
queryEngine.setFilter(analyticsSettings.filter);
......@@ -779,10 +792,12 @@ int main(int argc, char* const argv[]) {
LOG(info) << " MQTT-listenAddress: " << settings.mqttListenHost << ":" << settings.mqttListenPort;
LOG(info) << " CacheInterval: " << int(pluginSettings.cacheInterval/1000) << " [s]";
LOG(info) << " CleaningInterval: " << settings.cleaningInterval << " [s]";
LOG(info) << " Threads: " << settings.threads;
LOG(info) << " MessageThreads: " << settings.messageThreads;
LOG(info) << " MessageSlots: " << settings.messageSlots;
LOG(info) << " Daemonize: " << (settings.daemonize ? "Enabled" : "Disabled");
LOG(info) << " StatisticsInterval: " << settings.statisticsInterval << " [s]";
LOG(info) << " StatisticsMqttPart: " << settings.statisticsMqttPart;
LOG(info) << " MQTT-prefix: " << pluginSettings.mqttPrefix;
LOG(info) << " Auto-publish: " << (pluginSettings.autoPublish ? "Enabled" : "Disabled");
LOG(info) << " Write-Dir: " << pluginSettings.tempdir;
......@@ -852,8 +867,19 @@ int main(int argc, char* const argv[]) {
if (settings.validateConfig)
return EXIT_SUCCESS;
else
LOG(info) << "Creating threads...";
// Dummy to keep io service alive even if no tasks remain (e.g. because all sensors have been stopped over REST API)
// Inherited from DCDB Pusher
keepAliveWork = boost::make_shared<boost::asio::io_context::work>(io);
// Create pool of threads which handle the sensors
for(size_t i = 0; i < settings.threads; i++) {
threads.create_thread(bind(static_cast< size_t (boost::asio::io_context::*) () >(&boost::asio::io_context::run), &io));
}
LOG(info) << "Threads created!";
analyticsController->start();
LOG(info) << "AnalyticsController running...";
/*
* Start the MQTT Message Server.
......@@ -869,7 +895,7 @@ int main(int argc, char* const argv[]) {
* Start the HTTP Server for the REST API
*/
if (restAPISettings.enabled) {
httpsServer = new CARestAPI(restAPISettings, &config.influxSettings, &mySensorCache, mySensorDataStore, mySensorConfig, analyticsController, &ms, analyticsController->getIoService());
httpsServer = new CARestAPI(restAPISettings, &config.influxSettings, &mySensorCache, mySensorDataStore, mySensorConfig, analyticsController, &ms, io);
config.readRestAPIUsers(httpsServer);
httpsServer->start();
LOG(info) << "HTTP Server running...";
......@@ -886,6 +912,7 @@ int main(int argc, char* const argv[]) {
readingCtr = 0;
dbQueryCtr = 0;
cachedQueryCtr = 0;
missesQueryCtr = 0;
start = getTimestamp();
uint64_t lastCleanup = start;
......@@ -913,11 +940,12 @@ int main(int argc, char* const argv[]) {
elapsed = (float)(NS_TO_S(end) - NS_TO_S(start));
float aIns = ceil(((float)analyticsController->getReadingCtr()) / elapsed);
float cacheReq = ceil(((float)cachedQueryCtr) / elapsed);
float missesReq = ceil(((float)missesQueryCtr) / elapsed);
float dbReq = ceil(((float)dbQueryCtr) / elapsed);
float rIns = restAPISettings.enabled ? ceil(((float)httpsServer->getInfluxCounter()) / elapsed) : 0.0f;
float mIns = ceil(((float)readingCtr) / elapsed);
float mMsg = ceil(((float) msgCtr) / elapsed);
LOG(info) << "Performance: MQTT [" << std::fixed << std::setprecision(0) << mIns << " ins/s|" << mMsg << " msg/s] REST [" << rIns << " ins/s] Analytics [" << aIns << " ins/s] Cache [" << cacheReq << " req/s] DB [" << dbReq << " req/s]";
LOG(info) << "Performance: MQTT [" << std::fixed << std::setprecision(0) << mIns << " ins/s|" << mMsg << " msg/s] REST [" << rIns << " ins/s] Analytics [" << aIns << " ins/s] Cache [" << cacheReq << " req/s] DB [" << dbReq << " req/s] Miss [" << missesReq << " req/s]";
std::map<std::string, hostInfo_t> lastSeen = ms.collectLastSeen();
uint64_t connectedHosts = 0;
for (auto h: lastSeen) {
......@@ -926,8 +954,25 @@ int main(int argc, char* const argv[]) {
}
}
LOG(info) << "Connected hosts: " << connectedHosts;
if (settings.statisticsMqttPart.size() > 0) {
std::string statisticsMqttTopic = pluginSettings.mqttPrefix + settings.statisticsMqttPart;
std::list<SensorDataStoreReading> stats;
stats.push_back(SensorDataStoreReading(SensorId(statisticsMqttTopic+"/msgsRcvd"), end, msgCtr));
stats.push_back(SensorDataStoreReading(SensorId(statisticsMqttTopic+"/cachedQueries"), end, cachedQueryCtr));
stats.push_back(SensorDataStoreReading(SensorId(statisticsMqttTopic+"/missedQueries"), end, missesQueryCtr));
stats.push_back(SensorDataStoreReading(SensorId(statisticsMqttTopic+"/dbQueries"), end, dbQueryCtr));
stats.push_back(SensorDataStoreReading(SensorId(statisticsMqttTopic+"/readingsRcvd"), end, readingCtr));
stats.push_back(SensorDataStoreReading(SensorId(statisticsMqttTopic+"/hosts"), end, connectedHosts));
for (auto s: stats) {
mySensorDataStore->insert(s);
mySensorCache.storeSensor(s);
}
}
msgCtr = 0;
cachedQueryCtr = 0;
missesQueryCtr = 0;
dbQueryCtr = 0;
readingCtr = 0;
}
......
......@@ -61,6 +61,10 @@ void SensorCache::storeSensor(SensorId sid, uint64_t ts, int64_t val) {
}
}
void SensorCache::storeSensor(const SensorDataStoreReading& s) {
storeSensor(s.sensorId, s.timeStamp.getRaw(), s.value);
}
int64_t SensorCache::getSensor(SensorId sid, uint64_t avg) {
/* Remove the reserved bytes to leverage the standard find function */
sid.setRsvd(0);
......
......@@ -32,6 +32,7 @@
#include <atomic>
#include <dcdb/sensorid.h>
#include <dcdb/timestamp.h>
#include <dcdb/sensordatastore.h>
#include "cacheentry.h"
using namespace DCDB;
......@@ -63,6 +64,13 @@ public:
**/
void storeSensor(SensorId sid, uint64_t ts, int64_t val);
/**
* @brief Store a sensor reading in the SensorCache.
*
* @param s The SensorDataStoreReading object of the sensor data to be cached.
**/
void storeSensor(const SensorDataStoreReading& s);
/**
* @brief Return a sensor reading or the average of the last readings
* from the SensorCache.
......
......@@ -207,6 +207,7 @@ public:
bool validateConfig = false;
bool daemonize = false;
int statisticsInterval = 60;
std::string statisticsMqttPart;
uint64_t threads = DEFAULT_THREADS;
int logLevelFile = -1;
int logLevelCmd = DEFAULT_LOGLEVEL;
......
......@@ -59,7 +59,8 @@ public:
SCALE_SET = 128,
TTL_SET = 256,
INTERVAL_SET = 512,
OPERATIONS_SET = 1024
OPERATIONS_SET = 1024,
DELTA_SET = 2048
} MetadataMask;
SensorMetadata() :
......@@ -74,6 +75,7 @@ public:
ttl(0),
interval(0),
operations(),
delta(false),
setMask(0) {}
SensorMetadata(const SensorMetadata& other) {
......@@ -90,6 +92,7 @@ public:
ttl = other.ttl;
interval = other.interval;
operations = other.operations;
delta = other.delta;
}
SensorMetadata& operator=(const SensorMetadata& other) {
......@@ -105,6 +108,7 @@ public:
ttl = other.ttl;
interval = other.interval;
operations = other.operations;
delta = other.delta;
return *this;
}
......@@ -170,6 +174,9 @@ public:
setOperations(_parseOperations(buf, ','));
oldPos = payload.length();
break;
case 11 :
setDelta(to_bool(buf));
break;
}
}
fieldCtr++;
......@@ -211,6 +218,8 @@ public:
setTTL(stoull(val.second.data()) * 1000000);
} else if (boost::iequals(val.first, "operations")) {
setOperations(val.second.data());
} else if (boost::iequals(val.first, "delta")) {
setDelta(to_bool(val.second.data()));
}
}
}
......@@ -252,6 +261,7 @@ public:
buf += (setMask & INTERVAL_SET) ? to_string(interval / 1000000) + "," : ",";
buf += (setMask & TTL_SET) ? to_string(ttl / 1000000) + "," : ",";
buf += (setMask & OPERATIONS_SET) ? _dumpOperations(',') + "," : ",";
buf += (setMask & DELTA_SET) ? bool_to_str(delta) + "," : ",";
return buf;
}
......@@ -281,6 +291,7 @@ public:
const uint64_t* getInterval() const { return (setMask & INTERVAL_SET) ? &interval : nullptr; }
const set<string>* getOperations() const { return (setMask & OPERATIONS_SET) ? &operations : nullptr; }
const string getOperationsString() const { return (setMask & OPERATIONS_SET) ? _dumpOperations() : ""; }
const bool* getDelta() const { return (setMask & DELTA_SET) ? &delta : nullptr; }
void setIsOperation(bool o) { isOperation = o; setMask = setMask | IS_OPERATION_SET; }
void setIsVirtual(bool v) { isVirtual = v; setMask = setMask | IS_VIRTUAL_SET; }
......@@ -294,6 +305,7 @@ public:
void setInterval(uint64_t i) { interval = i; setMask = setMask | INTERVAL_SET; }
void setOperations(const string& o) { setOperations(_parseOperations(o)); }
void clearOperations() { operations.clear(); setMask = setMask & ~OPERATIONS_SET; }
void setDelta(bool d) { delta = d; setMask = setMask | DELTA_SET; }
// Merges a set of operations with the local one
void setOperations(const set<string>& o) {
......@@ -375,6 +387,9 @@ protected:
config.push_back(boost::property_tree::ptree::value_type("ttl", boost::property_tree::ptree(to_string(ttl / 1000000))));
if(setMask & OPERATIONS_SET)
config.push_back(boost::property_tree::ptree::value_type("operations", boost::property_tree::ptree(_dumpOperations())));
if(setMask & DELTA_SET)
config.push_back(boost::property_tree::ptree::value_type("delta", boost::property_tree::ptree(bool_to_str(delta))));
}
// Protected class members
......@@ -389,6 +404,7 @@ protected:
uint64_t ttl;
uint64_t interval;
set<string> operations;
bool delta;
uint64_t setMask;
};
......
......@@ -52,6 +52,7 @@ public:
_cacheInterval(900000),
_subsamplingFactor(1),
_subsamplingIndex(0),
_factor(1),
_cache(nullptr),
_delta(false),
_deltaMax(LLONG_MAX),
......@@ -79,6 +80,7 @@ public:
_cacheInterval(other._cacheInterval),
_subsamplingFactor(other._subsamplingFactor),
_subsamplingIndex(0),
_factor(other._factor),
_cache(nullptr),
_delta(other._delta),
_deltaMax(other._deltaMax),
......@@ -103,6 +105,7 @@ public:
_cacheInterval = other._cacheInterval;
_subsamplingFactor = other._subsamplingFactor;
_subsamplingIndex = 0;
_factor = other._factor;
_cache.reset(nullptr);
_delta = other._delta;
_deltaMax = other._deltaMax;
......@@ -129,8 +132,11 @@ public:
const std::string& getMqtt() const { return _mqtt; }
bool getSkipConstVal() const { return _skipConstVal; }
bool getPublish() const { return _publish; }
bool getDelta() const { return _delta; }
unsigned getCacheInterval() const { return _cacheInterval; }
int getSubsampling() const { return _subsamplingFactor; }
double getFactor() const { return _factor; }
const CacheEntry* const getCache() const { return _cache.get(); }
const reading_t& getLatestValue() const { return _latestValue; }
const bool isInit() const { return _cache && _readingQueue; }
......@@ -149,6 +155,7 @@ public:
void setMqtt(const std::string& mqtt) { _mqtt = mqtt; }
void setCacheInterval(unsigned cacheInterval) { _cacheInterval = cacheInterval; }
void setSubsampling(int factor) { _subsamplingFactor = factor; }
void setFactor(const double &factor) { _factor = factor; }
void setLastRaw(int64_t raw) { _lastRawValue.value = raw; }
void setLastURaw(uint64_t raw) { _lastRawUValue.value = raw; }
......@@ -185,9 +192,9 @@ public:
if( _delta ) {
if (!_firstReading) {
if (rawReading.value < _lastRawValue.value)
reading.value = (rawReading.value + ((int64_t)_deltaMax - _lastRawValue.value)) * factor;
reading.value = (rawReading.value + ((int64_t)_deltaMax - _lastRawValue.value)) * factor * _factor;
else
reading.value = (rawReading.value - _lastRawValue.value) * factor;
reading.value = (rawReading.value - _lastRawValue.value) * factor * _factor;
} else {
_firstReading = false;
_lastRawValue = rawReading;
......@@ -196,7 +203,7 @@ public:
_lastRawValue = rawReading;
}
else
reading.value = rawReading.value * factor;
reading.value = rawReading.value * factor * _factor;
storeReadingLocal(reading);
if (storeGlobal) {
......@@ -226,9 +233,9 @@ public:
if( _delta ) {
if (!_firstReading) {
if (rawReading.value < _lastRawUValue.value)
reading.value = (rawReading.value + (_deltaMax - _lastRawUValue.value)) * factor;
reading.value = (rawReading.value + (_deltaMax - _lastRawUValue.value)) * factor * _factor;
else
reading.value = (rawReading.value - _lastRawUValue.value) * factor;
reading.value = (rawReading.value - _lastRawUValue.value) * factor * _factor;
} else {
_firstReading = false;
_lastRawUValue = rawReading;
......@@ -237,7 +244,7 @@ public:
_lastRawUValue = rawReading;
}
else
reading.value = rawReading.value * factor;
reading.value = rawReading.value * factor * _factor;
storeReadingLocal(reading);
if (storeGlobal) {
......@@ -284,6 +291,7 @@ public:
if (getSubsampling() != 1) {
LOG_VAR(ll) << leading << " SubSampling: " << getSubsampling();
}
LOG_VAR(ll) << leading << " Factor: " << _factor;
LOG_VAR(ll) << leading << " Skip const values: " << (_skipConstVal ? "true" : "false");
LOG_VAR(ll) << leading << " Store delta only: " << (_delta ? "true" : "false");
if(_delta) {
......@@ -301,6 +309,7 @@ protected:
unsigned int _cacheInterval;
int _subsamplingFactor;
unsigned int _subsamplingIndex;
double _factor;
std::unique_ptr<CacheEntry> _cache;
bool _delta;
uint64_t _deltaMax;
......
......@@ -61,7 +61,7 @@ void GlobalConfiguration::readConfig() {
BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("global")) {
// ----- READING PLUGIN SETTINGS -----
if (boost::iequals(global.first, "mqttprefix")) {
pluginSettings.mqttPrefix = global.second.data();
pluginSettings.mqttPrefix = MQTTChecker::formatTopic(global.second.data());
} else if (boost::iequals(global.first, "autoPublish")) {
pluginSettings.autoPublish = to_bool(global.second.data());
} else if (boost::iequals(global.first, "tempdir")) {
......@@ -81,6 +81,8 @@ void GlobalConfiguration::readConfig() {
logLevelFile = stoi(global.second.data());
} else if (boost::iequals(global.first, "statisticsInterval")) {
statisticsInterval = stoi(global.second.data());
} else if (boost::iequals(global.first, "statisticsMqttPart")) {
statisticsMqttPart = MQTTChecker::formatTopic(global.second.data());
} else if (!readAdditionalValues(global)) {
LOG(warning) << " Value \"" << global.first << "\" not recognized. Omitting";
}
......
......@@ -3,13 +3,13 @@ DCDBDEPSPATH ?= $(DCDBBASEPATH)/deps
DCDBDEPLOYPATH ?= $(DCDBBASEPATH)/install
# dcdbpusher plugins to be built
PLUGINS = sysfs ipmi pdu bacnet snmp procfs tester gpfsmon msr
PLUGINS = sysfs ipmi pdu bacnet snmp procfs tester gpfsmon msr rest
# data analytics plugins to be built
OPERATORS = aggregator smoothing regressor classifier clustering cssignatures job_aggregator testeroperator filesink smucngperf persystsql coolingcontrol healthchecker