feat: restify instrumentation#416
feat: restify instrumentation#416vmarchaud merged 31 commits intoopen-telemetry:mainfrom rauno56:feat/restify-instrumentation
Conversation
plugins/node/opentelemetry-instrumentation-restify/src/instrumentation.ts
Outdated
Show resolved
Hide resolved
Codecov Report
@@ Coverage Diff @@
## main #416 +/- ##
=======================================
Coverage 95.83% 95.83%
=======================================
Files 15 15
Lines 624 624
Branches 94 94
=======================================
Hits 598 598
Misses 26 26 |
examples/restify/client.js
Outdated
| // the span, which is created to track work that happens outside of the | ||
| // request lifecycle entirely. | ||
| const span = tracer.startSpan(`makeRequest to ${path}`); | ||
| api.context.with(api.setSpan(api.context.active(), span), () => { |
There was a problem hiding this comment.
Do we need to include manual span creation in the example? I think we should keep the client as simple as possible for an example focusing on server/restify instrumentation. HTTP instrumentation should generate a client span anyway.
There was a problem hiding this comment.
True. It would make sense if the HTTP instrumentation was not there. I'll remove that.
|
|
||
| const { diag } = api; | ||
| const RESTIFY_MW_METHODS = ['use', 'pre']; | ||
| const RESTIFY_METHODS = ['del', 'get', 'head', 'opts', 'post', 'put', 'patch']; |
There was a problem hiding this comment.
Does restify support custom HTTP methods? If so, will this instrumentation be able to work with them?
There was a problem hiding this comment.
No. Everything that allows adding a handler is listed here. There's a "wildcard"-way of reaching to the API of find-my-way which is mentioned here in restify docs, but even that has to be done through one of these functions.
However, I'm not testing for that shortcut. Will add a test for that.
There was a problem hiding this comment.
Restify does not support custom HTTP methods, it turns out. It overwrites it with the one specified with function used to register the handler. Added a test to make sure the more verbose API works as expected.
| if (this._isDisabled) { | ||
| return handler(req, res, next); | ||
| } | ||
| // const parentSpan = api.getSpan(api?.context?.active()); |
There was a problem hiding this comment.
Need to update the name of the parent span here for incoming requests, e.g. as is in express: https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/opentelemetry-instrumentation-express/src/express.ts#L193-L208
| return module; | ||
| } | ||
|
|
||
| private _middlewarePatcher(original: Function, methodName?: string) { |
There was a problem hiding this comment.
I think middleware spans should have middleware name as the span name (not sure if possibly with restify), e.g. the operation tree looks like this currently, where each middleware operation name is the route name:

However the express instrumentation contains middleware names:

Also I think middleware spans should have the incoming request span as its parent.
There was a problem hiding this comment.
Yep, it's possible. Express takes the name of the function it seems, which can be undefined at times, but still better than nothing. Thanks!
Also I think middleware spans should have the incoming request span as its parent.
I generally agree but don't want to change that because there might not be a request span if HTTP instrumentation is not enabled, so the structure would be different between HTTP instrumentation enabled and not.
|
Seems to work fine with restify |
johnbley
left a comment
There was a problem hiding this comment.
In general, LGTM. Thanks for this significant feature contribution!
| return original.call( | ||
| this, | ||
| path, | ||
| ...instrumentation._handlerPatcher( |
There was a problem hiding this comment.
I like how cleanly you've kept the reuse between methodPatcher and middlewarePatcher - not too complex but still keeping the essential bits parameterized instead of copied+pasted.
dyladan
left a comment
There was a problem hiding this comment.
Looks awesome thanks for contributing
plugins/node/opentelemetry-instrumentation-restify/src/instrumentation.ts
Outdated
Show resolved
Hide resolved
plugins/node/opentelemetry-instrumentation-restify/src/instrumentation.ts
Outdated
Show resolved
Hide resolved
plugins/node/opentelemetry-instrumentation-restify/package.json
Outdated
Show resolved
Hide resolved
plugins/node/opentelemetry-instrumentation-restify/package.json
Outdated
Show resolved
Hide resolved
|
I think I addressed everything except two totally valid points @obecny, brought up, I don't necessarily think are worth changing and would like a second opinion on:
I don't have a strong technical preference in either of those points, more of a question of how much bikeshedding we want to go through in the long run and for me to calibrate how important maintainers generally think such questions are. |
|
I agree with @obecny here on both points:
I agree with you on this however: that there are both technical preference. I don't like blocking PRs for those kind of choices (so i'll not) but i strongly recommend addressing them. |
Yes, it is not supposed to, but Removed Thanks a lot @vmarchaud and @obecny for your input. It's highly appreciated! 🙏 |
I do wonder whether we should come up with another solution than implementing stuff ourselves if we have a utility in 3 instrumentations? 5? 15? |
We generally have them on the |
vmarchaud
left a comment
There was a problem hiding this comment.
thanks taking the time to addressing all feedback :)
| { | ||
| "name": "restify-example", | ||
| "private": true, | ||
| "version": "0.18.0", |
There was a problem hiding this comment.
Nit: 0.15.0 in core we have 0.18.x
There was a problem hiding this comment.
Version in examples are not kept in sync in this repo, i think it would be better to do it with lerna instead
EDit: #428
Which problem is this PR solving?
This is adding
restifyinstrumentation.Short description of the changes
Restify has a somewhat similar API to
expressand is created for the same purpose - building APIs. This instrumentation wraps all handlers to generate a span for each of them.