Skip to content

Commit

Permalink
ft: ZENKO-584 add failed CRR metrics route
Browse files Browse the repository at this point in the history
  • Loading branch information
philipyoo committed Jun 30, 2018
1 parent 68d27ed commit b3b2229
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 22 deletions.
92 changes: 72 additions & 20 deletions lib/backbeat/Metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ class Metrics {

/**
* Get data points which are the keys used to query Redis
* @param {object} details - route details from lib/api/routes.js
* @param {object} details - route details from lib/backbeat/routes.js
* @param {array} data - provides already fetched data in order of
* dataPoints mentioned for each route in lib/api/routes.js. This can be
* undefined.
* dataPoints mentioned for each route in lib/backbeat/routes.js. This can
* be undefined.
* @param {function} cb - callback(error, data), where data returns
* data stored in Redis.
* @return {array} dataPoints array defined in lib/api/routes.js
* @return {array} dataPoints array defined in lib/backbeat/routes.js
*/
_getData(details, data, cb) {
if (!data) {
Expand All @@ -87,10 +87,10 @@ class Metrics {

/**
* Get replication backlog in ops count and size in bytes
* @param {object} details - route details from lib/api/routes.js
* @param {object} details - route details from lib/backbeat/routes.js
* @param {function} cb - callback(error, data)
* @param {array} data - optional field providing already fetched data
* in order of dataPoints mentioned for each route in lib/api/routes.js
* @param {array} data - optional field providing already fetched data in
* order of dataPoints mentioned for each route in lib/backbeat/routes.js
* @return {undefined}
*/
getBacklog(details, cb, data) {
Expand Down Expand Up @@ -133,10 +133,10 @@ class Metrics {

/**
* Get completed replicated stats by ops count and size in bytes
* @param {object} details - route details from lib/api/routes.js
* @param {object} details - route details from lib/backbeat/routes.js
* @param {function} cb - callback(error, data)
* @param {array} data - optional field providing already fetched data
* in order of dataPoints mentioned for each route in lib/api/routes.js
* @param {array} data - optional field providing already fetched data in
* order of dataPoints mentioned for each route in lib/backbeat/routes.js
* @return {undefined}
*/
getCompletions(details, cb, data) {
Expand Down Expand Up @@ -181,13 +181,63 @@ class Metrics {
});
}

/**
* Get failed replication stats by ops count and size in bytes
* @param {object} details - route details from lib/backbeat/routes.js
* @param {function} cb - callback(error, data)
* @param {array} data - optional field providing already fetched data in
* order of dataPoints mentioned for each route in lib/backbeat/routes.js
* @return {undefined}
*/
getFailedMetrics(details, cb, data) {
this._getData(details, data, (err, res) => {
if (err && err.type) {
this._logger.error('error getting metric: failures', {
origin: err.emthod,
method: 'Metrics.getFailedMetrics',
});
return cb(err.type.customizeDescription(err.message));
}
if (err || res.length !== details.dataPoints.length) {
this._logger.error('error getting metrics: failures', {
method: 'Metrics.getFailedMetrics',
});
return cb(errors.InternalError);
}

// Find if time since start is less than EXPIRY time
const timeSinceStart = (Date.now() - this._internalStart) / 1000;
const timeDisplay = timeSinceStart < EXPIRY ?
timeSinceStart : EXPIRY;
const numOfIntervals = Math.ceil(timeDisplay / INTERVAL);

const d = res.map(r => (
r.requests.slice(0, numOfIntervals).reduce((acc, i) =>
acc + i, 0)
));

const response = {
failures: {
description: 'Number of failed replication operations ' +
'(count) and bytes (size) in the last ' +
`${Math.floor(timeDisplay)} seconds`,
results: {
count: d[0],
size: d[1],
},
},
};
return cb(null, response);
});
}

/**
* Get current throughput in ops/sec and bytes/sec
* Throughput is the number of units processed in a given time
* @param {object} details - route details from lib/api/routes.js
* @param {object} details - route details from lib/backbeat/routes.js
* @param {function} cb - callback(error, data)
* @param {array} data - optional field providing already fetched data
* in order of dataPoints mentioned for each route in lib/api/routes.js
* @param {array} data - optional field providing already fetched data in
* order of dataPoints mentioned for each route in lib/backbeat/routes.js
* @return {undefined}
*/
getThroughput(details, cb, data) {
Expand Down Expand Up @@ -253,10 +303,10 @@ class Metrics {

/**
* Get all metrics
* @param {object} details - route details from lib/api/routes.js
* @param {object} details - route details from lib/backbeat/routes.js
* @param {function} cb = callback(error, data)
* @param {array} data - optional field providing already fetched data
* in order of dataPoints mentioned for each route in lib/api/routes.js
* @param {array} data - optional field providing already fetched data in
* order of dataPoints mentioned for each route in lib/backbeat/routes.js
* @return {undefined}
*/
getAllMetrics(details, cb, data) {
Expand All @@ -274,14 +324,16 @@ class Metrics {
});
return cb(errors.InternalError);
}
// res = [ ops, ops_done, bytes, bytes_done ]
// res = [ ops, ops_done, ops_fail, bytes, bytes_done, bytes_fail]
return async.parallel([
done => this.getBacklog({ dataPoints: new Array(4) }, done,
res),
[res[0], res[1], res[3], res[4]]),
done => this.getCompletions({ dataPoints: new Array(2) }, done,
[res[1], res[3]]),
[res[1], res[4]]),
done => this.getFailedMetrics({ dataPoints: new Array(2) },
done, [res[2], res[5]]),
done => this.getThroughput({ dataPoints: new Array(2) }, done,
[res[1], res[3]]),
[res[1], res[4]]),
], (err, results) => {
if (err) {
this._logger.error('error getting metrics: all', {
Expand Down
13 changes: 11 additions & 2 deletions lib/backbeat/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ function routes(redisKeys, allLocations) {
method: 'getCompletions',
dataPoints: [redisKeys.opsDone, redisKeys.bytesDone],
},
// Route: /_/metrics/crr/<location>/failures
{
httpMethod: 'GET',
category: 'metrics',
type: 'failures',
extensions: { crr: [...allLocations, 'all'] },
method: 'getFailedMetrics',
dataPoints: [redisKeys.opsFail, redisKeys.bytesFail],
},
// Route: /_/metrics/crr/<location>/throughput
{
httpMethod: 'GET',
Expand All @@ -53,8 +62,8 @@ function routes(redisKeys, allLocations) {
type: 'all',
extensions: { crr: [...allLocations, 'all'] },
method: 'getAllMetrics',
dataPoints: [redisKeys.ops, redisKeys.opsDone, redisKeys.bytes,
redisKeys.bytesDone],
dataPoints: [redisKeys.ops, redisKeys.opsDone, redisKeys.opsFail,
redisKeys.bytes, redisKeys.bytesDone, redisKeys.bytesFail],
},
// Route: /_/crr/failed?marker=<marker>
{
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/backbeat/Metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ describe('Metrics class', () => {
size: 0,
},
},
failures: {
description: 'Number of failed replication operations ' +
'(count) and bytes (size) in the last 900 seconds',
results: {
count: 0,
size: 0,
},
},
throughput: {
description: 'Current throughput for replication' +
' operations in ops/sec (count) and bytes/sec (size) ' +
Expand Down

0 comments on commit b3b2229

Please sign in to comment.