Skip to content

Commit

Permalink
feat(mojaloop/#3432): add metrics for quote handlers and models
Browse files Browse the repository at this point in the history
  • Loading branch information
kleyow committed Sep 29, 2023
1 parent 3f97d97 commit a5864fa
Show file tree
Hide file tree
Showing 18 changed files with 942 additions and 587 deletions.
17 changes: 16 additions & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,20 @@
"JWS_SIGNING_KEY_PATH": "secrets/jwsSigningKey.key"
}
},
"API_DOCUMENTATION_ENDPOINTS": true
"API_DOCUMENTATION_ENDPOINTS": true,
"INSTRUMENTATION": {
"METRICS": {
"DISABLED": false,
"labels": {
"fspId": "*"
},
"config": {
"timeout": 5000,
"prefix": "moja_qs_",
"defaultLabels": {
"serviceName": "quoting-service"
}
}
}
}
}
8 changes: 2 additions & 6 deletions docker-compose.base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ services:
volumes:
# override the default values with our own - this is because the KAFKA_HOST env variable is ignored for some reason
- ./docker/ml-api-adapter/default.json:/opt/app/config/default.json

# TODO: we should be able to remove this - I think the image command is broken
command:
- "node"
Expand Down Expand Up @@ -64,12 +64,10 @@ services:
- /opt/wait-for-mockserver.sh
environment:
- MOCK_HOST=mockserver

kafka:
image: docker.io/bitnami/kafka:3.5
container_name: cl_kafka
networks:
- cl-mojaloop-net
ports:
- "9092:9092"
environment:
Expand Down Expand Up @@ -97,8 +95,6 @@ services:

init-kafka:
container_name: cl_init_kafka
networks:
- cl-mojaloop-net
image: docker.io/bitnami/kafka:3.5
depends_on:
- kafka
Expand Down
1,216 changes: 647 additions & 569 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,19 @@
"@mojaloop/central-services-error-handling": "12.0.7",
"@mojaloop/central-services-health": "14.0.2",
"@mojaloop/central-services-logger": "11.2.2",
"@mojaloop/central-services-metrics": "12.0.8",
"@mojaloop/central-services-shared": "18.1.0",
"@mojaloop/event-sdk": "12.0.2",
"@mojaloop/central-services-metrics": "^12.0.8",
"@mojaloop/central-services-shared": "18.1.2",
"@mojaloop/event-sdk": "13.0.0",
"@mojaloop/ml-number": "11.2.3",
"@mojaloop/sdk-standard-components": "17.1.3",
"ajv": "8.12.0",
"ajv-keywords": "5.1.0",
"axios": "1.5.0",
"axios": "1.5.1",
"blipp": "4.0.2",
"event-stream": "4.0.1",
"good-console": "8.0.0",
"good-squeeze": "5.1.0",
"joi": "17.10.1",
"joi": "17.10.2",
"json-rules-engine": "5.0.2",
"knex": "2.5.1",
"memory-cache": "0.2.0",
Expand All @@ -111,14 +111,14 @@
"audit-ci": "^6.6.1",
"eslint": "8.16.0",
"eslint-config-standard": "17.1.0",
"jest": "29.6.4",
"jest": "29.7.0",
"jest-junit": "16.0.0",
"npm-check-updates": "16.13.2",
"npm-check-updates": "16.14.4",
"nyc": "15.1.0",
"pre-commit": "1.2.2",
"proxyquire": "2.1.3",
"replace": "^1.2.2",
"sinon": "15.2.0",
"sinon": "16.0.0",
"standard": "17.1.0",
"standard-version": "9.5.0",
"swagmock": "1.0.0"
Expand Down
8 changes: 8 additions & 0 deletions src/handlers/bulkQuotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const ErrorHandler = require('@mojaloop/central-services-error-handling')
const EventSdk = require('@mojaloop/event-sdk')
const LibUtil = require('../lib/util')
const BulkQuotesModel = require('../model/bulkQuotes')
const Metrics = require('@mojaloop/central-services-metrics')

