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 ed311bb0 authored by Alessio Netti's avatar Alessio Netti
Browse files

Fixed assignment of file sink paths to sensors

- The MQTT topic of a sensor is now used to identify the file name of the
sink and is appended to the path given as input
parent f4b377a5
......@@ -100,6 +100,12 @@ protected:
delete units;
return false;
}
if(*units.size() > 1) {
LOG(error) << this->_analyzerName << " " << an.getName() << ": Invalid job template unit, please check your configuration!";
delete units;
return false;
}
shared_ptr<UnitTemplate<SBase>> jobUnit = *units[0];
delete units;
an.clearUnits();
......
......@@ -329,11 +329,10 @@ public:
for(const auto& out : outputs) {
SBase uOut(*out);
uOut.setName(resolveJobString(uOut.getName(), j));
uOut.setMqtt(_navi->buildTopicForNode(j, uOut.getMqtt()));
// Duplicating the file sink adding the name of each unit to the path
string sPath = uOut.getSinkPath();
if(sPath != "")
uOut.setSinkPath(adjustSinkPath(sPath, j));
uOut.setMqtt(_navi->buildTopicForNode(j, uOut.getMqtt()));
// Duplicating the file sink adding the name of each unit to the path
if(uOut.getSinkPath()!="")
uOut.setSinkPath(MQTTChecker::topicToFile(uOut.getMqtt(), uOut.getSinkPath()));
jobUnit->addOutput(uOut);
}
return jobUnit;
......@@ -363,17 +362,6 @@ public:
protected:
// Adjust the path of a sensor sink such that it will include the unit name as well
string adjustSinkPath(const string& sPath, const string& node) {
string newSPath = sPath;
size_t idx = newSPath.find_last_of("/\\");
if(idx != string::npos)
newSPath = newSPath.substr(0, idx+1) + MQTTChecker::topicToName(node) + "_" + newSPath.substr(idx+1, string::npos);
else
newSPath = MQTTChecker::topicToName(node) + "_" + newSPath;
return newSPath;
}
// This private method will resolve all nodes in the current sensor tree that satisfy the "unit" pattern,
// and then verify whether "node" belongs to this set or not.
bool nodeBelongsToPattern(const string& node, const string& unit) {
......@@ -458,16 +446,14 @@ protected:
delete sensors;
// If we are instantiating output sensors by unit, we generate mqtt topics by using the prefix
// associated to the respective node in the sensor tree, and the sensor suffix itself
if(u != SensorNavigator::rootKey) {
if(u != SensorNavigator::rootKey)
uOut.setMqtt(_navi->buildTopicForNode(u, uOut.getMqtt()));
// Duplicating the file sink adding the name of each unit to the path
string sPath = uOut.getSinkPath();
if(sPath != "")
uOut.setSinkPath(adjustSinkPath(sPath, u));
}
// If we are not using units (only unit is root, out of the hierarchy) we build sensors like in samplers
else
uOut.setMqtt(MQTTChecker::formatTopic(mqttPrefix) + MQTTChecker::formatTopic(uOut.getMqtt()));
// Duplicating the file sink adding the name of each unit to the path
if(uOut.getSinkPath()!="")
uOut.setSinkPath(MQTTChecker::topicToFile(uOut.getMqtt(), uOut.getSinkPath()));
unitOutputs.push_back(make_shared<SBase>(uOut));
}
shared_ptr<UnitTemplate<SBase>> unPtr = make_shared<UnitTemplate<SBase>>(u, unitInputs, unitOutputs);
......
......@@ -33,6 +33,7 @@
#define MQTT_SEP '/'
#define NAME_SEP '.'
#define JOB_STR "job"
/**
* Class that manages constraint for MQTT topic formatting
......@@ -74,7 +75,28 @@ public:
* @return The numerical job ID
*/
static uint32_t topicToJob(const std::string& topic) {
return 0;
std::string jobKey(JOB_STR), jobId = topic;
jobId.erase(std::remove(jobId.begin(), jobId.end(), MQTT_SEP), jobId.end());
size_t pos = jobId.find(jobKey);
if (pos != std::string::npos)
jobId.erase(pos, jobKey.length());
return std::stoull(jobId);
}
/**
* @brief Converts an MQTT topic to a filesystem path representation
*
* @param topic The MQTT topic to be processed
* @param path The base destination path
* @return A processed file system path
*/
static std::string topicToFile(const std::string& topic, const std::string& path="") {
std::string tPath = path;
if(tPath.empty())
tPath = "./";
else if(tPath[tPath.size()-1]!='/')
tPath += '/';
return tPath + topicToName(topic);
}
/**
......
......@@ -68,6 +68,7 @@ public:
SensorBase(const SensorBase& other) :
_name(other._name),
_mqtt(other._mqtt),
_sinkPath(other._sinkPath),
_skipConstVal(other._skipConstVal),
_cacheInterval(other._cacheInterval),
_subsamplingFactor(other._subsamplingFactor),
......@@ -88,6 +89,7 @@ public:
SensorBase& operator=(const SensorBase& other) {
_name = other._name;
_mqtt = other._mqtt;
_sinkPath = other._sinkPath;
_skipConstVal = other._skipConstVal;
_cacheInterval = other._cacheInterval;
_subsamplingFactor = other._subsamplingFactor;
......
......@@ -303,7 +303,7 @@ All the different plugins share some same general principles in common regarding
3. Sensors hold only those attributes which are necessary to uniquely identify the target sensor. Common base attributes:
* __mqttsuffix__ (to make its [mqtt-topic](#mqttTopic) unique)
* __delta__ (identifies a monotonic sensor. If set to "on", differences between successive readings are collected)
* __sink__ (a path to a file to which sensor readings should be written, disabled by default)
* __sink__ (a path to a directory to which sensor readings should be written, disabled by default)
* __subSampling__ (subsampling factor S. If > 1, only one reading every S is sent over MQTT, and the others are kept locally)
5. Be aware that naming of sensor/group/entity is not fixed. A plugin developer can name them as he likes, e.g. counter/multicounter/host.
6. It is possible to define template groups or entities in the config file, but not template sensors (as a sensor should only consists of attributs which make him unique this would not be too useful). To specify a template group/entity simply prefix its definition with `template_` (see the example below). You can reference them later by using the `default` attribute. A template entity can consist of groups and these in turn can consist of sensors. When using a template, all of its attribute values are copied to the actual sensor. Copied attributes can be overwritten in the actual entity/sensor (some of them even should be overwritten, e.g. the mqttPart). However, groups/sensors associated with a template are copied to the actual entity/group and can NOT be overwritten. One can specify further groups/sensors which are then added to those copied from the template. Template entitys/groups itself or sensors within them are never used in live operation of the plugin. They are purely cosmetic for convenient configuration.
......
......@@ -814,6 +814,8 @@ protected:
for(auto& s: g->getSensors()) {
s->setMqtt(MQTTChecker::formatTopic(_mqttPrefix) + MQTTChecker::formatTopic(g->getMqttPart()) + MQTTChecker::formatTopic(s->getMqtt()));
s->setName(s->getMqtt());
if(s->getSinkPath()!="")
s->setSinkPath(MQTTChecker::topicToFile(s->getMqtt(), s->getSinkPath()));
}
return true;
}
......
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