Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing 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:

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

Delta calculation in SensorBase

- Sensors now support a "delta" field in config files. If set to "on",
differences between successive readings instead of the raw values will
be stored
- Default is "off"
- This option should only be applied to monotonic sensors
- Can be applied to perfevents as well
parent 755c388c
......@@ -163,6 +163,7 @@ All the different plugins share some same general principles in common regarding
* __default__ (One can define the name of a template group (see below) whose values and sensors should be used as default)
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)
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.
......@@ -343,6 +343,9 @@ protected:
if (boost::iequals(val.first, "mqttsuffix")) {
else if (boost::iequals(val.first, "delta")) {
sBase.setDelta( == "on" );
sensorBase(sBase, config);
return true;
......@@ -10,6 +10,7 @@
#include <memory>
#include <string>
#include <limits.h>
#include <boost/lockfree/spsc_queue.hpp>
typedef struct {
......@@ -26,10 +27,13 @@ public:
_readingQueue(nullptr) {
_latestValue.timestamp = 0;
_latestValue.value = 0;
_lastRawValue.timestamp = 0;
_lastRawValue.value = 0;
SensorBase(const SensorBase& other) :
......@@ -37,7 +41,9 @@ public:
_readingQueue(nullptr) {}
virtual ~SensorBase() {}
......@@ -47,18 +53,23 @@ public:
_mqtt = other._mqtt;
_cacheIndex = 0;
_delta = other._delta;
_latestValue.timestamp = other._latestValue.timestamp;
_latestValue.value = other._latestValue.value;
_lastRawValue.timestamp = other._lastRawValue.timestamp;
_lastRawValue.value = other._lastRawValue.value;
return *this;
const bool isDelta() const { return _delta;}
const std::string& getName() const { return _name; }
const std::string& getMqtt() const { return _mqtt; }
const reading_t * const getCache() const { return _cache.get(); }
const reading_t getLatestValue() const { return _latestValue; } /*TODO return reference*/
void setDelta(const bool delta) { _delta = delta; }
void setName(const std::string& name, int cpuID=-1) { _name = formatName(name, cpuID); }
void setMqtt(const std::string& mqtt) { _mqtt = mqtt; }
......@@ -78,12 +89,21 @@ public:
virtual void storeReading(reading_t reading, unsigned int cacheSize) {
_cache[_cacheIndex] = reading;
_cacheIndex = (_cacheIndex + 1) % cacheSize;
_latestValue.value = reading.value;
virtual void storeReading(reading_t reading, unsigned int cacheSize, unsigned long long maxValue=ULLONG_MAX) {
_latestValue.timestamp = reading.timestamp;
if( _delta ) {
if (reading.value < _lastRawValue.value)
_latestValue.value = reading.value + (maxValue - _lastRawValue.value);
_latestValue.value = reading.value - _lastRawValue.value;
_lastRawValue.value = reading.value;
_latestValue.value = reading.value;
_cache[_cacheIndex] = _latestValue;
_cacheIndex = (_cacheIndex + 1) % cacheSize;
static std::string formatName(const std::string& name, int cpuID=-1) {return cpuID<0 ? name : "cpu" + std::to_string(cpuID) + "." + name;}
......@@ -94,7 +114,9 @@ protected:
std::string _mqtt;
unsigned int _cacheIndex;
std::unique_ptr<reading_t[]> _cache;
bool _delta;
reading_t _latestValue;
reading_t _lastRawValue;
std::unique_ptr<boost::lockfree::spsc_queue<reading_t>> _readingQueue;
......@@ -199,7 +199,8 @@ bool MeminfoParser::_readMetrics() {
if ( this->_readings == NULL )
this->_readings = new std::vector<reading_t>(this->_numMetrics);
fseek(this->_metricsFile, 0, SEEK_SET);
unsigned int ctr = 0, lineCtr=0;
int lineCtr=0;
unsigned int ctr = 0;
char *lineToken, *savePtr;
this->_memFreeValue.value = 0;
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