/**
* Operations on /bulkQuotes
Expand All @@ -52,6 +53,11 @@ module.exports = {
* responses: 202, 400, 401, 403, 404, 405, 406, 501, 503
*/
post: async function BulkQuotes (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'bulkQuotes_post',
'Process HTTP POST bulkQuotes request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a POST /bulkQuotes request: ${util.inspect(request.payload)}`)

Expand Down Expand Up @@ -79,11 +85,13 @@ module.exports = {
model.handleBulkQuoteRequest(request.headers, request.payload, span).catch(err => {
request.server.log(['error'], `ERROR - handleBulkQuoteRequest: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - POST /bulkQuotes: ${LibUtil.getStackOrInspect(err)}`)
const fspiopError = ErrorHandler.ReformatFSPIOPError(err)
model.handleException(fspiopSource, bulkQuoteId, fspiopError, request.headers, span)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE)
Expand Down
16 changes: 16 additions & 0 deletions src/handlers/bulkQuotes/{id}.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const Enum = require('@mojaloop/central-services-shared').Enum
const EventSdk = require('@mojaloop/event-sdk')
const LibUtil = require('../../lib/util')
const BulkQuotesModel = require('../../model/bulkQuotes.js')
const Metrics = require('@mojaloop/central-services-metrics')

/**
* Operations on /bulkQuotes/{id}
*/
Expand All @@ -49,6 +51,11 @@ module.exports = {
* responses: 202, 400, 401, 403, 404, 405, 406, 501, 503
*/
get: async function getBulkQuotesById (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_id_get',
'Process HTTP GET /bulkQuotes/{id} request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a GET /bulkQuotes/{id} request for bulkQuoteId ${request.params.id}`)

Expand Down Expand Up @@ -77,10 +84,12 @@ module.exports = {
model.handleBulkQuoteGet(request.headers, bulkQuoteId, span).catch(err => {
request.server.log(['error'], `ERROR - handleBulkQuoteGet: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - GET /bulkQuotes/{id}: ${LibUtil.getStackOrInspect(err)}`)
model.handleException(fspiopSource, bulkQuoteId, err, request.headers, span)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE)
Expand All @@ -94,6 +103,11 @@ module.exports = {
* responses: 200, 400, 401, 403, 404, 405, 406, 501, 503
*/
put: async function putBulkQuotesById (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_id_get',
'Process HTTP PUT /bulkQuotes/{id} request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a PUT /bulkQuotes/{id} request: ${util.inspect(request.payload)}`)

Expand All @@ -120,10 +134,12 @@ module.exports = {
model.handleBulkQuoteUpdate(request.headers, bulkQuoteId, request.payload, span).catch(err => {
request.server.log(['error'], `ERROR - handleBulkQuoteUpdate: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - PUT /bulkQuotes/{id}: ${LibUtil.getStackOrInspect(err)}`)
model.handleException(fspiopSource, bulkQuoteId, err, request.headers, span)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.OK.CODE)
Expand Down
9 changes: 9 additions & 0 deletions src/handlers/bulkQuotes/{id}/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const Enum = require('@mojaloop/central-services-shared').Enum
const EventSdk = require('@mojaloop/event-sdk')
const LibUtil = require('../../../lib/util')
const BulkQuotesModel = require('../../../model/bulkQuotes')
const Metrics = require('@mojaloop/central-services-metrics')

/**
* Operations on /bulkQuotes/{id}/error
*/
Expand All @@ -49,6 +51,11 @@ module.exports = {
* responses: 200, 400, 401, 403, 404, 405, 406, 501, 503
*/
put: async function BulkQuotesErrorById (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_id_get',
'Process HTTP PUT /bulkQuotes/{id}/error request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a PUT /bulkQuotes/{id}/error request: ${util.inspect(request.payload)}`)

Expand All @@ -75,10 +82,12 @@ module.exports = {
model.handleBulkQuoteError(request.headers, bulkQuoteId, request.payload.errorInformation, span).catch(err => {
request.server.log(['error'], `ERROR - handleBulkQuoteError: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - PUT /bulkQuotes/{id}/error: ${LibUtil.getStackOrInspect(err)}`)
model.handleException(fspiopSource, bulkQuoteId, err, request.headers)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.OK.CODE)
Expand Down
2 changes: 2 additions & 0 deletions src/handlers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ const health = require('./health')
const bulkQuotes = require('./bulkQuotes')
const bulkQuotesById = require('./bulkQuotes/{id}')
const bulkQuotesErrorById = require('./bulkQuotes/{id}/error')
const metrics = require('./metrics')

module.exports = {
HealthGet: health.get,
MetricsGet: metrics.get,
QuotesErrorByIDPut: quotesErrorByID.put,
QuotesByIdGet: quotesById.get,
QuotesByIdPut: quotesById.put,
Expand Down
9 changes: 9 additions & 0 deletions src/handlers/metrics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

const Metrics = require('@mojaloop/central-services-metrics')

module.exports = {
get: async (context, request, h) => {
return h.response(await Metrics.getMetricsForPrometheus()).code(200)
}
}
8 changes: 8 additions & 0 deletions src/handlers/quotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const ErrorHandler = require('@mojaloop/central-services-error-handling')
const EventSdk = require('@mojaloop/event-sdk')
const LibUtil = require('../lib/util')
const QuotesModel = require('../model/quotes')
const Metrics = require('@mojaloop/central-services-metrics')

/**
* Operations on /quotes
Expand All @@ -52,6 +53,11 @@ module.exports = {
* responses: 202, 400, 401, 403, 404, 405, 406, 501, 503
*/
post: async function Quotes (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_post',
'Process HTTP POST quotes request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a POST /quotes request: ${util.inspect(request.payload)}`)

Expand Down Expand Up @@ -79,11 +85,13 @@ module.exports = {
model.handleQuoteRequest(request.headers, request.payload, span).catch(err => {
request.server.log(['error'], `ERROR - handleQuoteRequest: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - POST /quotes: ${LibUtil.getStackOrInspect(err)}`)
const fspiopError = ErrorHandler.ReformatFSPIOPError(err)
model.handleException(fspiopSource, quoteId, fspiopError, request.headers, span)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE)
Expand Down
15 changes: 15 additions & 0 deletions src/handlers/quotes/{id}.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const Enum = require('@mojaloop/central-services-shared').Enum
const EventSdk = require('@mojaloop/event-sdk')
const LibUtil = require('../../lib/util')
const QuotesModel = require('../../model/quotes.js')
const Metrics = require('@mojaloop/central-services-metrics')

/**
* Operations on /quotes/{id}
Expand All @@ -51,6 +52,11 @@ module.exports = {
* responses: 202, 400, 401, 403, 404, 405, 406, 501, 503
*/
get: async function getQuotesById (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_id_get',
'Process HTTP GET /quotes/{id} request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a GET /quotes/{id} request for quoteId ${request.params.id}`)

Expand Down Expand Up @@ -79,10 +85,12 @@ module.exports = {
model.handleQuoteGet(request.headers, quoteId, span).catch(err => {
request.server.log(['error'], `ERROR - handleQuoteGet: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - GET /quotes/{id}: ${LibUtil.getStackOrInspect(err)}`)
model.handleException(fspiopSource, quoteId, err, request.headers, span)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE)
Expand All @@ -97,6 +105,11 @@ module.exports = {
* responses: 200, 400, 401, 403, 404, 405, 406, 501, 503
*/
put: async function putQuotesById (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_id_put',
'Process HTTP PUT /quotes/{id} request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a PUT /quotes/{id} request: ${util.inspect(request.payload)}`)

Expand All @@ -123,10 +136,12 @@ module.exports = {
model.handleQuoteUpdate(request.headers, quoteId, request.payload, span).catch(err => {
request.server.log(['error'], `ERROR - handleQuoteUpdate: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - PUT /quotes/{id}: ${LibUtil.getStackOrInspect(err)}`)
model.handleException(fspiopSource, quoteId, err, request.headers, span)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.OK.CODE)
Expand Down
8 changes: 8 additions & 0 deletions src/handlers/quotes/{id}/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const EventSdk = require('@mojaloop/event-sdk')
const Enum = require('@mojaloop/central-services-shared').Enum
const LibUtil = require('../../../lib/util')
const QuotesModel = require('../../../model/quotes')
const Metrics = require('@mojaloop/central-services-metrics')

/**
* Operations on /quotes/{id}/error
Expand All @@ -51,6 +52,11 @@ module.exports = {
* responses: 200, 400, 401, 403, 404, 405, 406, 501, 503
*/
put: async function QuotesByIdAndError (context, request, h) {
const histTimerEnd = Metrics.getHistogram(
'quotes_id_put_error',
'Process HTTP PUT /quotes/{id}/error request',
['success']
).startTimer()
// log request
request.server.log(['info'], `got a PUT /quotes/{id}/error request: ${util.inspect(request.payload)}`)

Expand All @@ -77,10 +83,12 @@ module.exports = {
model.handleQuoteError(request.headers, quoteId, request.payload.errorInformation, span).catch(err => {
request.server.log(['error'], `ERROR - handleQuoteError: ${LibUtil.getStackOrInspect(err)}`)
})
histTimerEnd({ success: true })
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - PUT /quotes/{id}/error: ${LibUtil.getStackOrInspect(err)}`)
model.handleException(fspiopSource, quoteId, err, request.headers)
histTimerEnd({ success: false })
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.OK.CODE)
Expand Down
10 changes: 10 additions & 0 deletions src/handlers/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ const APIRoutes = (api) => [
tags: ['api', 'health'],
description: 'GET health'
}
},
{
method: 'GET',
path: '/metrics',
handler: (req, h) => handleRequest(api, req, h),
config: {
tags: ['api', 'metrics'],
description: 'Prometheus metrics endpoint',
id: 'metrics'
}
}
]

Expand Down
Loading

0 comments on commit a5864fa

Please sign in to comment.