dd-trace 4.9.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +66 -0
- package/package.json +1 -1
- package/packages/datadog-instrumentations/src/couchbase.js +41 -5
- package/packages/datadog-plugin-aws-sdk/src/base.js +22 -10
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +16 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +18 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +23 -0
- package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
- package/packages/datadog-plugin-couchbase/src/index.js +32 -30
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +7 -17
- package/packages/datadog-plugin-http/src/server.js +10 -2
- package/packages/datadog-plugin-http2/src/client.js +2 -16
- package/packages/datadog-plugin-http2/src/server.js +10 -1
- package/packages/datadog-plugin-memcached/src/index.js +1 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +2 -2
- package/packages/datadog-plugin-oracledb/src/index.js +1 -1
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-redis/src/index.js +1 -1
- package/packages/datadog-plugin-tedious/src/index.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +16 -9
- package/packages/dd-trace/src/service-naming/index.js +7 -11
- package/packages/dd-trace/src/service-naming/schemas/definition.js +4 -4
- package/packages/dd-trace/src/service-naming/schemas/util.js +21 -3
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +20 -8
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +33 -23
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +33 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +14 -2
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +12 -9
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +33 -1
package/CONTRIBUTING.md
CHANGED
|
@@ -4,4 +4,70 @@ Please reach out before starting work on any major code changes.
|
|
|
4
4
|
This will ensure we avoid duplicating work, or that your code can't be merged due to a rapidly changing
|
|
5
5
|
base. If you would like support for a module that is not listed, [contact support][1] to share a request.
|
|
6
6
|
|
|
7
|
+
## Keep changes small and incremental
|
|
8
|
+
|
|
9
|
+
Changes should be incremental and understandable. As much as possible, large-scale efforts should be broken up into many PRs over time for better reviewability. If a feature would require more changes to be "complete" it's fine to land partial changes if they are not wired up to anything yet, so long as tests are included which at least prove those parts work in isolation.
|
|
10
|
+
|
|
11
|
+
There are great benefits to taking a measured and iterative approach to improvement. When working on code in fewer places there is far less risk of running into merge conflicts or incompatibilities with other systems. Keeping contributions small makes them easy to review which makes that much quicker to land. Additionally, keeping things small and iterative makes it easier for other teams to review and understand what the code does.
|
|
12
|
+
|
|
13
|
+
## Be descriptive
|
|
14
|
+
|
|
15
|
+
Sometimes code can be self-documenting, but often it can't. That is especially true to someone reviewing code they haven't worked on. Be conscious of writing code in a self-describing way and leave comments anywhere that self-description fails. This goes a long way towards making even complex code coherent to one not already familiar with it.
|
|
16
|
+
|
|
17
|
+
Try to write code in a way the describes the intent when read. For example, verbs can be used for function and method names to communicate that they are used to do some specific action. In doing so it becomes clear when referenced by name elsewhere that it is a function and what the function is meant to do. If a function can not be described with a simple verb it's probably too complex or does too many things.
|
|
18
|
+
|
|
19
|
+
## Give your code space
|
|
20
|
+
|
|
21
|
+
Very dense code is hard to read. It helps to make use of empty lines to separate logical groupings of statements. Long lines should be split up into multiple lines to make them more readable. Complex objects or arrays should generally be split over several lines. Sometimes it's a good idea to assign a variable only to immediately use it in a call as it can be more descriptive than just using the expression in place. It's not always clear what an argument is for if it doesn't visibly have a name somehow. Remember, lines are free, our time is not.
|
|
22
|
+
|
|
23
|
+
## Avoid large refactors
|
|
24
|
+
|
|
25
|
+
Large refactors should generally be avoided in favour of iterative approaches. For example, rather than rewriting how every plugin works, one might make a special-case plugin that works a bit different for their particular use-case. If several dozen files need to change to add a feature we've probably done something wrong.
|
|
26
|
+
|
|
27
|
+
Sometimes new patterns or new ideas emerge which would be a substantial improvement over the existing state. It can be tempting to want to go all-in on a new way to do something, but the code churn can be hard to manage. It's best to introduce such new things incrementally and advocate for their adoption gradually through the rest of the codebase. As old systems are gradually phased out, the infrastructure which supports them can be deleted or relegated to lazy-loading only if and when that specific part of the system needs to be used.
|
|
28
|
+
|
|
29
|
+
## Test everything
|
|
30
|
+
|
|
31
|
+
It's very difficult to know if a change is valid unless there are tests to prove it. As an extension of that, it's also difficult to know the _use_ of that code is valid if the way it is integrated is not propertly tested. For this reason we generally favour integration tests over unit tests. If an API is expected to be used in different places or in different ways then it should generally include unit tests too for each unique scenario, however great care should be taken to ensure unit tests are actually testing the _logic_ and not just testing the _mocks_. It's a very common mistake to write a unit test that abstracts away the actual use of the interface so much that it doesn't actually test how that interface works in real-world scenarios. Remember to test how it handles failures, how it operates under heavy load, and how it impacts usability of what its purpose is.
|
|
32
|
+
|
|
33
|
+
## Don't forget benchmarks
|
|
34
|
+
|
|
35
|
+
Observability products tend to have quite a bit of their behaviour running in app code hot paths. It's important we extensively benchmark anything we expect to have heavy use to ensure it performs well and we don't cause any significant regressions through future changes. Measuring once at the time of writing is insufficient--a graph with just one data point is not going to tell you much of anything.
|
|
36
|
+
|
|
37
|
+
## Always consider backportability
|
|
38
|
+
|
|
39
|
+
To reduce delta between release lines and make it easier for us to support older versions we try as much as possible to backport every change we can. We should be diligent about keeping breaking changes to a minimum and ensuring we don't use language or runtime features which are too new. This way we can generally be confident that a change can be backported.
|
|
40
|
+
|
|
41
|
+
To reduce the surface area of a breaking change, the breaking aspects could be placed behind a flag which is disabled by default or isolated to a function. In the next major the change would then be just to change the default of the flag or to start or stop calling the isolated function. By isolating the breaking logic it also becomes easier to delete later when it's no longer relevant on any release line.
|
|
42
|
+
|
|
43
|
+
Currently we do not have CI to test PRs for mergeability to past release lines, but we intend to expand our CI to include that in the future. For the time being, it's recommended when developing locally to try to cherry-pick your changes onto the previous vN.x branches to see if the tests pass there too.
|
|
44
|
+
|
|
45
|
+
## Respect semantic versioning
|
|
46
|
+
|
|
47
|
+
This library follows the semantic versioning standard, but there are some subtleties left under-specified so this section is meant to clarify exactly how we interpret the meaning of semver. Additionally, it exists to communicate that we also use semver labels on all PRs to indicate which type of release the change should land in. Outside contributions should be evaluated and a semver label selected by the relevant team.
|
|
48
|
+
|
|
49
|
+
### semver-patch
|
|
50
|
+
|
|
51
|
+
If the change is a bug or security fix, it should be labelled as semver-patch. These changes should generally not alter existing behaviour in any way other than to correct the specific issue.
|
|
52
|
+
|
|
53
|
+
### semver-minor
|
|
54
|
+
|
|
55
|
+
Any addition of new functionality should be labelled as semver-minor and should not change any existing behaviour either in how any existing API works or in changing the contents or value of any existing data being reported except in purely additive cases where all existing data retains its prior state. Such changes may include new configuration options which when used will change behaviour, or may include the addition of new data being captured such as a new instrumentation, but should not impact the current operating design of any existing features.
|
|
56
|
+
|
|
57
|
+
### semver-major
|
|
58
|
+
|
|
59
|
+
In the event that some existing functionality _does_ need to change, as much as possible the non-breaking aspects of that change should be made in a semver-minor PR and the actually breaking aspects should be done via a follow-up PR with only the specific aspects which are breaking. Remember to [always consider backportability](#always-consider-backportability).
|
|
60
|
+
|
|
61
|
+
## Indicate intended release targets
|
|
62
|
+
|
|
63
|
+
When writing major changes we use a series of labels in the form of `dont-land-on-vN.x` where N is the major release line which a PR should not land in. Every PR marked as semver-major should include these tags. These tags allow our [branch-diff](https://github.com/bengl/branch-diff) tooling to work smoothly as we can exclude PRs not intended for the release line we're preparing a release proposal for. The `semver-major` labels on their own are not sufficient as they don't encode any indication of from _which_ releases they are a major change.
|
|
64
|
+
|
|
65
|
+
For outside contributions we will have the relevant team add these labels when they review and determine when they plan to release it.
|
|
66
|
+
|
|
67
|
+
## Ensure all tests are green
|
|
68
|
+
|
|
69
|
+
We follow an all-green policy which means that for any PR to be merged _all_ tests must be passing. If a test is flaky or failing consistently the owner of that test should make it a priority to fix that test and unblock other teams from landing changes. For outside contributors there are currently several tests which will always fail as full CI permission is required. For these PRs our current process is for the relevant team to copy the PR and resubmit it to run tests as a user with full CI permission.
|
|
70
|
+
|
|
71
|
+
Eventually we plan to look into putting these permission-required tests behind a label which team members can add to their PRs at creation to run the full CI and can add to outside contributor PRs to trigger the CI from their own user credentials. If the label is not present there will be another action which checks the label is present. Rather than showing a bunch of confusing failures to new contributors it would just show a single job failure which indicates an additional label is required, and we can name it in a way that makes it clear that it's not the responsibility of the outside contributor to add it. Something like `approve-full-ci` is one possible choice there.
|
|
72
|
+
|
|
7
73
|
[1]: https://docs.datadoghq.com/help
|
package/package.json
CHANGED
|
@@ -74,7 +74,7 @@ function wrap (prefix, fn) {
|
|
|
74
74
|
return asyncResource.runInAsyncScope(() => {
|
|
75
75
|
const cb = callbackResource.bind(arguments[callbackIndex])
|
|
76
76
|
|
|
77
|
-
startCh.publish({ bucket: { name: this.name || this._name } })
|
|
77
|
+
startCh.publish({ bucket: { name: this.name || this._name }, seedNodes: this._dd_hosts })
|
|
78
78
|
|
|
79
79
|
arguments[callbackIndex] = asyncResource.bind(function (error, result) {
|
|
80
80
|
if (error) {
|
|
@@ -146,7 +146,8 @@ function wrapWithName (name) {
|
|
|
146
146
|
return function () { // no arguments used by us
|
|
147
147
|
return wrapCBandPromise(operation, name, {
|
|
148
148
|
collection: { name: this._name || '_default' },
|
|
149
|
-
bucket: { name: this._scope._bucket._name }
|
|
149
|
+
bucket: { name: this._scope._bucket._name },
|
|
150
|
+
seedNodes: this._dd_connStr
|
|
150
151
|
}, this, arguments)
|
|
151
152
|
}
|
|
152
153
|
}
|
|
@@ -155,7 +156,7 @@ function wrapWithName (name) {
|
|
|
155
156
|
function wrapV3Query (query) {
|
|
156
157
|
return function (q) {
|
|
157
158
|
const resource = getQueryResource(q)
|
|
158
|
-
return wrapCBandPromise(query, 'query', { resource }, this, arguments)
|
|
159
|
+
return wrapCBandPromise(query, 'query', { resource, seedNodes: this._connStr }, this, arguments)
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -179,7 +180,7 @@ addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^2.6.12'] }, Buc
|
|
|
179
180
|
|
|
180
181
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
181
182
|
return asyncResource.runInAsyncScope(() => {
|
|
182
|
-
startCh.publish({ resource: n1qlQuery, bucket: { name: this.name || this._name } })
|
|
183
|
+
startCh.publish({ resource: n1qlQuery, bucket: { name: this.name || this._name }, seedNodes: this._dd_hosts })
|
|
183
184
|
|
|
184
185
|
emitter.once('rows', asyncResource.bind(() => {
|
|
185
186
|
finishCh.publish(undefined)
|
|
@@ -212,11 +213,32 @@ addHook({ name: 'couchbase', file: 'lib/cluster.js', versions: ['^2.6.12'] }, Cl
|
|
|
212
213
|
Cluster.prototype._maybeInvoke = wrapMaybeInvoke(Cluster.prototype._maybeInvoke)
|
|
213
214
|
Cluster.prototype.query = wrapQuery(Cluster.prototype.query)
|
|
214
215
|
|
|
216
|
+
shimmer.wrap(Cluster.prototype, 'openBucket', openBucket => {
|
|
217
|
+
return function () {
|
|
218
|
+
const bucket = openBucket.apply(this, arguments)
|
|
219
|
+
const hosts = this.dsnObj.hosts
|
|
220
|
+
bucket._dd_hosts = hosts.map(hostAndPort => hostAndPort.join(':')).join(',')
|
|
221
|
+
return bucket
|
|
222
|
+
}
|
|
223
|
+
})
|
|
215
224
|
return Cluster
|
|
216
225
|
})
|
|
217
226
|
|
|
218
227
|
// semver >=3 <3.2.0
|
|
219
228
|
|
|
229
|
+
addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^3.0.7', '^3.1.3'] }, Bucket => {
|
|
230
|
+
shimmer.wrap(Bucket.prototype, 'collection', getCollection => {
|
|
231
|
+
return function () {
|
|
232
|
+
const collection = getCollection.apply(this, arguments)
|
|
233
|
+
const connStr = this._cluster._connStr
|
|
234
|
+
collection._dd_connStr = connStr
|
|
235
|
+
return collection
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
return Bucket
|
|
240
|
+
})
|
|
241
|
+
|
|
220
242
|
addHook({ name: 'couchbase', file: 'lib/collection.js', versions: ['^3.0.7', '^3.1.3'] }, Collection => {
|
|
221
243
|
wrapAllNames(['upsert', 'insert', 'replace'], name => {
|
|
222
244
|
shimmer.wrap(Collection.prototype, name, wrapWithName(name))
|
|
@@ -242,7 +264,21 @@ addHook({ name: 'couchbase', file: 'dist/collection.js', versions: ['>=3.2.0'] }
|
|
|
242
264
|
return collection
|
|
243
265
|
})
|
|
244
266
|
|
|
245
|
-
addHook({ name: 'couchbase', file: 'dist/
|
|
267
|
+
addHook({ name: 'couchbase', file: 'dist/bucket.js', versions: ['>=3.2.0'] }, bucket => {
|
|
268
|
+
const Bucket = bucket.Bucket
|
|
269
|
+
shimmer.wrap(Bucket.prototype, 'collection', getCollection => {
|
|
270
|
+
return function () {
|
|
271
|
+
const collection = getCollection.apply(this, arguments)
|
|
272
|
+
const connStr = this._cluster._connStr
|
|
273
|
+
collection._dd_connStr = connStr
|
|
274
|
+
return collection
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
return bucket
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
addHook({ name: 'couchbase', file: 'dist/cluster.js', versions: ['3.2.0 - 3.2.1', '>=3.2.2'] }, (cluster) => {
|
|
246
282
|
const Cluster = cluster.Cluster
|
|
247
283
|
|
|
248
284
|
shimmer.wrap(Cluster.prototype, 'query', wrapV3Query)
|
|
@@ -31,11 +31,10 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
31
31
|
if (!this.isEnabled(request)) {
|
|
32
32
|
return
|
|
33
33
|
}
|
|
34
|
-
const serviceName = this.getServiceName()
|
|
35
34
|
const childOf = this.tracer.scope().active()
|
|
36
35
|
const tags = {
|
|
37
36
|
'span.kind': 'client',
|
|
38
|
-
'service.name': serviceName,
|
|
37
|
+
'service.name': this.serviceName(),
|
|
39
38
|
'aws.operation': operation,
|
|
40
39
|
'aws.region': awsRegion,
|
|
41
40
|
'region': awsRegion,
|
|
@@ -45,7 +44,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
45
44
|
}
|
|
46
45
|
if (this.requestTags) this.requestTags.set(request, tags)
|
|
47
46
|
|
|
48
|
-
const span = this.tracer.startSpan(
|
|
47
|
+
const span = this.tracer.startSpan(this.operationFromRequest(request), { childOf, tags })
|
|
49
48
|
|
|
50
49
|
analyticsSampler.sample(span, this.config.measured)
|
|
51
50
|
|
|
@@ -79,6 +78,26 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
79
78
|
// implemented by subclasses, or not
|
|
80
79
|
}
|
|
81
80
|
|
|
81
|
+
operationFromRequest (request) {
|
|
82
|
+
// can be overriden by subclasses
|
|
83
|
+
return this.operationName({
|
|
84
|
+
id: 'aws',
|
|
85
|
+
type: 'web',
|
|
86
|
+
kind: 'client',
|
|
87
|
+
awsService: this.serviceIdentifier
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
serviceName () {
|
|
92
|
+
return this.config.service ||
|
|
93
|
+
super.serviceName({
|
|
94
|
+
id: 'aws',
|
|
95
|
+
type: 'web',
|
|
96
|
+
kind: 'client',
|
|
97
|
+
awsService: this.serviceIdentifier
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
82
101
|
isEnabled (request) {
|
|
83
102
|
const serviceId = this.serviceIdentifier.toUpperCase()
|
|
84
103
|
const envVarValue = process.env[`DD_TRACE_AWS_SDK_${serviceId}_ENABLED`]
|
|
@@ -122,13 +141,6 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
122
141
|
configure (config) {
|
|
123
142
|
super.configure(normalizeConfig(config, this.serviceIdentifier))
|
|
124
143
|
}
|
|
125
|
-
|
|
126
|
-
// TODO: test splitByAwsService when the test suite is fixed
|
|
127
|
-
getServiceName () {
|
|
128
|
-
return this.config.service
|
|
129
|
-
? this.config.service
|
|
130
|
-
: `${this.tracer._service}-aws-${this.serviceIdentifier}`
|
|
131
|
-
}
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
function normalizeConfig (config, serviceIdentifier) {
|
|
@@ -48,6 +48,22 @@ class Lambda extends BaseAwsSdkPlugin {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
operationFromRequest (request) {
|
|
53
|
+
if (request.operation === 'invoke') {
|
|
54
|
+
return this.operationName({
|
|
55
|
+
type: 'web',
|
|
56
|
+
kind: 'client'
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return this.operationName({
|
|
61
|
+
id: 'aws',
|
|
62
|
+
type: 'web',
|
|
63
|
+
kind: 'client',
|
|
64
|
+
awsService: 'lambda'
|
|
65
|
+
})
|
|
66
|
+
}
|
|
51
67
|
}
|
|
52
68
|
|
|
53
69
|
module.exports = Lambda
|
|
@@ -27,6 +27,24 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
27
27
|
// for example if it contains a phone number?
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
operationFromRequest (request) {
|
|
31
|
+
switch (request.operation) {
|
|
32
|
+
case 'publish':
|
|
33
|
+
case 'publishBatch':
|
|
34
|
+
return this.operationName({
|
|
35
|
+
type: 'messaging',
|
|
36
|
+
kind: 'producer'
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this.operationName({
|
|
41
|
+
id: 'aws',
|
|
42
|
+
type: 'web',
|
|
43
|
+
kind: 'client',
|
|
44
|
+
awsService: 'sns'
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
30
48
|
requestInject (span, request) {
|
|
31
49
|
const { operation, params } = request
|
|
32
50
|
|
|
@@ -41,6 +41,29 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
41
41
|
})
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
operationFromRequest (request) {
|
|
45
|
+
switch (request.operation) {
|
|
46
|
+
case 'receiveMessage':
|
|
47
|
+
return this.operationName({
|
|
48
|
+
type: 'messaging',
|
|
49
|
+
kind: 'consumer'
|
|
50
|
+
})
|
|
51
|
+
case 'sendMessage':
|
|
52
|
+
case 'sendMessageBatch':
|
|
53
|
+
return this.operationName({
|
|
54
|
+
type: 'messaging',
|
|
55
|
+
kind: 'producer'
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return this.operationName({
|
|
60
|
+
id: 'aws',
|
|
61
|
+
type: 'web',
|
|
62
|
+
kind: 'client',
|
|
63
|
+
awsService: 'sqs'
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
44
67
|
isEnabled (request) {
|
|
45
68
|
// TODO(bengl) Figure out a way to make separate plugins for consumer and producer so that
|
|
46
69
|
// config can be isolated to `.configure()` instead of this whole isEnabled() thing.
|
|
@@ -14,7 +14,7 @@ class CassandraDriverPlugin extends DatabasePlugin {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
this.startSpan(this.operationName(), {
|
|
17
|
-
service: this.serviceName(this.config, this.system),
|
|
17
|
+
service: this.serviceName({ pluginConfig: this.config, system: this.system }),
|
|
18
18
|
resource: trim(query, 5000),
|
|
19
19
|
type: 'cassandra',
|
|
20
20
|
kind: 'client',
|
|
@@ -1,51 +1,57 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const StoragePlugin = require('../../dd-trace/src/plugins/storage')
|
|
4
4
|
const { storage } = require('../../datadog-core')
|
|
5
|
-
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
6
5
|
|
|
7
|
-
class CouchBasePlugin extends
|
|
8
|
-
static get id () {
|
|
9
|
-
|
|
10
|
-
}
|
|
6
|
+
class CouchBasePlugin extends StoragePlugin {
|
|
7
|
+
static get id () { return 'couchbase' }
|
|
8
|
+
static get peerServicePrecursors () { return ['db.couchbase.seed.nodes'] }
|
|
11
9
|
|
|
12
|
-
addSubs (func, start
|
|
10
|
+
addSubs (func, start) {
|
|
13
11
|
this.addSub(`apm:couchbase:${func}:start`, start)
|
|
14
|
-
this.addSub(`apm:couchbase:${func}:error`, this.addError)
|
|
15
|
-
this.addSub(`apm:couchbase:${func}:finish`, finish)
|
|
12
|
+
this.addSub(`apm:couchbase:${func}:error`, error => this.addError(error))
|
|
13
|
+
this.addSub(`apm:couchbase:${func}:finish`, message => this.finish(message))
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
startSpan (operation, customTags, store, { bucket, collection }) {
|
|
16
|
+
startSpan (operation, customTags, store, { bucket, collection, seedNodes }) {
|
|
19
17
|
const tags = {
|
|
20
18
|
'db.type': 'couchbase',
|
|
21
19
|
'component': 'couchbase',
|
|
22
|
-
'service.name': this.config.service || `${this.tracer._service}-couchbase`,
|
|
23
20
|
'resource.name': `couchbase.${operation}`,
|
|
24
|
-
'span.kind':
|
|
21
|
+
'span.kind': this.constructor.kind,
|
|
22
|
+
'db.couchbase.seed.nodes': seedNodes
|
|
25
23
|
}
|
|
26
24
|
|
|
25
|
+
if (bucket) tags['couchbase.bucket.name'] = bucket.name
|
|
26
|
+
if (collection) tags['couchbase.collection.name'] = collection.name
|
|
27
|
+
|
|
27
28
|
for (const tag in customTags) {
|
|
28
29
|
tags[tag] = customTags[tag]
|
|
29
30
|
}
|
|
30
|
-
const span = this.tracer.startSpan(`couchbase.${operation}`, {
|
|
31
|
-
childOf: store ? store.span : null,
|
|
32
|
-
tags
|
|
33
|
-
})
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
return super.startSpan(
|
|
33
|
+
this.operationName({ operation }),
|
|
34
|
+
{
|
|
35
|
+
service: this.serviceName({ pluginConfig: this.config }),
|
|
36
|
+
meta: tags
|
|
37
|
+
}
|
|
38
|
+
)
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
constructor (...args) {
|
|
43
42
|
super(...args)
|
|
44
43
|
|
|
45
|
-
this.addSubs('query', ({ resource, bucket }) => {
|
|
44
|
+
this.addSubs('query', ({ resource, bucket, seedNodes }) => {
|
|
46
45
|
const store = storage.getStore()
|
|
47
|
-
const span = this.startSpan(
|
|
48
|
-
|
|
46
|
+
const span = this.startSpan(
|
|
47
|
+
'query', {
|
|
48
|
+
'span.type': 'sql',
|
|
49
|
+
'resource.name': resource,
|
|
50
|
+
'span.kind': this.constructor.kind
|
|
51
|
+
},
|
|
52
|
+
store,
|
|
53
|
+
{ bucket, seedNodes }
|
|
54
|
+
)
|
|
49
55
|
this.enter(span, store)
|
|
50
56
|
})
|
|
51
57
|
|
|
@@ -56,16 +62,12 @@ class CouchBasePlugin extends Plugin {
|
|
|
56
62
|
this._addCommandSubs('prepend')
|
|
57
63
|
}
|
|
58
64
|
_addCommandSubs (name) {
|
|
59
|
-
this.addSubs(name, ({ bucket, collection }) => {
|
|
65
|
+
this.addSubs(name, ({ bucket, collection, seedNodes }) => {
|
|
60
66
|
const store = storage.getStore()
|
|
61
|
-
const span = this.startSpan(name, {}, store, { bucket, collection })
|
|
67
|
+
const span = this.startSpan(name, {}, store, { bucket, collection, seedNodes })
|
|
62
68
|
this.enter(span, store)
|
|
63
69
|
})
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
function defaultFinish () {
|
|
68
|
-
storage.getStore().span.finish()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
73
|
module.exports = CouchBasePlugin
|
|
@@ -9,7 +9,7 @@ class ElasticsearchPlugin extends DatabasePlugin {
|
|
|
9
9
|
const body = getBody(params.body || params.bulkBody)
|
|
10
10
|
|
|
11
11
|
this.startSpan(this.operationName(), {
|
|
12
|
-
service: this.serviceName(this.config),
|
|
12
|
+
service: this.serviceName({ pluginConfig: this.config }),
|
|
13
13
|
resource: `${params.method} ${quantizePath(params.path)}`,
|
|
14
14
|
type: 'elasticsearch',
|
|
15
15
|
kind: 'client',
|
|
@@ -8,8 +8,8 @@ const formats = require('../../../ext/formats')
|
|
|
8
8
|
const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
9
9
|
const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
|
|
10
10
|
const log = require('../../dd-trace/src/log')
|
|
11
|
-
const url = require('url')
|
|
12
11
|
const { CLIENT_PORT_KEY, COMPONENT, ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
|
|
12
|
+
const { URL } = require('url')
|
|
13
13
|
|
|
14
14
|
const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
15
15
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
@@ -36,12 +36,12 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
36
36
|
const method = (options.method || 'GET').toUpperCase()
|
|
37
37
|
const childOf = store && allowed ? store.span : null
|
|
38
38
|
// TODO delegate to super.startspan
|
|
39
|
-
const span = this.startSpan(
|
|
39
|
+
const span = this.startSpan(this.operationName(), {
|
|
40
40
|
childOf,
|
|
41
41
|
meta: {
|
|
42
42
|
[COMPONENT]: this.constructor.id,
|
|
43
43
|
'span.kind': 'client',
|
|
44
|
-
'service.name':
|
|
44
|
+
'service.name': this.serviceName({ pluginConfig: this.config, sessionDetails: extractSessionDetails(options) }),
|
|
45
45
|
'resource.name': method,
|
|
46
46
|
'span.type': 'http',
|
|
47
47
|
'http.method': method,
|
|
@@ -217,25 +217,15 @@ function hasAmazonSignature (options) {
|
|
|
217
217
|
return search && search.toLowerCase().indexOf('x-amz-signature=') !== -1
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
function
|
|
221
|
-
if (config.splitByDomain) {
|
|
222
|
-
return getHost(options)
|
|
223
|
-
} else if (config.service) {
|
|
224
|
-
return config.service
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return tracer._service
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function getHost (options) {
|
|
220
|
+
function extractSessionDetails (options) {
|
|
231
221
|
if (typeof options === 'string') {
|
|
232
|
-
return
|
|
222
|
+
return new URL(options).host
|
|
233
223
|
}
|
|
234
224
|
|
|
235
|
-
const
|
|
225
|
+
const host = options.hostname || options.host || 'localhost'
|
|
236
226
|
const port = options.port
|
|
237
227
|
|
|
238
|
-
return
|
|
228
|
+
return { host, port }
|
|
239
229
|
}
|
|
240
230
|
|
|
241
231
|
function startsWith (searchString) {
|
|
@@ -23,8 +23,16 @@ class HttpServerPlugin extends ServerPlugin {
|
|
|
23
23
|
|
|
24
24
|
start ({ req, res, abortController }) {
|
|
25
25
|
const store = storage.getStore()
|
|
26
|
-
const span = web.startSpan(
|
|
27
|
-
|
|
26
|
+
const span = web.startSpan(
|
|
27
|
+
this.tracer,
|
|
28
|
+
{
|
|
29
|
+
...this.config,
|
|
30
|
+
service: this.config.service || this.serviceName()
|
|
31
|
+
},
|
|
32
|
+
req,
|
|
33
|
+
res,
|
|
34
|
+
this.operationName()
|
|
35
|
+
)
|
|
28
36
|
span.setTag(COMPONENT, this.constructor.id)
|
|
29
37
|
|
|
30
38
|
this._parentStore = store
|
|
@@ -38,12 +38,12 @@ class Http2ClientPlugin extends ClientPlugin {
|
|
|
38
38
|
|
|
39
39
|
const store = storage.getStore()
|
|
40
40
|
const childOf = store && allowed ? store.span : null
|
|
41
|
-
const span = this.startSpan(
|
|
41
|
+
const span = this.startSpan(this.operationName(), {
|
|
42
42
|
childOf,
|
|
43
43
|
meta: {
|
|
44
44
|
[COMPONENT]: this.constructor.id,
|
|
45
45
|
[SPAN_KIND]: CLIENT,
|
|
46
|
-
'service.name':
|
|
46
|
+
'service.name': this.serviceName({ pluginConfig: this.config, sessionDetails }),
|
|
47
47
|
'resource.name': method,
|
|
48
48
|
'span.type': 'http',
|
|
49
49
|
'http.method': method,
|
|
@@ -133,20 +133,6 @@ function extractSessionDetails (authority, options) {
|
|
|
133
133
|
return { protocol, port, host }
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
function getFormattedHostString (host, port) {
|
|
137
|
-
return [host, port].filter(val => val).join(':')
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function getServiceName (tracer, config, sessionDetails) {
|
|
141
|
-
if (config.splitByDomain) {
|
|
142
|
-
return getFormattedHostString(sessionDetails.host, sessionDetails.port)
|
|
143
|
-
} else if (config.service) {
|
|
144
|
-
return config.service
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return tracer._service
|
|
148
|
-
}
|
|
149
|
-
|
|
150
136
|
function hasAmazonSignature (headers, path) {
|
|
151
137
|
if (headers) {
|
|
152
138
|
headers = Object.keys(headers)
|
|
@@ -18,7 +18,16 @@ class Http2ServerPlugin extends ServerPlugin {
|
|
|
18
18
|
|
|
19
19
|
start ({ req, res }) {
|
|
20
20
|
const store = storage.getStore()
|
|
21
|
-
const span = web.startSpan(
|
|
21
|
+
const span = web.startSpan(
|
|
22
|
+
this.tracer,
|
|
23
|
+
{
|
|
24
|
+
...this.config,
|
|
25
|
+
service: this.config.service || this.serviceName()
|
|
26
|
+
},
|
|
27
|
+
req,
|
|
28
|
+
res,
|
|
29
|
+
this.operationName()
|
|
30
|
+
)
|
|
22
31
|
|
|
23
32
|
span.setTag(COMPONENT, this.constructor.id)
|
|
24
33
|
|
|
@@ -10,7 +10,7 @@ class MemcachedPlugin extends CachePlugin {
|
|
|
10
10
|
const address = getAddress(client, server, query)
|
|
11
11
|
|
|
12
12
|
this.startSpan({
|
|
13
|
-
service: this.serviceName(this.config, this.system),
|
|
13
|
+
service: this.serviceName({ pluginConfig: this.config, system: this.system }),
|
|
14
14
|
resource: query.type,
|
|
15
15
|
type: 'memcached',
|
|
16
16
|
meta: {
|
|
@@ -12,7 +12,7 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
12
12
|
const query = getQuery(ops)
|
|
13
13
|
const resource = truncate(getResource(this, ns, query, name))
|
|
14
14
|
this.startSpan(this.operationName(), {
|
|
15
|
-
service: this.serviceName(this.config),
|
|
15
|
+
service: this.serviceName({ pluginConfig: this.config }),
|
|
16
16
|
resource,
|
|
17
17
|
type: 'mongodb',
|
|
18
18
|
kind: 'client',
|
|
@@ -8,7 +8,7 @@ class MySQLPlugin extends DatabasePlugin {
|
|
|
8
8
|
static get system () { return 'mysql' }
|
|
9
9
|
|
|
10
10
|
start (payload) {
|
|
11
|
-
const service = this.serviceName(this.config, payload.conf, this.system)
|
|
11
|
+
const service = this.serviceName({ pluginConfig: this.config, dbConfig: payload.conf, system: this.system })
|
|
12
12
|
this.startSpan(this.operationName(), {
|
|
13
13
|
service,
|
|
14
14
|
resource: payload.sql,
|
|
@@ -19,11 +19,11 @@ class NextPlugin extends ServerPlugin {
|
|
|
19
19
|
start ({ req, res }) {
|
|
20
20
|
const store = storage.getStore()
|
|
21
21
|
const childOf = store ? store.span : store
|
|
22
|
-
const span = this.tracer.startSpan(
|
|
22
|
+
const span = this.tracer.startSpan(this.operationName(), {
|
|
23
23
|
childOf,
|
|
24
24
|
tags: {
|
|
25
25
|
[COMPONENT]: this.constructor.id,
|
|
26
|
-
'service.name': this.config.service || this.
|
|
26
|
+
'service.name': this.config.service || this.serviceName(),
|
|
27
27
|
'resource.name': req.method,
|
|
28
28
|
'span.type': 'web',
|
|
29
29
|
'span.kind': 'server',
|
|
@@ -10,7 +10,7 @@ class OracledbPlugin extends DatabasePlugin {
|
|
|
10
10
|
static get peerServicePrecursors () { return ['db.instance', 'db.hostname'] }
|
|
11
11
|
|
|
12
12
|
start ({ query, connAttrs }) {
|
|
13
|
-
const service = this.serviceName(this.config, connAttrs)
|
|
13
|
+
const service = this.serviceName({ pluginConfig: this.config, params: connAttrs })
|
|
14
14
|
const url = getUrl(connAttrs.connectString)
|
|
15
15
|
|
|
16
16
|
this.startSpan(this.operationName(), {
|
|
@@ -9,7 +9,7 @@ class PGPlugin extends DatabasePlugin {
|
|
|
9
9
|
static get system () { return 'postgres' }
|
|
10
10
|
|
|
11
11
|
start ({ params = {}, query, processId }) {
|
|
12
|
-
const service = this.serviceName(this.config, params)
|
|
12
|
+
const service = this.serviceName({ pluginConfig: this.config, params })
|
|
13
13
|
const originalStatement = query.text
|
|
14
14
|
|
|
15
15
|
this.startSpan(this.operationName(), {
|
|
@@ -15,7 +15,7 @@ class RedisPlugin extends CachePlugin {
|
|
|
15
15
|
|
|
16
16
|
this.startSpan({
|
|
17
17
|
resource,
|
|
18
|
-
service: this.serviceName(this.config, this.system, connectionName),
|
|
18
|
+
service: this.serviceName({ pluginConfig: this.config, system: this.system, connectionName }),
|
|
19
19
|
type: 'redis',
|
|
20
20
|
meta: {
|
|
21
21
|
'db.type': 'redis',
|
|
@@ -10,7 +10,7 @@ class TediousPlugin extends DatabasePlugin {
|
|
|
10
10
|
|
|
11
11
|
start ({ queryOrProcedure, connectionConfig }) {
|
|
12
12
|
this.startSpan(this.operationName(), {
|
|
13
|
-
service: this.serviceName(this.config, this.system),
|
|
13
|
+
service: this.serviceName({ pluginConfig: this.config, system: this.system }),
|
|
14
14
|
resource: queryOrProcedure,
|
|
15
15
|
type: 'sql',
|
|
16
16
|
kind: 'client',
|
|
@@ -22,17 +22,24 @@ class TracingPlugin extends Plugin {
|
|
|
22
22
|
return store && store.span
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
serviceName (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
serviceName (opts = {}) {
|
|
26
|
+
const {
|
|
27
|
+
type = this.constructor.type,
|
|
28
|
+
id = this.constructor.id,
|
|
29
|
+
kind = this.constructor.kind
|
|
30
|
+
} = opts
|
|
31
|
+
|
|
32
|
+
return Nomenclature.serviceName(type, kind, id, opts)
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
operationName (
|
|
34
|
-
const {
|
|
35
|
-
|
|
35
|
+
operationName (opts = {}) {
|
|
36
|
+
const {
|
|
37
|
+
type = this.constructor.type,
|
|
38
|
+
id = this.constructor.id,
|
|
39
|
+
kind = this.constructor.kind
|
|
40
|
+
} = opts
|
|
41
|
+
|
|
42
|
+
return Nomenclature.opName(type, kind, id, opts)
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
configure (config) {
|
|
@@ -18,20 +18,16 @@ class SchemaManager {
|
|
|
18
18
|
return this.config.spanRemoveIntegrationFromService && this.version === 'v0'
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
opName (type, kind, plugin,
|
|
22
|
-
return this.schema.getOpName(type, kind, plugin,
|
|
21
|
+
opName (type, kind, plugin, opts) {
|
|
22
|
+
return this.schema.getOpName(type, kind, plugin, opts)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
serviceName (type, kind, plugin,
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
serviceName (type, kind, plugin, opts) {
|
|
26
|
+
const schema = this.shouldUseConsistentServiceNaming
|
|
27
|
+
? this.schemas.v1
|
|
28
|
+
: this.schema
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
// We're short-circuiting, so we do not obey custom service functions
|
|
31
|
-
if (typeof pluginConfig.service === 'function') {
|
|
32
|
-
return this.config.service
|
|
33
|
-
}
|
|
34
|
-
return pluginConfig.service || this.config.service
|
|
30
|
+
return schema.getServiceName(type, kind, plugin, { ...opts, tracerService: this.config.service })
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
configure (config = {}) {
|
|
@@ -10,14 +10,14 @@ class SchemaDefinition {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
getOpName (type, kind, plugin,
|
|
13
|
+
getOpName (type, kind, plugin, opts) {
|
|
14
14
|
const item = this.getSchemaItem(type, kind, plugin)
|
|
15
|
-
return item.opName(
|
|
15
|
+
return item.opName(opts)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
getServiceName (type, kind, plugin,
|
|
18
|
+
getServiceName (type, kind, plugin, opts) {
|
|
19
19
|
const item = this.getSchemaItem(type, kind, plugin)
|
|
20
|
-
return item.serviceName(
|
|
20
|
+
return item.serviceName(opts)
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -1,5 +1,23 @@
|
|
|
1
|
-
function identityService (
|
|
2
|
-
return
|
|
1
|
+
function identityService ({ tracerService }) {
|
|
2
|
+
return tracerService
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
function getFormattedHostString ({ host, port }) {
|
|
6
|
+
return [host, port].filter(val => val).join(':')
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function httpPluginClientService ({ tracerService, pluginConfig, sessionDetails }) {
|
|
10
|
+
if (pluginConfig.splitByDomain) {
|
|
11
|
+
return getFormattedHostString(sessionDetails)
|
|
12
|
+
} else if (pluginConfig.service) {
|
|
13
|
+
return pluginConfig.service
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return tracerService
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function awsServiceV0 ({ tracerService, awsService }) {
|
|
20
|
+
return `${tracerService}-aws-${awsService}`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = { identityService, httpPluginClientService, awsServiceV0 }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const { identityService } = require('../util')
|
|
1
|
+
const { identityService, awsServiceV0 } = require('../util')
|
|
2
2
|
|
|
3
|
-
function amqpServiceName (
|
|
4
|
-
return `${
|
|
3
|
+
function amqpServiceName ({ tracerService }) {
|
|
4
|
+
return `${tracerService}-amqp`
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
const messaging = {
|
|
@@ -16,15 +16,23 @@ const messaging = {
|
|
|
16
16
|
},
|
|
17
17
|
'google-cloud-pubsub': {
|
|
18
18
|
opName: () => 'pubsub.request',
|
|
19
|
-
serviceName:
|
|
19
|
+
serviceName: ({ tracerService }) => `${tracerService}-pubsub`
|
|
20
20
|
},
|
|
21
21
|
kafkajs: {
|
|
22
22
|
opName: () => 'kafka.produce',
|
|
23
|
-
serviceName:
|
|
23
|
+
serviceName: ({ tracerService }) => `${tracerService}-kafka`
|
|
24
24
|
},
|
|
25
25
|
rhea: {
|
|
26
26
|
opName: () => 'amqp.send',
|
|
27
|
-
serviceName:
|
|
27
|
+
serviceName: ({ tracerService }) => `${tracerService}-amqp-producer`
|
|
28
|
+
},
|
|
29
|
+
sqs: {
|
|
30
|
+
opName: () => 'aws.request',
|
|
31
|
+
serviceName: awsServiceV0
|
|
32
|
+
},
|
|
33
|
+
sns: {
|
|
34
|
+
opName: () => 'aws.request',
|
|
35
|
+
serviceName: awsServiceV0
|
|
28
36
|
}
|
|
29
37
|
},
|
|
30
38
|
consumer: {
|
|
@@ -42,11 +50,15 @@ const messaging = {
|
|
|
42
50
|
},
|
|
43
51
|
kafkajs: {
|
|
44
52
|
opName: () => 'kafka.consume',
|
|
45
|
-
serviceName:
|
|
53
|
+
serviceName: ({ tracerService }) => `${tracerService}-kafka`
|
|
46
54
|
},
|
|
47
55
|
rhea: {
|
|
48
56
|
opName: () => 'amqp.receive',
|
|
49
57
|
serviceName: identityService
|
|
58
|
+
},
|
|
59
|
+
sqs: {
|
|
60
|
+
opName: () => 'aws.request',
|
|
61
|
+
serviceName: awsServiceV0
|
|
50
62
|
}
|
|
51
63
|
},
|
|
52
64
|
client: {
|
|
@@ -56,7 +68,7 @@ const messaging = {
|
|
|
56
68
|
},
|
|
57
69
|
'google-cloud-pubsub': {
|
|
58
70
|
opName: () => 'pubsub.request',
|
|
59
|
-
serviceName:
|
|
71
|
+
serviceName: ({ tracerService }) => `${tracerService}-pubsub`
|
|
60
72
|
}
|
|
61
73
|
}
|
|
62
74
|
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
function getRedisService (
|
|
2
|
-
if (
|
|
3
|
-
return
|
|
4
|
-
? `${
|
|
1
|
+
function getRedisService (pluginConfig, connectionName) {
|
|
2
|
+
if (pluginConfig.splitByInstance && connectionName) {
|
|
3
|
+
return pluginConfig.service
|
|
4
|
+
? `${pluginConfig.service}-${connectionName}`
|
|
5
5
|
: connectionName
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
return
|
|
8
|
+
return pluginConfig.service
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function fromSystem (
|
|
12
|
-
return system ? `${
|
|
11
|
+
function fromSystem (tracerService, system) {
|
|
12
|
+
return system ? `${tracerService}-${system}` : undefined
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function mysqlServiceName (
|
|
16
|
-
if (typeof
|
|
17
|
-
return
|
|
15
|
+
function mysqlServiceName ({ tracerService, pluginConfig, dbConfig, system }) {
|
|
16
|
+
if (typeof pluginConfig.service === 'function') {
|
|
17
|
+
return pluginConfig.service(dbConfig)
|
|
18
18
|
}
|
|
19
|
-
return
|
|
19
|
+
return pluginConfig.service || fromSystem(tracerService, system)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function withSuffixFunction (suffix) {
|
|
23
|
-
return (
|
|
24
|
-
if (typeof
|
|
25
|
-
return
|
|
23
|
+
return ({ tracerService, pluginConfig, params }) => {
|
|
24
|
+
if (typeof pluginConfig.service === 'function') {
|
|
25
|
+
return pluginConfig.service(params)
|
|
26
26
|
}
|
|
27
|
-
return
|
|
27
|
+
return pluginConfig.service || `${tracerService}-${suffix}`
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const redisConfig = {
|
|
32
32
|
opName: () => 'redis.command',
|
|
33
|
-
serviceName: (
|
|
34
|
-
return getRedisService(
|
|
33
|
+
serviceName: ({ tracerService, pluginConfig, system, connectionName }) => {
|
|
34
|
+
return getRedisService(pluginConfig, connectionName) || fromSystem(tracerService, system)
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -39,11 +39,17 @@ const storage = {
|
|
|
39
39
|
client: {
|
|
40
40
|
'cassandra-driver': {
|
|
41
41
|
opName: () => 'cassandra.query',
|
|
42
|
-
serviceName: (
|
|
42
|
+
serviceName: ({ tracerService, pluginConfig, system }) =>
|
|
43
|
+
pluginConfig.service || fromSystem(tracerService, system)
|
|
44
|
+
},
|
|
45
|
+
couchbase: {
|
|
46
|
+
opName: ({ operation }) => `couchbase.${operation}`,
|
|
47
|
+
serviceName: ({ tracerService, pluginConfig }) => pluginConfig.service || `${tracerService}-couchbase`
|
|
43
48
|
},
|
|
44
49
|
elasticsearch: {
|
|
45
50
|
opName: () => 'elasticsearch.query',
|
|
46
|
-
serviceName: (
|
|
51
|
+
serviceName: ({ tracerService, pluginConfig }) =>
|
|
52
|
+
pluginConfig.service || `${tracerService}-elasticsearch`
|
|
47
53
|
},
|
|
48
54
|
ioredis: redisConfig,
|
|
49
55
|
mariadb: {
|
|
@@ -52,11 +58,13 @@ const storage = {
|
|
|
52
58
|
},
|
|
53
59
|
memcached: {
|
|
54
60
|
opName: () => 'memcached.command',
|
|
55
|
-
serviceName: (
|
|
61
|
+
serviceName: ({ tracerService, pluginConfig, system }) =>
|
|
62
|
+
pluginConfig.service || fromSystem(tracerService, system)
|
|
56
63
|
},
|
|
57
64
|
'mongodb-core': {
|
|
58
65
|
opName: () => 'mongodb.query',
|
|
59
|
-
serviceName: (
|
|
66
|
+
serviceName: ({ tracerService, pluginConfig }) =>
|
|
67
|
+
pluginConfig.service || `${tracerService}-mongodb`
|
|
60
68
|
},
|
|
61
69
|
mysql: {
|
|
62
70
|
opName: () => 'mysql.query',
|
|
@@ -68,7 +76,8 @@ const storage = {
|
|
|
68
76
|
},
|
|
69
77
|
opensearch: {
|
|
70
78
|
opName: () => 'opensearch.query',
|
|
71
|
-
serviceName: (
|
|
79
|
+
serviceName: ({ tracerService, pluginConfig }) =>
|
|
80
|
+
pluginConfig.service || `${tracerService}-opensearch`
|
|
72
81
|
},
|
|
73
82
|
oracledb: {
|
|
74
83
|
opName: () => 'oracle.query',
|
|
@@ -81,7 +90,8 @@ const storage = {
|
|
|
81
90
|
redis: redisConfig,
|
|
82
91
|
tedious: {
|
|
83
92
|
opName: () => 'tedious.request',
|
|
84
|
-
serviceName: (
|
|
93
|
+
serviceName: ({ tracerService, pluginConfig, system }) =>
|
|
94
|
+
pluginConfig.service || fromSystem(tracerService, system)
|
|
85
95
|
}
|
|
86
96
|
}
|
|
87
97
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { identityService } = require('../util')
|
|
1
|
+
const { identityService, httpPluginClientService, awsServiceV0 } = require('../util')
|
|
2
2
|
const { DD_MAJOR } = require('../../../../../../version')
|
|
3
3
|
|
|
4
4
|
const web = {
|
|
@@ -10,6 +10,26 @@ const web = {
|
|
|
10
10
|
moleculer: {
|
|
11
11
|
opName: () => 'moleculer.call',
|
|
12
12
|
serviceName: identityService
|
|
13
|
+
},
|
|
14
|
+
http: {
|
|
15
|
+
opName: () => 'http.request',
|
|
16
|
+
serviceName: httpPluginClientService
|
|
17
|
+
},
|
|
18
|
+
fetch: {
|
|
19
|
+
opName: () => 'http.request',
|
|
20
|
+
serviceName: httpPluginClientService
|
|
21
|
+
},
|
|
22
|
+
http2: {
|
|
23
|
+
opName: () => 'http.request',
|
|
24
|
+
serviceName: httpPluginClientService
|
|
25
|
+
},
|
|
26
|
+
aws: {
|
|
27
|
+
opName: () => 'aws.request',
|
|
28
|
+
serviceName: awsServiceV0
|
|
29
|
+
},
|
|
30
|
+
lambda: {
|
|
31
|
+
opName: () => 'aws.request',
|
|
32
|
+
serviceName: awsServiceV0
|
|
13
33
|
}
|
|
14
34
|
},
|
|
15
35
|
server: {
|
|
@@ -20,6 +40,18 @@ const web = {
|
|
|
20
40
|
moleculer: {
|
|
21
41
|
opName: () => 'moleculer.action',
|
|
22
42
|
serviceName: identityService
|
|
43
|
+
},
|
|
44
|
+
http: {
|
|
45
|
+
opName: () => 'web.request',
|
|
46
|
+
serviceName: identityService
|
|
47
|
+
},
|
|
48
|
+
http2: {
|
|
49
|
+
opName: () => 'web.request',
|
|
50
|
+
serviceName: identityService
|
|
51
|
+
},
|
|
52
|
+
next: {
|
|
53
|
+
opName: () => 'next.request',
|
|
54
|
+
serviceName: identityService
|
|
23
55
|
}
|
|
24
56
|
}
|
|
25
57
|
}
|
|
@@ -22,7 +22,15 @@ const messaging = {
|
|
|
22
22
|
opName: () => 'kafka.send',
|
|
23
23
|
serviceName: identityService
|
|
24
24
|
},
|
|
25
|
-
rhea: amqpOutbound
|
|
25
|
+
rhea: amqpOutbound,
|
|
26
|
+
sqs: {
|
|
27
|
+
opName: () => 'aws.sqs.send',
|
|
28
|
+
serviceName: identityService
|
|
29
|
+
},
|
|
30
|
+
sns: {
|
|
31
|
+
opName: () => 'aws.sns.send',
|
|
32
|
+
serviceName: identityService
|
|
33
|
+
}
|
|
26
34
|
},
|
|
27
35
|
consumer: {
|
|
28
36
|
amqplib: amqpInbound,
|
|
@@ -35,7 +43,11 @@ const messaging = {
|
|
|
35
43
|
opName: () => 'kafka.process',
|
|
36
44
|
serviceName: identityService
|
|
37
45
|
},
|
|
38
|
-
rhea: amqpInbound
|
|
46
|
+
rhea: amqpInbound,
|
|
47
|
+
sqs: {
|
|
48
|
+
opName: () => 'aws.sqs.process',
|
|
49
|
+
serviceName: identityService
|
|
50
|
+
}
|
|
39
51
|
},
|
|
40
52
|
client: {
|
|
41
53
|
amqplib: {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const { identityService } = require('../util')
|
|
2
1
|
|
|
3
|
-
function configWithFallback (
|
|
4
|
-
return
|
|
2
|
+
function configWithFallback ({ tracerService, pluginConfig }) {
|
|
3
|
+
return pluginConfig.service || tracerService
|
|
5
4
|
}
|
|
6
5
|
|
|
7
6
|
const redisNaming = {
|
|
@@ -11,14 +10,14 @@ const redisNaming = {
|
|
|
11
10
|
|
|
12
11
|
const mySQLNaming = {
|
|
13
12
|
opName: () => 'mysql.query',
|
|
14
|
-
serviceName:
|
|
13
|
+
serviceName: withFunction
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
function withFunction (
|
|
18
|
-
if (typeof
|
|
19
|
-
return
|
|
16
|
+
function withFunction ({ tracerService, pluginConfig, params }) {
|
|
17
|
+
if (typeof pluginConfig.service === 'function') {
|
|
18
|
+
return pluginConfig.service(params)
|
|
20
19
|
}
|
|
21
|
-
return configWithFallback(
|
|
20
|
+
return configWithFallback({ tracerService, pluginConfig })
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
const storage = {
|
|
@@ -27,6 +26,10 @@ const storage = {
|
|
|
27
26
|
opName: () => 'cassandra.query',
|
|
28
27
|
serviceName: configWithFallback
|
|
29
28
|
},
|
|
29
|
+
couchbase: {
|
|
30
|
+
opName: () => 'couchbase.query',
|
|
31
|
+
serviceName: configWithFallback
|
|
32
|
+
},
|
|
30
33
|
elasticsearch: {
|
|
31
34
|
opName: () => 'elasticsearch.query',
|
|
32
35
|
serviceName: configWithFallback
|
|
@@ -34,7 +37,7 @@ const storage = {
|
|
|
34
37
|
ioredis: redisNaming,
|
|
35
38
|
mariadb: {
|
|
36
39
|
opName: () => 'mariadb.query',
|
|
37
|
-
serviceName:
|
|
40
|
+
serviceName: withFunction
|
|
38
41
|
},
|
|
39
42
|
memcached: {
|
|
40
43
|
opName: () => 'memcached.command',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { identityService } = require('../util')
|
|
1
|
+
const { identityService, httpPluginClientService } = require('../util')
|
|
2
2
|
|
|
3
3
|
const web = {
|
|
4
4
|
client: {
|
|
@@ -9,6 +9,26 @@ const web = {
|
|
|
9
9
|
moleculer: {
|
|
10
10
|
opName: () => 'moleculer.client.request',
|
|
11
11
|
serviceName: identityService
|
|
12
|
+
},
|
|
13
|
+
http: {
|
|
14
|
+
opName: () => 'http.client.request',
|
|
15
|
+
serviceName: httpPluginClientService
|
|
16
|
+
},
|
|
17
|
+
fetch: {
|
|
18
|
+
opName: () => 'http.client.request',
|
|
19
|
+
serviceName: httpPluginClientService
|
|
20
|
+
},
|
|
21
|
+
http2: {
|
|
22
|
+
opName: () => 'http.client.request',
|
|
23
|
+
serviceName: httpPluginClientService
|
|
24
|
+
},
|
|
25
|
+
aws: {
|
|
26
|
+
opName: ({ awsService }) => `aws.${awsService}.request`,
|
|
27
|
+
serviceName: identityService
|
|
28
|
+
},
|
|
29
|
+
lambda: {
|
|
30
|
+
opName: () => 'aws.lambda.invoke',
|
|
31
|
+
serviceName: identityService
|
|
12
32
|
}
|
|
13
33
|
},
|
|
14
34
|
server: {
|
|
@@ -19,6 +39,18 @@ const web = {
|
|
|
19
39
|
moleculer: {
|
|
20
40
|
opName: () => 'moleculer.server.request',
|
|
21
41
|
serviceName: identityService
|
|
42
|
+
},
|
|
43
|
+
http: {
|
|
44
|
+
opName: () => 'http.server.request',
|
|
45
|
+
serviceName: identityService
|
|
46
|
+
},
|
|
47
|
+
http2: {
|
|
48
|
+
opName: () => 'http.server.request',
|
|
49
|
+
serviceName: identityService
|
|
50
|
+
},
|
|
51
|
+
next: {
|
|
52
|
+
opName: () => 'http.server.request',
|
|
53
|
+
serviceName: identityService
|
|
22
54
|
}
|
|
23
55
|
}
|
|
24
56
|
}
|