-
Notifications
You must be signed in to change notification settings - Fork 318
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
Apply service naming flow to messaging integrations #2961
Apply service naming flow to messaging integrations #2961
Conversation
Overall package sizeSelf size: 4.03 MB Dependency sizes
🤖 This report was automatically generated by heaviest-objects-in-the-universe |
d5ab814
to
d0a8c94
Compare
Codecov Report
@@ Coverage Diff @@
## jbertran/service-naming-framework #2961 +/- ##
=====================================================================
- Coverage 87.20% 87.04% -0.16%
=====================================================================
Files 324 324
Lines 11583 11610 +27
Branches 33 33
=====================================================================
+ Hits 10101 10106 +5
- Misses 1482 1504 +22
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
bc2afe9
to
9d58aba
Compare
d0a8c94
to
58f0dca
Compare
9d58aba
to
666ed7a
Compare
58f0dca
to
4d3c8be
Compare
666ed7a
to
d6c89eb
Compare
4d3c8be
to
3f71489
Compare
53d730b
to
0b51015
Compare
8122b35
to
59c42f3
Compare
2a75c6c
to
ae92f15
Compare
'amqp.connection.user': address.user | ||
} | ||
}) | ||
this.startSpan( |
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.
I remember you and Roch talking about minimizing the line diffs in the plugins. Did the linter complain about this:
this.startSpan(this.operationName(), {
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.
Oh, I see you did follow this pattern later in the PR. Looks like there are several places where this can be applied.
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.
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.
Do you know if we're lucky enough now that all of the plugins pass this.operationName()
as the first argument and the same .service
pattern in the second argument?
If we were lucky then we could refactor startSpan
like so:
startSpan ({ childOf, kind, meta, metrics, resource, type } = {}) {
name = this.operationName()
service = this.config.service || this.serviceName({ service: this.tracer._service })
const store = storage.getStore()
If not, I then wonder if it's a common enough pattern that would could introduce some sort of wrapper that maybe filled in the blanks:
startSpanWithDefaults (obj) {
let name = this.operationName()
let service = this.config.service || this.serviceName({ service: this.tracer._service })
return this.startSpan(name, {...obj, service})
}
Then again, it might just be another annoying layer of abstraction. Wdyt @rochdev?
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.
Name and service are indeed common as far as I've seen, it's just that the service name override config.service || this.serviceName
occurs at different levels in the hierarchy depending on the plugins. I think we should be able to make this behaviour common, but I'd like to update all relevant plugins to use the naming schema before tackling that, to have a clearer picture of where the pitfalls are (if any).
@@ -240,6 +240,17 @@ describe('Plugin Manager', () => { | |||
loadChannel.publish({ name: 'four' }) | |||
expect(instantiated).to.deep.equal(['two', 'four']) | |||
}) | |||
it('configures service naming schema resolution', () => { |
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.
I wonder if we should break this up:
const Nomenclature = require('../../dd-trace/src/service-naming') // top of file?
describe('configures service naming schema resolution', () => {
const config = {
foo: { 'bar': 1 },
baz: 2
}
let configureSpy
beforeEach(() => {
configureSpy = sinon.spy(Nomenclature, 'configure')
})
afterEach(() => {
configureSpy.restore()
})
it('works', () => {
pm.configure(config)
expect(configureSpy).to.have.been.calledWith(config)
})
})
The expect()
call throws IIRC, and basically the test can fail for other reasons and not get to the part with the restore. By throwing the cleanup in an afterEach
(or after
) it then prevents a situation where a failed expectation pollutes the future state of the tests.
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.
Done in #2941
I left a bunch of small comments but I think it's architecturally good and overall pretty close. |
447629c
to
2e1360a
Compare
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.
The overall design LGTM, just a few comments on minor things that could be improved, especially given that this will touch every plugin eventually.
|
||
withNamingSchema( | ||
() => sender.send({ key: 'value' }), | ||
() => namingSchema.send.opName, |
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.
Do these need to be functions? Accepting an object could make this easier also when an override is not needed, for example withNamingSchema(() => {}, namingSchema.send)
.
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.
With the way the tests are performed, they do need to be functions. I'm open to other ideas since I'm not a huge fan either 😅
namingSchema
is a proxy that resolves the v0
/v1
part of the naming schema, so it must be accessed inside the test case, because the configuration change that controls v0
/v1
is kept at the test case level.
@@ -7,15 +7,17 @@ const { getResourceName } = require('./util') | |||
|
|||
class AmqplibClientPlugin extends ClientPlugin { | |||
static get id () { return 'amqplib' } | |||
static get type () { return 'messaging' } | |||
static get ioDirection () { return 'controlPlane' } |
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.
Not sure I understand this, that definitely doesn't sound like a direction?
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.
Also, is this actually used somewhere?
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.
Agreed, this ioDirection
should probably be more generically named. subType
sounds a bit too generic to me, WDYT?
Of all 3 AMQP integrations, this one is special because it's auto-instrumented based on a defs.js
file generated by the library, which includes control-plane calls for managing exchanges and queues. These get their own amqp.command
operation name, which has to go somewhere that's neither inbound
nor outbound
in the naming schema.
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.
The fact that it's a control plane then can be inferred by type=worker
+ kind=client
.
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.
Done in 50b1fe7. Client integrations will get updated, so I'll generalize this part to client integrations when they're all updated.
@@ -7,15 +7,17 @@ const { getResourceName } = require('./util') | |||
|
|||
class AmqplibClientPlugin extends ClientPlugin { | |||
static get id () { return 'amqplib' } | |||
static get type () { return 'messaging' } |
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.
This is redundant with both the span kind and the IO direction, and could be set in the base class for most cases. Can we settle on just 1 and make sure that everything is normalized accordingly?
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.
Span kind can be integrated in startSpan
for consumer and producer plugins. For this specific one, since it's a client we can't bake it in until we've dealt with all clients, and we're in the rare case where the client is specifically a messaging client (most will be HTTP or database), so setting it here seems like the best we can do.
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.
Done in 05ad286
156b625
to
ca5d3e1
Compare
ca5d3e1
to
e1db72b
Compare
a27b9d1
to
427f07e
Compare
427f07e
to
50b1fe7
Compare
* add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type
* add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type
* add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type
* add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
* introduce DD_TRACE_SPAN_ATTRIBUTE_SCHEMA env var * add attribute schema v0 for rhea * add attribute schema v1 for rhea * add test harness for service/operation naming * grab config object from pluginManager init * provide schema autoresolution in consumer/producer plugins * bind service to schema manager at configure time * rename plugins to match inbound/outbound service naming terminology * minimize test dependencies * naming resolution wrt version in the test object uses the Nomenclature, instead of being resolved by the test fixture * we no longer use the test fixture for _all_ existing tests, rather let the default resolution do the work * the testing fixture accepts a callback which is a minimal viable trace retrieval, on which we examine _only_ service and name * split test naming schema from test code * Apply service naming flow to messaging integrations (#2961) * add v0 to all messaging plugins * add v1 to all messaging plugins * test naming schema for all messaging integrations * add naming schema tests for other versions * bake messaging data into producer/consumer plugins * persist kind in plugins and infer naming subtype from kind+type * no logs on empty DD_SPAN_TRACE_ATTRIBUTE_SCHEMA * don't compute service name unless necessary
What does this PR do?
Apply the new naming flow introduced in #2941 to all messaging integrations.
In source, this just requires using the
TracingPlugin
methods for naming resolution.In tests, this means defining the expected naming per version and performing relevant tests for both
v0
andv1
, using thewithNamingSchema
fixture.Motivation
After the introduction of #2941 , we want all plugins to be sensitive to the naming schema.
Additional Notes