Closed kellymclaughlin closed 6 years ago
Here's a first cut at the changes for Metric
to make this happen:
diff --git a/lib/metric.js b/lib/metric.js
index bd11950..682dd32 100644
--- a/lib/metric.js
+++ b/lib/metric.js
@@ -23,9 +23,31 @@ var lib_provider = require('./provider');
function Metric(options) {
mod_assert.optionalObject(options, 'options');
this.labels = options ? options.labels : {};
- this.value = 0;
+
+ this.expires = false;
+ if (options && options.expires) {
+ this.expires = options.expires;
+ }
+ this.default_value = 0;
+ if (options && options.default_value) {
+ this.expires = options.expires;
+ }
+ /*
+ * The expiry_period is time period after which the metric is reset to
+ * its default value if the metric timestamp is not updated due to a call
+ * to the add or set methods.
+ */
+ this.expiry_period = 300;
+ if (options && options.expiry_period) {
+ this.expiry_period = options.expiry_period;
+ }
+
+ this.value = this.default_value;
+
// ISO 8601 time when this metric was last updated.
this.timestamp = null;
+
+ this.expiry_timer = null;
}
/*
@@ -37,30 +59,55 @@ Metric.prototype.add = function add(num) {
mod_assert.number(num, 'num');
var self = this;
+
+ if (this.expiry_timer) {
+ clearTimeout(this.expiry_timer);
+ this.expiry_timer = null;
+ }
+
lib_provider['metric-add'].fire(function () {
return ([num, self.labels]);
});
this.value += num;
this.timestamp = new Date().toISOString();
+
+ if (this.expires) {
+ this.expiry_timer = setTimeout(this.resetValue, this.expiry_period);
+ }
};
Metric.prototype.set = function set(num) {
mod_assert.number(num, 'num');
var self = this;
+
+ if (this.expiry_timer) {
+ clearTimeout(this.expiry_timer);
+ this.expiry_timer = null;
+ }
+
lib_provider['metric-set'].fire(function () {
return ([num, self.labels]);
});
this.value = num;
this.timestamp = new Date().toISOString();
+
+ if (this.expires) {
+ this.expiry_timer = setTimeout(this.resetValue, this.expiry_period);
+ }
};
Metric.prototype.getValue = function getValue() {
return (this.value);
};
+Metric.prototype.resetValue = function resetValue() {
+ this.value = this.default_value;
+ this.timestamp = new Date().toISOString();
+};
+
module.exports = {
Metric: Metric
};
From here it would just be exposing the API in the collector on down to set these options which should be a pretty straightforward process.
CR to address this issue is here.
Add the ability for metrics contained in a
MetricVector
object to be expired, meaning they are removed from themetrics
objects of theMetricVector
, or to be reset to a user-specified default value at the end of the expiry period. This could be exposed as additional options accepted when a new metric collector is registered.The specific use case I have in mind for this is when a gauge is used to track the progress of a finite event or sequence of steps, but the event has no discrete final state that can be observed to indicate completion. Currently a gauge will continue providing a reading of the last known value indefinitely once the metric data is no longer extant. Providing an expiry option would allow a way to detect the completion of the event or sequence and take the action of either removing the metric entirely or setting the value to a default. For example, in the case of a gauge monitoring a sequence of steps this might be setting the value to 0 to show completion.