Created
February 9, 2019 00:21
-
-
Save crrobinson14/213b1865672f015b27f5a30835a9376f to your computer and use it in GitHub Desktop.
QOS Logging Middleware for ActionHero
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Initializer, api } = require('actionhero'); | |
const fs = require('fs'); | |
const shortid = require('../lib/shortid'); | |
const safeApiRequestId = params => (params.apiRequestId || shortid(20)) | |
.replace(/[^0-9a-zA-Z_-]/g, '') | |
.substring(0, 64); | |
function instrumentAction(data) { | |
const { action, params, response, connection } = data; | |
// Create an api request ID if one wasn't on the record, and sanitize it | |
const apiRequestId = safeApiRequestId(params); | |
params.apiRequestId = apiRequestId; | |
// Copy some fields to the response object for normal API calls | |
response.action = action; | |
response.apiRequestId = apiRequestId; | |
response.serverTime = +new Date(); | |
data.actionQos = { | |
action, | |
apiRequestId, | |
connectionId: (connection || {}).id, | |
connectionType: (connection || {}).type, | |
startTime: Date.now(), | |
endTime: 0, | |
execTime: 0, | |
status: 0, | |
headers: {}, | |
params: {}, | |
}; | |
// postProcessors are skipped on errors, so we set this ahead of time in case something throws. | |
data.response.status = 'ERROR'; | |
} | |
function reportQOS(data) { | |
const { actionQos } = data; | |
/* istanbul ignore next */ | |
if (!actionQos) { | |
return; | |
} | |
actionQos.endTime = Date.now(); | |
actionQos.execTime = actionQos.endTime - actionQos.startTime; | |
actionQos.status = ((data.connection || {}).rawConnection || {}).responseHttpCode || 200; | |
// TODO: Add this record as a reportable metric maybe in CloudWatch? | |
data.response.status = 'OK'; | |
} | |
process.on('unhandledRejection', (reason, p) => console.log('Unhandled Rejection at:', p, 'reason:', reason)); | |
process.on('uncaughtException', err => fs.writeSync(1, `Caught exception: ${err}\n`)); | |
module.exports = class QOSLog extends Initializer { | |
constructor() { | |
super(); | |
this.name = 'QOSLog'; | |
this.loadPriority = 500; | |
this.startPriority = 500; | |
this.stopPriority = 500; | |
} | |
async initialize() { | |
api.qosLog = QOSLog; | |
} | |
async start() { | |
// Check incoming requests for authentication requirements | |
api.actions.addMiddleware({ | |
name: 'Request Processing : QOS', | |
global: true, | |
priority: 500, | |
preProcessor: instrumentAction, | |
postProcessor: reportQOS | |
}); | |
} | |
async stop() { | |
// TODO: Flush QOS metrics if necessary | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment