overleaf/libraries/metrics/mongodb.coffee

101 lines
3.5 KiB
CoffeeScript
Raw Normal View History

2014-05-06 15:52:03 +00:00
module.exports =
monitor: (mongodb_require_path, logger) ->
2015-07-28 15:53:55 +00:00
try
# for the v1 driver the methods to wrap are in the mongodb
# module in lib/mongodb/db.js
mongodb = require("#{mongodb_require_path}")
try
# for the v2 driver the relevant methods are in the mongodb-core
# module in lib/topologies/{server,replset,mongos}.js
v2_path = mongodb_require_path.replace(/\/mongodb$/, '/mongodb-core')
mongodbCore = require(v2_path)
2014-05-06 15:52:03 +00:00
Metrics = require("./metrics")
monitorMethod = (base, method, type) ->
2015-07-28 15:53:55 +00:00
return unless base?
return unless (_method = base[method])?
arglen = _method.length
2014-05-06 15:52:03 +00:00
2015-07-28 15:53:55 +00:00
mongo_driver_v1_wrapper = (db_command, options, callback) ->
2014-05-06 15:52:03 +00:00
if (typeof callback == 'undefined')
callback = options
options = {}
2014-05-06 16:19:04 +00:00
collection = db_command.collectionName
if collection.match(/\$cmd$/)
# Ignore noisy command methods like authenticating, ismaster and ping
return _method.call this, db_command, options, callback
2014-05-07 10:50:09 +00:00
key = "mongo-requests.#{collection}.#{type}"
2014-05-06 15:52:03 +00:00
if db_command.query?
query = Object.keys(db_command.query).sort().join("_")
key += "." + query
timer = new Metrics.Timer("mongo", {collection: collection, query:query})
2014-05-06 15:52:03 +00:00
start = new Date()
_method.call this, db_command, options, () ->
timer.done()
time = new Date() - start
logger.log
query: db_command.query
query_type: type
2014-05-06 16:19:04 +00:00
collection: collection
2014-05-06 15:52:03 +00:00
"response-time": new Date() - start
"mongo request"
callback.apply this, arguments
2015-07-28 15:53:55 +00:00
mongo_driver_v2_wrapper = (ns, ops, options, callback) ->
if (typeof callback == 'undefined')
callback = options
options = {}
if ns.match(/\$cmd$/)
# Ignore noisy command methods like authenticating, ismaster and ping
return _method.call this, ns, ops, options, callback
key = "mongo-requests.#{ns}.#{type}"
if ops[0].q? # ops[0].q
query = Object.keys(ops[0].q).sort().join("_")
key += "." + query
timer = new Metrics.Timer(key)
start = new Date()
_method.call this, ns, ops, options, () ->
timer.done()
time = new Date() - start
logger.log
query: ops[0].q
query_type: type
collection: ns
"response-time": new Date() - start
"mongo request"
callback.apply this, arguments
if arglen == 3
base[method] = mongo_driver_v1_wrapper
else if arglen == 4
base[method] = mongo_driver_v2_wrapper
monitorMethod(mongodb?.Db.prototype, "_executeQueryCommand", "query")
monitorMethod(mongodb?.Db.prototype, "_executeRemoveCommand", "remove")
monitorMethod(mongodb?.Db.prototype, "_executeInsertCommand", "insert")
monitorMethod(mongodb?.Db.prototype, "_executeUpdateCommand", "update")
monitorMethod(mongodbCore?.Server.prototype, "command", "command")
monitorMethod(mongodbCore?.Server.prototype, "remove", "remove")
monitorMethod(mongodbCore?.Server.prototype, "insert", "insert")
monitorMethod(mongodbCore?.Server.prototype, "update", "update")
monitorMethod(mongodbCore?.ReplSet.prototype, "command", "command")
monitorMethod(mongodbCore?.ReplSet.prototype, "remove", "remove")
monitorMethod(mongodbCore?.ReplSet.prototype, "insert", "insert")
monitorMethod(mongodbCore?.ReplSet.prototype, "update", "update")
monitorMethod(mongodbCore?.Mongos.prototype, "command", "command")
monitorMethod(mongodbCore?.Mongos.prototype, "remove", "remove")
monitorMethod(mongodbCore?.Mongos.prototype, "insert", "insert")
monitorMethod(mongodbCore?.Mongos.prototype, "update", "update")