Skip to content
This repository has been archived by the owner on Feb 4, 2022. It is now read-only.

Commit

Permalink
feat(apm): add events for command monitoring support in core
Browse files Browse the repository at this point in the history
NODE-1390
  • Loading branch information
mbroadst committed Apr 9, 2018
1 parent 0e660eb commit 37dce9c
Showing 1 changed file with 105 additions and 0 deletions.
105 changes: 105 additions & 0 deletions lib/connection/apm.js
@@ -0,0 +1,105 @@
'use strict';

/** Commands that we want to redact because of the sensitive nature of their contents */
const SENSITIVE_COMMANDS = [
'authenticate',
'saslStart',
'saslContinue',
'getnonce',
'createUser',
'updateUser',
'copydbgetnonce',
'copydbsaslstart',
'copydb'
];

// helper methods
function extractCommand(command) { return command.query ? command.query : command; }
function extractCommandName(command) { return Object.keys(command)[0]; }
function calculateDuration(started) { return Date.now() - started; }
function generateConnectionId(pool) { return `${pool.options.host}:${pool.options.port}`; }
function maybeRedact(commandName, result) {
return SENSITIVE_COMMANDS.indexOf(commandName) !== -1 ? {} : result;
}

/** An event indicating the start of a given command */
class CommandStartedEvent {
/**
* Create a started event
*
* @param {Pool} pool the pool that originated the command
* @param {Object} command the command
*/
constructor (pool, command) {
const cmd = extractCommand(command);
const commandName = extractCommandName(cmd);

// NOTE: remove in major revision, this is not spec behavior
if (SENSITIVE_COMMANDS.indexOf(commandName) !== -1) {
this.commandObj = {};
this.commandObj[commandName] = true;
}

Object.assign(this, {
command: cmd,
databaseName: command.ns.split('.')[0],
commandName: extractCommandName(cmd),
requestId: command.requestId,
connectionId: generateConnectionId(pool)
});
}
};

/** An event indicating the success of a given command */
class CommandSucceededEvent {
/**
* Create a succeeded event
*
* @param {Pool} pool the pool that originated the command
* @param {Object} command the command
* @param {Object} reply the reply for this command from the server
* @param {Number} started a timestamp of when the command was first sent to calculate duration
*/
constructor(pool, command, reply, started) {
const cmd = extractCommand(command);
const commandName = extractCommandName(cmd);

Object.assign(this, {
duration: calculateDuration(started),
commandName,
reply: maybeRedact(commandName, reply.result),
requestId: command.requestId,
connectionId: generateConnectionId(pool)
});
}
};

/** An event indicating the failure of a given command */
class CommandFailedEvent {
/**
* Create a failure event
*
* @param {Pool} pool the pool that originated the command
* @param {Object} command the command
* @param {MongoError|Object} error the generated error or a server error response
* @param {Number} started a timestamp of when the command was first sent to calculate duration
*/
constructor(pool, command, error, started) {
const cmd = extractCommand(command);
const commandName = extractCommandName(cmd);

Object.assign(this, {
duration: calculateDuration(started),
commandName,
failure: maybeRedact(commandName, error),
requestId: command.requestId,
connectionId: generateConnectionId(pool)
});
}
};

module.exports = {
CommandStartedEvent,
CommandSucceededEvent,
CommandFailedEvent
};

0 comments on commit 37dce9c

Please sign in to comment.