Commit 30c355d3 authored by Alessio Netti's avatar Alessio Netti
Browse files

DA: integration of analytics in collectagent

- QueryEngine integration done (but not functional yet, debugging required)
- Changed behavior on exceptional conditions: if SensorNavigator or
AnalyticsManager initialization fails, termination follows
- Now the QueryEngine can also access output sensors of other Analyzers
- Minor bugfixes
parent acc15ee7
...@@ -65,7 +65,7 @@ void AggregatorAnalyzer::computeAvg(int unitID) { ...@@ -65,7 +65,7 @@ void AggregatorAnalyzer::computeAvg(int unitID) {
for(const auto& in : _units[unitID]->getInputs()) { for(const auto& in : _units[unitID]->getInputs()) {
// Getting the most recent values as specified in _window // Getting the most recent values as specified in _window
_buffer = _queryEngine.querySensor(in->getName(), _window, 0, _buffer); _buffer = _queryEngine.querySensor(in->getName(), _window, 0, _buffer);
if(_buffer->empty()) { if(!_buffer || _buffer->empty()) {
LOG(error) << "Analyzer " << _name << " cannot read from sensor " << in->getName() << "!"; LOG(error) << "Analyzer " << _name << " cannot read from sensor " << in->getName() << "!";
return; return;
} }
...@@ -90,7 +90,7 @@ void AggregatorAnalyzer::computeMax(int unitID) { ...@@ -90,7 +90,7 @@ void AggregatorAnalyzer::computeMax(int unitID) {
for(const auto& in : _units[unitID]->getInputs()) { for(const auto& in : _units[unitID]->getInputs()) {
// Getting the most recent values as specified in _window // Getting the most recent values as specified in _window
_buffer = _queryEngine.querySensor(in->getName(), _window, 0, _buffer); _buffer = _queryEngine.querySensor(in->getName(), _window, 0, _buffer);
if(_buffer->empty()) { if(!_buffer || _buffer->empty()) {
LOG(error) << "Analyzer " << _name << " cannot read from sensor " << in->getName() << "!"; LOG(error) << "Analyzer " << _name << " cannot read from sensor " << in->getName() << "!";
return; return;
} }
...@@ -113,7 +113,7 @@ void AggregatorAnalyzer::computeMin(int unitID) { ...@@ -113,7 +113,7 @@ void AggregatorAnalyzer::computeMin(int unitID) {
for(const auto& in : _units[unitID]->getInputs()) { for(const auto& in : _units[unitID]->getInputs()) {
// Getting the most recent values as specified in _window // Getting the most recent values as specified in _window
_buffer = _queryEngine.querySensor(in->getName(), _window, 0, _buffer); _buffer = _queryEngine.querySensor(in->getName(), _window, 0, _buffer);
if(_buffer->empty()) { if(!_buffer || _buffer->empty()) {
LOG(error) << "Analyzer " << _name << " cannot read from sensor " << in->getName() << "!"; LOG(error) << "Analyzer " << _name << " cannot read from sensor " << in->getName() << "!";
return; return;
} }
......
...@@ -25,8 +25,7 @@ bool AnalyticsController::initialize(globalCA_t& settings, const string& configP ...@@ -25,8 +25,7 @@ bool AnalyticsController::initialize(globalCA_t& settings, const string& configP
_settings = settings; _settings = settings;
_configPath = configPath; _configPath = configPath;
_navigator = make_shared<SensorNavigator>(); _navigator = make_shared<SensorNavigator>();
//TODO: make exceptional conditions consistent
// A sensor navigator is only built if data analytics plugins are expected to be instantiated // A sensor navigator is only built if data analytics plugins are expected to be instantiated
QueryEngine &_queryEngine = QueryEngine::getInstance(); QueryEngine &_queryEngine = QueryEngine::getInstance();
if(_manager->probe(_configPath, "collectagent.conf")) { if(_manager->probe(_configPath, "collectagent.conf")) {
...@@ -46,8 +45,8 @@ bool AnalyticsController::initialize(globalCA_t& settings, const string& configP ...@@ -46,8 +45,8 @@ bool AnalyticsController::initialize(globalCA_t& settings, const string& configP
_navigator->buildTree(_settings.hierarchy, &names, &topics); _navigator->buildTree(_settings.hierarchy, &names, &topics);
} catch (const std::invalid_argument &e) { } catch (const std::invalid_argument &e) {
LOG(error) << e.what(); LOG(error) << e.what();
LOG(error) << "Failed to build sensor hierarchy tree, data analytics manager will not be initialized!"; LOG(error) << "Failed to build sensor hierarchy tree!";
return true; return false;
} }
LOG(info) << "Built a sensor hierarchy tree of size " << _navigator->getTreeSize() << " and depth " LOG(info) << "Built a sensor hierarchy tree of size " << _navigator->getTreeSize() << " and depth "
<< _navigator->getTreeDepth() << "."; << _navigator->getTreeDepth() << ".";
...@@ -62,7 +61,7 @@ bool AnalyticsController::initialize(globalCA_t& settings, const string& configP ...@@ -62,7 +61,7 @@ bool AnalyticsController::initialize(globalCA_t& settings, const string& configP
//TODO: find a better solution to disable the SensorBase default cache //TODO: find a better solution to disable the SensorBase default cache
_settings.pluginSettings.cacheInterval = 0; _settings.pluginSettings.cacheInterval = 0;
if(!_manager->load(_configPath, "collectagent.conf", _settings.pluginSettings)) { if(!_manager->load(_configPath, "collectagent.conf", _settings.pluginSettings)) {
LOG(fatal) << "Failed to load data analytics manager! Collect agent is proceeding anyway."; LOG(fatal) << "Failed to load data analytics manager!";
return false; return false;
} }
...@@ -112,18 +111,19 @@ void AnalyticsController::run() { ...@@ -112,18 +111,19 @@ void AnalyticsController::run() {
for (auto &p : _analyticsPlugins) { for (auto &p : _analyticsPlugins) {
if (_doHalt) break; if (_doHalt) break;
for (const auto &a : p.configurator->getAnalyzers()) for (const auto &a : p.configurator->getAnalyzers())
for (const auto &u : a->getUnits()) if(a->getStreaming())
for (const auto &s : u->getBaseOutputs()) for (const auto &u : a->getUnits())
if (s->getSizeOfReadingQueue() >= a->getMinValues() && sid.mqttTopicConvert(s->getMqtt())) { for (const auto &s : u->getBaseOutputs())
readings.clear(); if (s->getSizeOfReadingQueue() >= a->getMinValues() && sid.mqttTopicConvert(s->getMqtt())) {
sensorQueue = s->getReadingQueue(); readings.clear();
while(sensorQueue->pop(readingBuf)) { sensorQueue = s->getReadingQueue();
readings.push_back(DCDB::SensorDataStoreReading(sid, readingBuf.timestamp, readingBuf.value)); while(sensorQueue->pop(readingBuf)) {
_sensorCache->storeSensor(sid, readingBuf.timestamp, readingBuf.value); readings.push_back(DCDB::SensorDataStoreReading(sid, readingBuf.timestamp, readingBuf.value));
_sensorCache->storeSensor(sid, readingBuf.timestamp, readingBuf.value);
}
_dcdbStore->insertBatch(readings);
_readingCtr+=readings.size();
} }
_dcdbStore->insertBatch(readings);
_readingCtr+=readings.size();
}
} }
sleep(1); sleep(1);
} }
...@@ -139,29 +139,30 @@ bool AnalyticsController::publishSensors() { ...@@ -139,29 +139,30 @@ bool AnalyticsController::publishSensors() {
uint64_t publishCtr = 0; uint64_t publishCtr = 0;
for (auto &p : _analyticsPlugins) for (auto &p : _analyticsPlugins)
for (const auto &a : p.configurator->getAnalyzers()) for (const auto &a : p.configurator->getAnalyzers())
for (const auto &u : a->getUnits()) if(a->getStreaming())
for (const auto &s : u->getBaseOutputs()) { for (const auto &u : a->getUnits())
err = _dcdbCfg->publishSensor(s->getName().c_str(), s->getMqtt().c_str()); for (const auto &s : u->getBaseOutputs()) {
switch (err) { err = _dcdbCfg->publishSensor(s->getName().c_str(), s->getMqtt().c_str());
case DCDB::SC_OK: switch (err) {
publishCtr++; case DCDB::SC_OK:
break; publishCtr++;
case DCDB::SC_INVALIDPATTERN: break;
LOG(error) << "Invalid sensor topic : " << s->getMqtt(); case DCDB::SC_INVALIDPATTERN:
failedPublish = true; LOG(error) << "Invalid sensor topic : " << s->getMqtt();
break; failedPublish = true;
case DCDB::SC_INVALIDPUBLICNAME: break;
LOG(error) << "Invalid sensor public name: " << s->getName(); case DCDB::SC_INVALIDPUBLICNAME:
failedPublish = true; LOG(error) << "Invalid sensor public name: " << s->getName();
break; failedPublish = true;
case DCDB::SC_INVALIDSESSION: break;
LOG(error) << "Cannot reach sensor data store."; case DCDB::SC_INVALIDSESSION:
failedPublish = true; LOG(error) << "Cannot reach sensor data store.";
break; failedPublish = true;
default: break;
break; default:
break;
}
} }
}
if(failedPublish) if(failedPublish)
LOG(error) << "Issues during sensor name auto-publish! Only " << publishCtr << " sensors were published."; LOG(error) << "Issues during sensor name auto-publish! Only " << publishCtr << " sensors were published.";
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <dcdb/sensordatastore.h> #include <dcdb/sensordatastore.h>
#include <dcdb/sensorconfig.h> #include <dcdb/sensorconfig.h>
#include <dcdb/version.h> #include <dcdb/version.h>
#include <dcdb/sensor.h>
#include "version.h" #include "version.h"
#include "configuration.h" #include "configuration.h"
...@@ -66,10 +67,58 @@ DCDB::Connection* dcdbConn; ...@@ -66,10 +67,58 @@ DCDB::Connection* dcdbConn;
DCDB::SensorDataStore *mySensorDataStore; DCDB::SensorDataStore *mySensorDataStore;
DCDB::SensorConfig *mySensorConfig; DCDB::SensorConfig *mySensorConfig;
DCDB::SCError err; DCDB::SCError err;
QueryEngine& queryEngine = QueryEngine::getInstance();
logger_t lg; logger_t lg;
std::vector<reading_t>* sensorQueryCallback(const string& name, const uint64_t startTs, const uint64_t endTs, std::vector<reading_t>* buffer, const bool rel) { std::vector<reading_t>* sensorQueryCallback(const string& name, const uint64_t startTs, const uint64_t endTs, std::vector<reading_t>* buffer, const bool rel) {
return buffer; std::string topic;
try {
topic = queryEngine.getNavigator()->getNodeTopic(name);
} catch(const std::domain_error& e) {
return NULL;
}
std::vector <reading_t> *output = NULL;
DCDB::SensorId sid;
sid.mqttTopicConvert(topic);
if(mySensorCache.getSensorMap().count(sid) > 0) {
CacheEntry &entry = mySensorCache.getSensorMap()[sid];
output = entry.getView(startTs, endTs, buffer, rel, true);
if (output->size() > 0)
return output;
}
// If we are here then the sensor was not found in the cache - we need to fetch data from Cassandra
try {
DCDB::PublicSensor publicSensor;
publicSensor.name = name;
publicSensor.pattern = topic;
std::list <DCDB::SensorDataStoreReading> results;
DCDB::Sensor sensor(dcdbConn, publicSensor);
uint64_t now = getTimestamp();
//Converting relative timestamps to absolute
uint64_t startTsInt = rel ? now - startTs : startTs;
uint64_t endTsInt = rel ? now - endTs : endTs;
DCDB::TimeStamp start(startTsInt), end(endTsInt);
sensor.query(results, start, end, DCDB::AGGREGATE_NONE);
if(output)
output->clear();
else if(buffer) {
buffer->clear();
output = buffer;
} else
output = new std::vector<reading_t>();
reading_t reading;
//TODO: fix when result contains only partial time range of the query
for (const auto &r : results) {
reading.value = r.value;
reading.timestamp = r.timeStamp.getRaw();
output->push_back(reading);
}
}
catch(const std::exception& e) {
if(!buffer && output) delete output;
return NULL;
}
return output;
} }
/* Normal termination (SIGINT, CTRL+C) */ /* Normal termination (SIGINT, CTRL+C) */
...@@ -423,7 +472,7 @@ int main(int argc, char* const argv[]) { ...@@ -423,7 +472,7 @@ int main(int argc, char* const argv[]) {
// Setting the size of the sensor cache // Setting the size of the sensor cache
// Conversion from milliseconds to nanoseconds // Conversion from milliseconds to nanoseconds
mySensorCache.setMaxHistory(settings.pluginSettings.cacheInterval * 1000000); mySensorCache.setMaxHistory(uint64_t(settings.pluginSettings.cacheInterval) * 1000000);
//Allocate and initialize connection to Cassandra. //Allocate and initialize connection to Cassandra.
dcdbConn = new DCDB::Connection(cassandraHost, atoi(cassandraPort.c_str()), settings.cassandraSettings.username, settings.cassandraSettings.password); dcdbConn = new DCDB::Connection(cassandraHost, atoi(cassandraPort.c_str()), settings.cassandraSettings.username, settings.cassandraSettings.password);
...@@ -461,7 +510,7 @@ int main(int argc, char* const argv[]) { ...@@ -461,7 +510,7 @@ int main(int argc, char* const argv[]) {
analyticsController->setCache(&mySensorCache); analyticsController->setCache(&mySensorCache);
if(!analyticsController->initialize(settings, argv[argc - 1])) if(!analyticsController->initialize(settings, argv[argc - 1]))
return EXIT_FAILURE; return EXIT_FAILURE;
QueryEngine::getInstance().setQueryCallback(sensorQueryCallback); queryEngine.setQueryCallback(sensorQueryCallback);
LOG_LEVEL vLogLevel = validateConfig ? LOG_LEVEL::info : LOG_LEVEL::debug; LOG_LEVEL vLogLevel = validateConfig ? LOG_LEVEL::info : LOG_LEVEL::debug;
LOG_VAR(vLogLevel) << "----- Configuration -----"; LOG_VAR(vLogLevel) << "----- Configuration -----";
......
...@@ -71,7 +71,7 @@ bool Configuration::readGlobal() { ...@@ -71,7 +71,7 @@ bool Configuration::readGlobal() {
} else if (boost::iequals(global.first, "messageSlots")) { } else if (boost::iequals(global.first, "messageSlots")) {
_global.messageSlots = stoul(global.second.data()); _global.messageSlots = stoul(global.second.data());
} else if (boost::iequals(global.first, "cacheInterval")) { } else if (boost::iequals(global.first, "cacheInterval")) {
_global.pluginSettings.cacheInterval = stoul(global.second.data()); _global.pluginSettings.cacheInterval = stoul(global.second.data()) * 1000;
} else if (boost::iequals(global.first, "verbosity")) { } else if (boost::iequals(global.first, "verbosity")) {
_global.logLevelFile = translateLogLevel(stoi(global.second.data())); _global.logLevelFile = translateLogLevel(stoi(global.second.data()));
} else if (boost::iequals(global.first, "threads")) { } else if (boost::iequals(global.first, "threads")) {
......
...@@ -15,7 +15,7 @@ SensorCache::~SensorCache() { ...@@ -15,7 +15,7 @@ SensorCache::~SensorCache() {
sensorCache.clear(); sensorCache.clear();
} }
const sensorCache_t& SensorCache::getSensorMap() { sensorCache_t& SensorCache::getSensorMap() {
return sensorCache; return sensorCache;
} }
......
...@@ -23,9 +23,9 @@ public: ...@@ -23,9 +23,9 @@ public:
virtual ~SensorCache(); virtual ~SensorCache();
/** /**
* @brief Returns a constant reference to the internal sensor cache map. * @brief Returns a reference to the internal sensor cache map.
**/ **/
const sensorCache_t& getSensorMap(); sensorCache_t& getSensorMap();
/** /**
* @brief Store a sensor reading in the SensorCache. * @brief Store a sensor reading in the SensorCache.
......
...@@ -396,22 +396,21 @@ void HttpsServer::requestHandler::operator()(server::request const &request, ser ...@@ -396,22 +396,21 @@ void HttpsServer::requestHandler::operator()(server::request const &request, ser
connection->set_status(server::connection::not_supported); connection->set_status(server::connection::not_supported);
goto error; goto error;
} }
}
//Updating the SensorNavigator on plugin reloads //Updating the SensorNavigator on plugin reloads
if(action == "reload") { if(pathStrs.back() == "reload") {
QueryEngine &qEngine = QueryEngine::getInstance(); QueryEngine &qEngine = QueryEngine::getInstance();
std::shared_ptr <SensorNavigator> navigator = std::make_shared<SensorNavigator>(); std::shared_ptr <SensorNavigator> navigator = std::make_shared<SensorNavigator>();
vector <std::string> names, topics; vector <std::string> names, topics;
for (const auto &p : _httpsServer._plugins) for (const auto &p : _httpsServer._plugins)
for (const auto &g : p.configurator->getSensorGroups()) for (const auto &g : p.configurator->getSensorGroups())
for (const auto &s : g->getSensors()) { for (const auto &s : g->getSensors()) {
names.push_back(s->getName()); names.push_back(s->getName());
topics.push_back(s->getMqtt()); topics.push_back(s->getMqtt());
} }
navigator->buildTree(qEngine.getSensorHierarchy(), &names, &topics); navigator->buildTree(qEngine.getSensorHierarchy(), &names, &topics);
qEngine.setNavigator(navigator); qEngine.setNavigator(navigator);
qEngine.triggerUpdate(); qEngine.triggerUpdate();
}
} }
} }
......
...@@ -133,19 +133,21 @@ void MQTTPusher::push() { ...@@ -133,19 +133,21 @@ void MQTTPusher::push() {
break; break;
} }
for (const auto &a : p.configurator->getAnalyzers()) { for (const auto &a : p.configurator->getAnalyzers()) {
for (const auto &u : a->getUnits()) { if(a->getStreaming()) {
for (const auto &s : u->getBaseOutputs()) { for (const auto &u : a->getUnits()) {
if (s->getSizeOfReadingQueue() >= a->getMinValues()) { for (const auto &s : u->getBaseOutputs()) {
if (_msgCap == DISABLED || totalCount < (unsigned)_maxNumberOfMessages) { if (s->getSizeOfReadingQueue() >= a->getMinValues()) {
if (sendReadings(*s, reads, totalCount) > 0) { if (_msgCap == DISABLED || totalCount < (unsigned) _maxNumberOfMessages) {
break; if (sendReadings(*s, reads, totalCount) > 0) {
} break;
} else { }
break; } else {
} break;
} }
} }
} }
}
}
} }
} }
} }
...@@ -221,20 +223,21 @@ bool MQTTPusher::sendMappings() { ...@@ -221,20 +223,21 @@ bool MQTTPusher::sendMappings() {
// Performing auto-publish for analytics output sensors // Performing auto-publish for analytics output sensors
for(auto& p: _analyticsPlugins) for(auto& p: _analyticsPlugins)
for(auto& a: p.configurator->getAnalyzers()) for(auto& a: p.configurator->getAnalyzers())
for(auto& u: a->getUnits()) if(a->getStreaming())
for(auto& s: u->getBaseOutputs()) { for(auto& u: a->getUnits())
topic = std::string(DCDB_MAP) + s->getMqtt(); for(auto& s: u->getBaseOutputs()) {
name = s->getName(); topic = std::string(DCDB_MAP) + s->getMqtt();
name = s->getName();
// Try to send mapping to the broker
if (mosquitto_publish(_mosq, NULL, topic.c_str(), name.length(), name.c_str(), _qosLevel, false) != MOSQ_ERR_SUCCESS) { // Try to send mapping to the broker
LOGM(error) << "Broker not reachable! Only " << publishCtr << " sensors were published."; if (mosquitto_publish(_mosq, NULL, topic.c_str(), name.length(), name.c_str(), _qosLevel, false) != MOSQ_ERR_SUCCESS) {
_connected = false; LOGM(error) << "Broker not reachable! Only " << publishCtr << " sensors were published.";
return true; _connected = false;
return true;
}
else
publishCtr++;
} }
else
publishCtr++;
}
LOGM(info) << "Sensor name auto-publish performed for all " << publishCtr << " sensors!"; LOGM(info) << "Sensor name auto-publish performed for all " << publishCtr << " sensors!";
return true; return true;
} }
......
...@@ -57,16 +57,23 @@ QueryEngine& _queryEngine = QueryEngine::getInstance(); ...@@ -57,16 +57,23 @@ QueryEngine& _queryEngine = QueryEngine::getInstance();
boost::shared_ptr<boost::asio::io_service::work> keepAliveWork; boost::shared_ptr<boost::asio::io_service::work> keepAliveWork;
//TODO: Include data analytics output sensors in the sensormap
std::vector<reading_t>* sensorQueryCallback(const string& name, const uint64_t startTs, const uint64_t endTs, std::vector<reading_t>* buffer, const bool rel) { std::vector<reading_t>* sensorQueryCallback(const string& name, const uint64_t startTs, const uint64_t endTs, std::vector<reading_t>* buffer, const bool rel) {
//Initializing the sensor map if necessary. Thread safe! //Initializing the sensor map if necessary. Thread safe!
if(_queryEngine.updated.load()) { if(_queryEngine.updated.load()) {
if(!_queryEngine.updating.exchange(true)) { if(!_queryEngine.updating.exchange(true)) {
_sensorMap.clear(); _sensorMap.clear();
// Adding ordinary sensors to the map
for (auto &p : _configuration->getPlugins()) for (auto &p : _configuration->getPlugins())
for (auto &g : p.configurator->getSensorGroups()) for (auto &g : p.configurator->getSensorGroups())
for (auto &s : g->getSensors()) for (auto &s : g->getSensors())
_sensorMap.insert(std::make_pair(s->getName(), s)); _sensorMap.insert(std::make_pair(s->getName(), s));
// Adding data analytics sensors to the map
for(auto& p : _analyticsManager->getPlugins())
for(const auto& a : p.configurator->getAnalyzers())
if (a->getStreaming())
for (const auto &u : a->getUnits())
for (const auto &o: u->getBaseOutputs())
_sensorMap.insert(std::make_pair(o->getName(), o));
_queryEngine.updated.store(false); _queryEngine.updated.store(false);
_queryEngine.updating.store(false); _queryEngine.updating.store(false);
} else { } else {
...@@ -77,11 +84,11 @@ std::vector<reading_t>* sensorQueryCallback(const string& name, const uint64_t s ...@@ -77,11 +84,11 @@ std::vector<reading_t>* sensorQueryCallback(const string& name, const uint64_t s
if(_sensorMap.count(name) > 0) { if(_sensorMap.count(name) > 0) {
SBasePtr sensor = _sensorMap[name]; SBasePtr sensor = _sensorMap[name];
if(!sensor->isInit()) if(!sensor->isInit())
return buffer; return NULL;
else else
return sensor->getCache()->getView(startTs, endTs, buffer, rel, true); return sensor->getCache()->getView(startTs, endTs, buffer, rel, true);
} }
return buffer; return NULL;
} }
void sigHandler(int sig) { void sigHandler(int sig) {
...@@ -255,7 +262,6 @@ int main(int argc, char** argv) { ...@@ -255,7 +262,6 @@ int main(int argc, char** argv) {
_analyticsManager = new AnalyticsManager(); _analyticsManager = new AnalyticsManager();
// Preparing the SensorNavigator // Preparing the SensorNavigator
bool failedTree = false;
if(_analyticsManager->probe(argv[argc-1], "dcdbpusher.conf")) { if(_analyticsManager->probe(argv[argc-1], "dcdbpusher.conf")) {
std::shared_ptr <SensorNavigator> navigator = std::make_shared<SensorNavigator>(); std::shared_ptr <SensorNavigator> navigator = std::make_shared<SensorNavigator>();
vector <std::string> names, topics; vector <std::string> names, topics;
...@@ -272,18 +278,16 @@ int main(int argc, char** argv) { ...@@ -272,18 +278,16 @@ int main(int argc, char** argv) {
_queryEngine.triggerUpdate(); _queryEngine.triggerUpdate();
} catch (const std::invalid_argument &e) { } catch (const std::invalid_argument &e) {
LOG(error) << e.what(); LOG(error) << e.what();
LOG(error) << "Failed to build sensor hierarchy tree, data analytics manager will not be initialized!"; LOG(error) << "Failed to build sensor hierarchy tree!";
failedTree = true;
}
}
if(!failedTree) {
_queryEngine.setQueryCallback(sensorQueryCallback);
if(!_analyticsManager->load(argv[argc-1], "dcdbpusher.conf", pluginSettings)) {
LOG(fatal) << "Failed to load data analytics manager!";
return 1; return 1;
} }
} }
_queryEngine.setQueryCallback(sensorQueryCallback);
if(!_analyticsManager->load(argv[argc-1], "dcdbpusher.conf", pluginSettings)) {
LOG(fatal) << "Failed to load data analytics manager!";
return 1;
}
//print configuration to give some feedback //print configuration to give some feedback
//config of plugins is only printed if the config shall be validated or to debug level otherwise //config of plugins is only printed if the config shall be validated or to debug level otherwise
...@@ -364,17 +368,15 @@ int main(int argc, char** argv) { ...@@ -364,17 +368,15 @@ int main(int argc, char** argv) {
g->start(); g->start();
} }
} }
if(!_queryEngine.updated.is_lock_free())
LOG(warning) << "This machine does not support lock-free atomics. Performance may be degraded.";
if(!failedTree) { LOG(info) << "Init analyzers...";
if(!_queryEngine.updated.is_lock_free()) _analyticsManager->init(io);
LOG(warning) << "This machine does not support lock-free atomics. Performance may be degraded.";
LOG(info) << "Init analyzers...";
_analyticsManager->init(io);
LOG(info) << "Starting analyzers..."; LOG(info) << "Starting analyzers...";
_analyticsManager->start(); _analyticsManager->start();
}
LOG(info) << "Sensors started!"; LOG(info) << "Sensors started!";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment