-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding foundation for dtrace probe support #959
Changes from 11 commits
7e926d2
2fbf525
09a03f3
be1c397
37153c5
f60329c
27456bc
23e8ea7
4b3fa05
7a6df3b
3ae3363
e739a71
863f64f
5c71582
9623b28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Load modules | ||
|
||
var Utils = require('./utils'); | ||
// dtrace-provider loaded inline when installed | ||
|
||
|
||
// Declare internals | ||
|
||
var internals = {}; | ||
|
||
|
||
internals.probes = { | ||
'pre.start': ['char *'], | ||
'pre.end': ['char *', 'json'] | ||
}; | ||
|
||
module.exports = internals.DTrace = function (name) { | ||
|
||
Utils.assert(this.constructor === internals.DTrace, 'DTrace must be instantiated using new'); | ||
|
||
if (!internals.DTrace.isInstalled()) { | ||
this.report = function () {}; | ||
return; | ||
} | ||
|
||
var dtrace = new internals.DTrace.Provider(name); | ||
this._probes = {}; | ||
var keys = Object.keys(internals.probes); | ||
for (var i = 0, il = keys.length; i < il; ++i) { | ||
var key = keys[i]; | ||
var probe = dtrace.addProbe.apply(dtrace, [key].concat(internals.probes[key])); | ||
this._probes[key] = probe; | ||
} | ||
|
||
dtrace.enable(); | ||
}; | ||
|
||
|
||
internals.DTrace.prototype.report = function (key, args) { | ||
|
||
this._probes[key].fire(function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not create probes on first use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They will only be created when dtrace-provider is installed. In which case, if we create a probe on first use then that may lead to additional overhead after the server has started, versus initializing during the startup. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like the idea of having to manage this list in one place, and every time we add a probe also register it here. How slow is creating probes? What about user-defined probes? |
||
|
||
return args; | ||
}); | ||
}; | ||
|
||
|
||
internals.DTrace.isInstalled = function () { | ||
|
||
var result = false; | ||
try { | ||
result = !!require.resolve('dtrace-provider'); | ||
} | ||
catch (err) {} | ||
|
||
internals.DTrace.isInstalled = function () { | ||
|
||
return result; | ||
}; | ||
|
||
return result; | ||
}; | ||
|
||
|
||
internals.DTrace.Provider = internals.DTrace.isInstalled() && require('dtrace-provider').DTraceProvider; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Load modules | ||
|
||
var Lab = require('lab'); | ||
var Hapi = require('../..'); | ||
var DTrace = require('../../lib/dtrace'); | ||
|
||
|
||
// Declare internals | ||
|
||
var internals = {}; | ||
|
||
|
||
// Test shortcuts | ||
|
||
var expect = Lab.expect; | ||
var before = Lab.before; | ||
var after = Lab.after; | ||
var describe = Lab.experiment; | ||
var it = Lab.test; | ||
|
||
|
||
describe('DTrace', function () { | ||
|
||
it('doesn\'t fire probes when dtrace provider isn\'t installed', function (done) { | ||
|
||
var provider = DTrace.Provider; | ||
var isInstalled = DTrace.isInstalled; | ||
DTrace.Provider = function () { | ||
|
||
return { | ||
enable: function () {}, | ||
addProbe: function () { | ||
|
||
return { | ||
fire: function (fn) { | ||
|
||
expect(fn).to.not.exist; | ||
} | ||
}; | ||
} | ||
}; | ||
}; | ||
DTrace.isInstalled = function () { | ||
|
||
return false; | ||
}; | ||
|
||
var server = new Hapi.Server(); | ||
|
||
|
||
var pre1 = function (request, next) { | ||
|
||
next('Hello'); | ||
}; | ||
|
||
server.route({ method: '*', path: '/', config: { | ||
handler: function () { | ||
|
||
this.reply('OK'); | ||
}, | ||
pre: [ | ||
{ method: pre1, assign: 'm1' } | ||
] | ||
}}); | ||
|
||
server.inject({ url: '/' }, function () { | ||
|
||
DTrace.Provider = provider; | ||
DTrace.isInstalled = isInstalled; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('fires correct probe on prerequisites when dtrace-provider is installed', function (done) { | ||
|
||
var provider = DTrace.Provider; | ||
var isInstalled = DTrace.isInstalled; | ||
DTrace.Provider = function () { | ||
|
||
return { | ||
enable: function () {}, | ||
addProbe: function () { | ||
|
||
return { | ||
fire: function (fn) { | ||
|
||
expect(fn()).to.contain('m1'); | ||
DTrace.Provider = provider; | ||
DTrace.isInstalled = isInstalled; | ||
done(); | ||
} | ||
}; | ||
} | ||
}; | ||
}; | ||
DTrace.isInstalled = function () { | ||
|
||
return true; | ||
}; | ||
|
||
var server = new Hapi.Server(); | ||
var pre1 = function (request, next) { | ||
|
||
next('Hello'); | ||
}; | ||
|
||
server.route({ method: '*', path: '/', config: { | ||
handler: function () { | ||
|
||
this.reply('OK'); | ||
}, | ||
pre: [ | ||
{ method: pre1, assign: 'm1' } | ||
] | ||
}}); | ||
|
||
server.inject({ url: '/' }, function () {}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
args is?? If I have to build an array or object, that's bad.