Skip to content

Commit b6781eb

Browse files
committed
start of apm code
1 parent 40a3be8 commit b6781eb

File tree

3 files changed

+111
-2
lines changed

3 files changed

+111
-2
lines changed

index.js

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Core module
2-
var core = require('mongodb-core');
2+
var core = require('mongodb-core'),
3+
EventEmitter = require('events').EventEmitter,
4+
inherits = require('util').inherits;
35

46
// Set up the connect function
57
var connect = require('./lib/mongo_client').connect;
@@ -35,5 +37,86 @@ connect.Timestamp = core.BSON.Timestamp;
3537

3638
// Add connect method
3739
connect.connect = connect;
40+
// Operation id
41+
var operationId = 1;
42+
43+
var Instrumentation = function() {
44+
EventEmitter.call(this);
45+
// Names of methods we need to wrap
46+
var methods = ['command'];
47+
// Prototype
48+
var proto = core.Server.prototype;
49+
// Reference
50+
var self = this;
51+
// Core server method we are going to wrap
52+
methods.forEach(function(x) {
53+
var func = proto[x];
54+
55+
// The actual prototype
56+
proto[x] = function() {
57+
var requestId = core.Query.nextRequestId();
58+
var ourOpId = operationId++;
59+
// Get the aruments
60+
var args = Array.prototype.slice.call(arguments, 0);
61+
var ns = args[0];
62+
var commandObj = args[1];
63+
var keys = Object.keys(commandObj);
64+
var commandName = keys[0];
65+
var db = ns.split('.')[0];
66+
67+
// Get a connection reference for this server instance
68+
var connection = this.s.pool.get()
69+
// Emit the start event for the command
70+
var command = {type: 'started', operationId: ourOpId};
71+
command.command = commandObj;
72+
command.databaseName = db;
73+
command.commandName = commandName
74+
command.connectionId = connection;
75+
command.requestId = requestId;
76+
self.emit('command', command)
77+
78+
// Start time
79+
var startTime = new Date().getTime();
80+
81+
// Get the callback
82+
var callback = args.pop();
83+
args.push(function(err, r) {
84+
var endTime = new Date().getTime();
85+
var command = {type: 'succeeded',
86+
duration: (endTime - startTime),
87+
requestId: requestId,
88+
operationId: ourOpId,
89+
connectionId: connection};
90+
91+
// If we have an error
92+
if(err) {
93+
command.type = 'failed'
94+
command.failure = err;
95+
} else {
96+
command.reply = r;
97+
}
98+
99+
// Emit the command
100+
self.emit('command', command)
101+
102+
// Return to caller
103+
callback(err, r);
104+
});
105+
106+
// Apply the call
107+
func.apply(this, args);
108+
}
109+
});
110+
}
111+
112+
inherits(Instrumentation, EventEmitter);
113+
114+
var instrumentation = new Instrumentation();
115+
116+
// Set up the instrumentation method
117+
connect.instrument = function() {
118+
return instrumentation;
119+
}
120+
38121
// Set our exports to be the connect function
39-
module.exports = connect;
122+
module.exports = connect;

test/functional/apm_tests.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use strict";
2+
3+
exports['Correctly receive the APM events'] = {
4+
metadata: { requires: { topology: ['single'] } },
5+
6+
// The actual test we wish to run
7+
test: function(configuration, test) {
8+
var listener = require('../..').instrument();
9+
listener.on('command', function(event) {
10+
console.log("===================================== received command")
11+
console.log(JSON.stringify(event, null, 2))
12+
});
13+
14+
var db = configuration.newDbInstance({w:1}, {poolSize:1, auto_reconnect:false});
15+
db.open(function(err, db) {
16+
db.collection('apm_test').insertOne({a:1}).then(function(r) {
17+
test.equal(1, r.insertedCount);
18+
db.close();
19+
test.done();
20+
});
21+
});
22+
}
23+
}

test/runner.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ var testFiles =[
254254
, '/test/functional/crud_api_tests.js'
255255
, '/test/functional/reconnect_tests.js'
256256

257+
// APM tests
258+
, '/test/functional/apm_tests.js'
259+
257260
// Logging tests
258261
, '/test/functional/logger_tests.js'
259262

0 commit comments

Comments
 (0)