newrelic 11.18.0 → 11.19.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/NEWS.md +57 -33
- package/README.md +2 -5
- package/THIRD_PARTY_NOTICES.md +6 -92
- package/lib/feature_flags.js +2 -1
- package/lib/instrumentation/amqplib/amqplib.js +1 -1
- package/lib/instrumentation/kafkajs/consumer.js +132 -0
- package/lib/instrumentation/kafkajs/index.js +34 -0
- package/lib/instrumentation/kafkajs/producer.js +74 -0
- package/lib/instrumentation/kafkajs.js +7 -0
- package/lib/instrumentations.js +1 -0
- package/lib/metrics/names.js +40 -35
- package/lib/shim/message-shim/index.js +10 -0
- package/lib/shim/message-shim/subscribe-consume.js +13 -1
- package/lib/shim/specs/message-subscribe.js +25 -0
- package/lib/shim/specs/message.js +23 -0
- package/lib/symbols.js +1 -0
- package/lib/transaction/tracecontext.js +8 -1
- package/package.json +5 -7
package/NEWS.md
CHANGED
|
@@ -1,36 +1,60 @@
|
|
|
1
|
-
### v11.
|
|
2
|
-
|
|
3
|
-
#### Features
|
|
4
|
-
|
|
5
|
-
* Added
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* Updated
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
####
|
|
28
|
-
|
|
29
|
-
*
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
### v11.19.0 (2024-06-06)
|
|
2
|
+
|
|
3
|
+
#### Features
|
|
4
|
+
|
|
5
|
+
* Added instrumentation for `kafkajs` (enabled through a [feature flag](https://github.com/newrelic/node-newrelic/blob/f003ee78204149c7905cb17cb4f084aeac1ba751/documentation/feature-flags.md#kakfajs_instrumentation)) ([#2237](https://github.com/newrelic/node-newrelic/pull/2237)) ([#2244](https://github.com/newrelic/node-newrelic/pull/2244)) ([#2236](https://github.com/newrelic/node-newrelic/pull/2236)) ([#2236](https://github.com/newrelic/node-newrelic/pull/2236)) ([#2251](https://github.com/newrelic/node-newrelic/pull/2251))
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
#### Miscellaneous chores
|
|
9
|
+
|
|
10
|
+
* Added kafkajs instrumentation and versioned tests skeleton ([#2224](https://github.com/newrelic/node-newrelic/pull/2224)) ([fc13916](https://github.com/newrelic/node-newrelic/commit/fc13916b94b813d028270dfccfed292af91875fb))
|
|
11
|
+
* Added kafkajs to compatibility list ([#2254](https://github.com/newrelic/node-newrelic/pull/2254)) ([f003ee7](https://github.com/newrelic/node-newrelic/commit/f003ee78204149c7905cb17cb4f084aeac1ba751))
|
|
12
|
+
* Implemented DT header injection for message specs ([#2250](https://github.com/newrelic/node-newrelic/pull/2250)) ([3e6bc6d](https://github.com/newrelic/node-newrelic/commit/3e6bc6d5485fd6e236c6f0a58922d698c00c920f))
|
|
13
|
+
* Removed targets for kafka versioned tests ([#2235](https://github.com/newrelic/node-newrelic/pull/2235)) ([838bab2](https://github.com/newrelic/node-newrelic/commit/838bab2ff425f5acb111a19f397760ed01c1bdde))
|
|
14
|
+
* Updated flaky when test ([#2241](https://github.com/newrelic/node-newrelic/pull/2241)) ([4079a0a](https://github.com/newrelic/node-newrelic/commit/4079a0ae38e584181eec284963560341941c5dd3))
|
|
15
|
+
* Updated readme to remove no longer relevant information ([#2240](https://github.com/newrelic/node-newrelic/pull/2240)) ([01fb53c](https://github.com/newrelic/node-newrelic/commit/01fb53cfe3c7df63bc2ef03d85991edb159569a6))
|
|
16
|
+
* Updated versioned tests due to update in @newrelic/security-agent V1.3.0 ([#2239](https://github.com/newrelic/node-newrelic/pull/2239)) ([982276c](https://github.com/newrelic/node-newrelic/commit/982276cd4fca57bbf64219e846a0a93cdfb3400b))
|
|
17
|
+
|
|
18
|
+
#### Tests
|
|
19
|
+
|
|
20
|
+
* Migrated `memcached` tests to versioned tests ([#2231](https://github.com/newrelic/node-newrelic/pull/2231)) ([0b3a928](https://github.com/newrelic/node-newrelic/commit/0b3a9284dc5bdc7755d176739186ea3c15cde23e))
|
|
21
|
+
* Ported `when` and `q` integration tests to versioned tests ([#2233](https://github.com/newrelic/node-newrelic/pull/2233)) ([9a4dddc](https://github.com/newrelic/node-newrelic/commit/9a4dddc64ce69ea63866d1ebaf6b86b9234c99ea))
|
|
22
|
+
* Updated ioredis tests to assert the host metric getting created on ioredis calls ([#2230](https://github.com/newrelic/node-newrelic/pull/2230)) ([89df06a](https://github.com/newrelic/node-newrelic/commit/89df06a6b885f8789e68d2b8047bada61db62e24))
|
|
23
|
+
* Updated unit tests that were missing constructing specs at instrumentation source ([#2252](https://github.com/newrelic/node-newrelic/pull/2252)) ([54ab238](https://github.com/newrelic/node-newrelic/commit/54ab238436717b5a248f40374e174f1b19217a0c))
|
|
24
|
+
|
|
25
|
+
### v11.18.0 (2024-05-29)
|
|
26
|
+
|
|
27
|
+
#### Features
|
|
28
|
+
|
|
29
|
+
* Added support for redis v4 legacyMode `client.v4.<command>` ([#2200](https://github.com/newrelic/node-newrelic/pull/2200)) ([b2284c5](https://github.com/newrelic/node-newrelic/commit/b2284c58eb798ab00a141ce08f4072584795c728))
|
|
30
|
+
|
|
31
|
+
#### Code refactoring
|
|
32
|
+
|
|
33
|
+
* Updated `shim.recordConsume` to use `shim.record` and added ability to invoke an after hook with callback args ([#2207](https://github.com/newrelic/node-newrelic/pull/2207)) ([4f48fc3](https://github.com/newrelic/node-newrelic/commit/4f48fc3bbd5afce4954019620b112f600b2dfb53))
|
|
34
|
+
|
|
35
|
+
#### Documentation
|
|
36
|
+
|
|
37
|
+
* Updated compatibility report ([#2223](https://github.com/newrelic/node-newrelic/pull/2223)) ([a256ca0](https://github.com/newrelic/node-newrelic/commit/a256ca0f2060efe576018527d37718a041ffc925))
|
|
38
|
+
|
|
39
|
+
#### Miscellaneous chores
|
|
40
|
+
|
|
41
|
+
* Removed outdated Slack reference ([#2198](https://github.com/newrelic/node-newrelic/pull/2198)) ([8110d42](https://github.com/newrelic/node-newrelic/commit/8110d426f402659d44bf786fec0503ca2413ee6b))
|
|
42
|
+
* Removed package-lock.json ([#2208](https://github.com/newrelic/node-newrelic/pull/2208)) ([b267695](https://github.com/newrelic/node-newrelic/commit/b26769502b4cb38f9133f76f427ee96ce718c15b))
|
|
43
|
+
* Removed unused express5 feature flag ([#2197](https://github.com/newrelic/node-newrelic/pull/2197)) ([366504b](https://github.com/newrelic/node-newrelic/commit/366504ba1e3bfed477a37be5d61f4e30e46b690d))
|
|
44
|
+
|
|
45
|
+
#### Tests
|
|
46
|
+
|
|
47
|
+
* Updated langchain versioned tests to separate the vectorstore and other tests. This is to avoid peer resolution of `@langchain/community` package that is being used to test the elasticsearch vectorstore ([#2216](https://github.com/newrelic/node-newrelic/pull/2216)) ([e768955](https://github.com/newrelic/node-newrelic/commit/e7689554aec2a038d5b80c54d4b6b603075856ac))
|
|
48
|
+
* Fixed aws-sdk-v3 bedrock tests ([#2211](https://github.com/newrelic/node-newrelic/pull/2211)) ([050469e](https://github.com/newrelic/node-newrelic/commit/050469ecc59ccc9ba6a6e78527ac392f262ff939))
|
|
49
|
+
* Fixed aws-sdk-v3 bedrock tests (again) ([#2212](https://github.com/newrelic/node-newrelic/pull/2212)) ([330cc4b](https://github.com/newrelic/node-newrelic/commit/330cc4b6ff8e3777b1dfa0fda7f5b4c5b20005af))
|
|
50
|
+
|
|
51
|
+
#### Continuous integration
|
|
52
|
+
|
|
53
|
+
* Updated the langchain vectorstore test to reference the correct version of `@langchain/core` getting tested ([#2202](https://github.com/newrelic/node-newrelic/pull/2202)) ([ed81852](https://github.com/newrelic/node-newrelic/commit/ed81852a4b3c582a54c0d274ba9d5887041ebeef))
|
|
54
|
+
* Added updating of docs site with compatibility table ([#2205](https://github.com/newrelic/node-newrelic/pull/2205)) ([c28a938](https://github.com/newrelic/node-newrelic/commit/c28a9387f68feb8fa59d4134828662b3babeb9d0))
|
|
55
|
+
* Fixed CI jobs ([#2215](https://github.com/newrelic/node-newrelic/pull/2215)) ([8b030fb](https://github.com/newrelic/node-newrelic/commit/8b030fbf479cd348e9b75544bc753c1d618bfca7))
|
|
56
|
+
* Fixed should-run CI step ([#2214](https://github.com/newrelic/node-newrelic/pull/2214)) ([d0a481d](https://github.com/newrelic/node-newrelic/commit/d0a481d4b58706c4793fa12fa7706091eaffa0a4))
|
|
57
|
+
|
|
34
58
|
### v11.17.0 (2024-05-15)
|
|
35
59
|
|
|
36
60
|
#### Features
|
package/README.md
CHANGED
|
@@ -118,16 +118,13 @@ For more information on getting started, [check the Node.js docs](https://docs.n
|
|
|
118
118
|
|
|
119
119
|
### External Modules
|
|
120
120
|
|
|
121
|
-
There are
|
|
121
|
+
There are modules that can be installed and configured to accompany the Node.js agent:
|
|
122
122
|
|
|
123
123
|
* [@newrelic/apollo-server-plugin](https://github.com/newrelic/newrelic-node-apollo-server-plugin): New Relic's official Apollo Server plugin for use with the Node.js agent.
|
|
124
124
|
* [@newrelic/next](https://github.com/newrelic/newrelic-node-nextjs): Provides instrumentation for the [Next.js](https://github.com/vercel/next.js/) npm package.
|
|
125
125
|
|
|
126
|
-
There are
|
|
126
|
+
There are modules included within the Node.js agent to add more instrumentation for 3rd party modules:
|
|
127
127
|
|
|
128
|
-
* [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk): Provides instrumentation for the [AWS SDK](https://www.npmjs.com/package/aws-sdk) npm package.
|
|
129
|
-
* [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa): Provides instrumentation for [koa](https://koajs.com/), [koa-router](https://github.com/ZijianHe/koa-router), [@koa/router](https://github.com/koajs/router), and [koa-route](https://github.com/koajs/route) npm packages.
|
|
130
|
-
* [@newrelic/superagent](https://github.com/newrelic/node-newrelic-superagent): Provides instrumentation for [superagent](https://github.com/visionmedia/superagent) npm package.
|
|
131
128
|
* [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics): Provides hooks into the native v8 layer of Node.js to provide metrics to the Node.js agent.
|
|
132
129
|
|
|
133
130
|
## Usage
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -65,11 +65,9 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
65
65
|
* [koa](#koa)
|
|
66
66
|
* [lint-staged](#lint-staged)
|
|
67
67
|
* [lockfile-lint](#lockfile-lint)
|
|
68
|
-
* [memcached](#memcached)
|
|
69
68
|
* [nock](#nock)
|
|
70
69
|
* [proxy](#proxy)
|
|
71
70
|
* [proxyquire](#proxyquire)
|
|
72
|
-
* [q](#q)
|
|
73
71
|
* [rfdc](#rfdc)
|
|
74
72
|
* [rimraf](#rimraf)
|
|
75
73
|
* [should](#should)
|
|
@@ -77,7 +75,6 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
77
75
|
* [superagent](#superagent)
|
|
78
76
|
* [tap](#tap)
|
|
79
77
|
* [temp](#temp)
|
|
80
|
-
* [when](#when)
|
|
81
78
|
|
|
82
79
|
**[optionalDependencies](#optionalDependencies)**
|
|
83
80
|
|
|
@@ -94,7 +91,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
94
91
|
|
|
95
92
|
### @grpc/grpc-js
|
|
96
93
|
|
|
97
|
-
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.10.
|
|
94
|
+
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.10.8](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.10.8)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.10.8/LICENSE):
|
|
98
95
|
|
|
99
96
|
```
|
|
100
97
|
Apache License
|
|
@@ -542,7 +539,7 @@ SOFTWARE.
|
|
|
542
539
|
|
|
543
540
|
### @newrelic/security-agent
|
|
544
541
|
|
|
545
|
-
This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.
|
|
542
|
+
This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.3.0](https://github.com/newrelic/csec-node-agent/tree/v1.3.0)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v1.3.0/LICENSE):
|
|
546
543
|
|
|
547
544
|
```
|
|
548
545
|
## New Relic Software License v1.0
|
|
@@ -889,7 +886,7 @@ SOFTWARE.
|
|
|
889
886
|
|
|
890
887
|
### @aws-sdk/client-s3
|
|
891
888
|
|
|
892
|
-
This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.
|
|
889
|
+
This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.587.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.587.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.587.0/LICENSE):
|
|
893
890
|
|
|
894
891
|
```
|
|
895
892
|
Apache License
|
|
@@ -1098,7 +1095,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co
|
|
|
1098
1095
|
|
|
1099
1096
|
### @aws-sdk/s3-request-presigner
|
|
1100
1097
|
|
|
1101
|
-
This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.
|
|
1098
|
+
This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.587.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.587.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.587.0/LICENSE):
|
|
1102
1099
|
|
|
1103
1100
|
```
|
|
1104
1101
|
Apache License
|
|
@@ -2496,7 +2493,7 @@ THE SOFTWARE.
|
|
|
2496
2493
|
|
|
2497
2494
|
### aws-sdk
|
|
2498
2495
|
|
|
2499
|
-
This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.
|
|
2496
|
+
This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1631.0](https://github.com/aws/aws-sdk-js/tree/v2.1631.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1631.0/LICENSE.txt):
|
|
2500
2497
|
|
|
2501
2498
|
```
|
|
2502
2499
|
|
|
@@ -2895,7 +2892,7 @@ THE SOFTWARE.
|
|
|
2895
2892
|
|
|
2896
2893
|
### eslint-plugin-jsdoc
|
|
2897
2894
|
|
|
2898
|
-
This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.2.
|
|
2895
|
+
This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.2.7](https://github.com/gajus/eslint-plugin-jsdoc/tree/v48.2.7)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v48.2.7/LICENSE):
|
|
2899
2896
|
|
|
2900
2897
|
```
|
|
2901
2898
|
Copyright (c) 2018, Gajus Kuizinas (http://gajus.com/)
|
|
@@ -3673,32 +3670,6 @@ This product includes source derived from [lockfile-lint](https://github.com/lir
|
|
|
3673
3670
|
limitations under the License.
|
|
3674
3671
|
```
|
|
3675
3672
|
|
|
3676
|
-
### memcached
|
|
3677
|
-
|
|
3678
|
-
This product includes source derived from [memcached](https://github.com/3rd-Eden/node-memcached) ([v2.2.2](https://github.com/3rd-Eden/node-memcached/tree/v2.2.2)), distributed under the [MIT License](https://github.com/3rd-Eden/node-memcached/blob/v2.2.2/LICENSE):
|
|
3679
|
-
|
|
3680
|
-
```
|
|
3681
|
-
Copyright (c) 2010 Arnout Kazemier,3rd-Eden
|
|
3682
|
-
|
|
3683
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
3684
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
3685
|
-
in the Software without restriction, including without limitation the rights
|
|
3686
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
3687
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
3688
|
-
furnished to do so, subject to the following conditions:
|
|
3689
|
-
|
|
3690
|
-
The above copyright notice and this permission notice shall be included in
|
|
3691
|
-
all copies or substantial portions of the Software.
|
|
3692
|
-
|
|
3693
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
3694
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
3695
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
3696
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
3697
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
3698
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
3699
|
-
THE SOFTWARE.
|
|
3700
|
-
```
|
|
3701
|
-
|
|
3702
3673
|
### nock
|
|
3703
3674
|
|
|
3704
3675
|
This product includes source derived from [nock](https://github.com/nock/nock) ([v11.8.0](https://github.com/nock/nock/tree/v11.8.0)), distributed under the [MIT License](https://github.com/nock/nock/blob/v11.8.0/LICENSE):
|
|
@@ -3775,32 +3746,6 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|
|
3775
3746
|
|
|
3776
3747
|
```
|
|
3777
3748
|
|
|
3778
|
-
### q
|
|
3779
|
-
|
|
3780
|
-
This product includes source derived from [q](https://github.com/kriskowal/q) ([v1.5.1](https://github.com/kriskowal/q/tree/v1.5.1)), distributed under the [MIT License](https://github.com/kriskowal/q/blob/v1.5.1/LICENSE):
|
|
3781
|
-
|
|
3782
|
-
```
|
|
3783
|
-
Copyright 2009–2017 Kristopher Michael Kowal. All rights reserved.
|
|
3784
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
3785
|
-
of this software and associated documentation files (the "Software"), to
|
|
3786
|
-
deal in the Software without restriction, including without limitation the
|
|
3787
|
-
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
3788
|
-
sell copies of the Software, and to permit persons to whom the Software is
|
|
3789
|
-
furnished to do so, subject to the following conditions:
|
|
3790
|
-
|
|
3791
|
-
The above copyright notice and this permission notice shall be included in
|
|
3792
|
-
all copies or substantial portions of the Software.
|
|
3793
|
-
|
|
3794
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
3795
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
3796
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
3797
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
3798
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
3799
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
3800
|
-
IN THE SOFTWARE.
|
|
3801
|
-
|
|
3802
|
-
```
|
|
3803
|
-
|
|
3804
3749
|
### rfdc
|
|
3805
3750
|
|
|
3806
3751
|
This product includes source derived from [rfdc](https://github.com/davidmarkclements/rfdc) ([v1.3.1](https://github.com/davidmarkclements/rfdc/tree/v1.3.1)), distributed under the [MIT License](https://github.com/davidmarkclements/rfdc/blob/v1.3.1/LICENSE):
|
|
@@ -3991,37 +3936,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
3991
3936
|
|
|
3992
3937
|
```
|
|
3993
3938
|
|
|
3994
|
-
### when
|
|
3995
|
-
|
|
3996
|
-
This product includes source derived from [when](https://github.com/cujojs/when) ([v3.7.8](https://github.com/cujojs/when/tree/v3.7.8)), distributed under the [MIT License](https://github.com/cujojs/when/blob/v3.7.8/LICENSE.txt):
|
|
3997
|
-
|
|
3998
|
-
```
|
|
3999
|
-
Open Source Initiative OSI - The MIT License
|
|
4000
|
-
|
|
4001
|
-
http://www.opensource.org/licenses/mit-license.php
|
|
4002
|
-
|
|
4003
|
-
Copyright (c) 2011 Brian Cavalier
|
|
4004
|
-
|
|
4005
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
4006
|
-
a copy of this software and associated documentation files (the
|
|
4007
|
-
"Software"), to deal in the Software without restriction, including
|
|
4008
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
4009
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
4010
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
4011
|
-
the following conditions:
|
|
4012
|
-
|
|
4013
|
-
The above copyright notice and this permission notice shall be
|
|
4014
|
-
included in all copies or substantial portions of the Software.
|
|
4015
|
-
|
|
4016
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
4017
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
4018
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
4019
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
4020
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
4021
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
4022
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
4023
|
-
```
|
|
4024
|
-
|
|
4025
3939
|
|
|
4026
3940
|
## optionalDependencies
|
|
4027
3941
|
|
package/lib/feature_flags.js
CHANGED
|
@@ -15,7 +15,8 @@ exports.prerelease = {
|
|
|
15
15
|
reverse_naming_rules: false,
|
|
16
16
|
undici_async_tracking: true,
|
|
17
17
|
unresolved_promise_cleanup: true,
|
|
18
|
-
legacy_context_manager: false
|
|
18
|
+
legacy_context_manager: false,
|
|
19
|
+
kafkajs_instrumentation: false
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
// flags that are no longer used for released features
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
const { kafkaCtx } = require('../../symbols')
|
|
8
|
+
const { MessageSpec, MessageSubscribeSpec, RecorderSpec } = require('../../shim/specs')
|
|
9
|
+
const { DESTINATIONS } = require('../../config/attribute-filter')
|
|
10
|
+
const CONSUMER_METHODS = [
|
|
11
|
+
'connect',
|
|
12
|
+
'disconnect',
|
|
13
|
+
'subscribe',
|
|
14
|
+
'stop',
|
|
15
|
+
'commitOffsets',
|
|
16
|
+
'seek',
|
|
17
|
+
'pause',
|
|
18
|
+
'resume'
|
|
19
|
+
]
|
|
20
|
+
const SEGMENT_PREFIX = 'kafkajs.Kafka.consumer#'
|
|
21
|
+
|
|
22
|
+
module.exports = function instrumentConsumer({ shim, kafkajs, recordMethodMetric }) {
|
|
23
|
+
const { agent } = shim
|
|
24
|
+
shim.wrap(kafkajs.Kafka.prototype, 'consumer', function wrapConsumer(shim, orig) {
|
|
25
|
+
return function wrappedConsumer() {
|
|
26
|
+
const args = shim.argsToArray.apply(shim, arguments)
|
|
27
|
+
const consumer = orig.apply(this, args)
|
|
28
|
+
consumer.on(consumer.events.REQUEST, function listener(data) {
|
|
29
|
+
// storing broker for when we add `host`, `port` to messaging spans
|
|
30
|
+
consumer[kafkaCtx] = {
|
|
31
|
+
clientId: data?.payload?.clientId,
|
|
32
|
+
broker: data?.payload.broker
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
shim.record(consumer, CONSUMER_METHODS, function wrapper(shim, fn, name) {
|
|
36
|
+
return new RecorderSpec({
|
|
37
|
+
name: `${SEGMENT_PREFIX}${name}`,
|
|
38
|
+
promise: true
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
shim.recordSubscribedConsume(
|
|
42
|
+
consumer,
|
|
43
|
+
'run',
|
|
44
|
+
new MessageSubscribeSpec({
|
|
45
|
+
name: `${SEGMENT_PREFIX}#run`,
|
|
46
|
+
destinationType: shim.TOPIC,
|
|
47
|
+
promise: true,
|
|
48
|
+
consumer: shim.FIRST,
|
|
49
|
+
functions: ['eachMessage'],
|
|
50
|
+
messageHandler: handler({ consumer, recordMethodMetric })
|
|
51
|
+
})
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
shim.wrap(consumer, 'run', function wrapRun(shim, fn) {
|
|
55
|
+
return function wrappedRun() {
|
|
56
|
+
const runArgs = shim.argsToArray.apply(shim, arguments)
|
|
57
|
+
if (runArgs?.[0]?.eachBatch) {
|
|
58
|
+
runArgs[0].eachBatch = shim.wrap(
|
|
59
|
+
runArgs[0].eachBatch,
|
|
60
|
+
function wrapEachBatch(shim, eachBatch) {
|
|
61
|
+
return function wrappedEachBatch() {
|
|
62
|
+
recordMethodMetric({ agent, name: 'eachBatch' })
|
|
63
|
+
return eachBatch.apply(this, arguments)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
return fn.apply(this, runArgs)
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
return consumer
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Wrapped of message handler that passes in consumer and recordMethodMetric.
|
|
78
|
+
* We do not want to bind this as this gets called with the appropriate binding
|
|
79
|
+
* in message-shim
|
|
80
|
+
*
|
|
81
|
+
* @param {object} params to function
|
|
82
|
+
* @param {object} params.consumer consumer being instrumented
|
|
83
|
+
* @param {function} params.recordMethodMetric helper method for logging tracking metrics
|
|
84
|
+
* @returns {function} message handler for setting metrics and spec for the consumer transaction
|
|
85
|
+
*/
|
|
86
|
+
function handler({ consumer, recordMethodMetric }) {
|
|
87
|
+
/**
|
|
88
|
+
* Message handler that extracts the topic and headers from message being consumed.
|
|
89
|
+
*
|
|
90
|
+
* This also sets some metrics for byte length of message, and number of messages.
|
|
91
|
+
* Lastly, adds tx attributes for byteCount and clientId
|
|
92
|
+
*
|
|
93
|
+
* @param {MessageShim} shim instance of shim
|
|
94
|
+
* @param {Array} args arguments passed to the `eachMessage` function of the `consumer.run`
|
|
95
|
+
* @returns {MessageSpec} spec for message handling
|
|
96
|
+
*/
|
|
97
|
+
return function messageHandler(shim, args) {
|
|
98
|
+
recordMethodMetric({ agent: shim.agent, name: 'eachMessage' })
|
|
99
|
+
const [data] = args
|
|
100
|
+
const { topic } = data
|
|
101
|
+
const segment = shim.getActiveSegment()
|
|
102
|
+
|
|
103
|
+
if (segment?.transaction) {
|
|
104
|
+
const tx = segment.transaction
|
|
105
|
+
const byteLength = data?.message.value?.byteLength
|
|
106
|
+
const metricPrefix = `Message/Kafka/Topic/Named/${topic}/Received`
|
|
107
|
+
// This will always be 1
|
|
108
|
+
tx.metrics.getOrCreateMetric(`${metricPrefix}/Messages`).recordValue(1)
|
|
109
|
+
if (byteLength) {
|
|
110
|
+
tx.metrics.measureBytes(`${metricPrefix}/Bytes`, byteLength)
|
|
111
|
+
tx.trace.attributes.addAttribute(
|
|
112
|
+
DESTINATIONS.TRANS_SCOPE,
|
|
113
|
+
'kafka.consume.byteCount',
|
|
114
|
+
byteLength
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
if (consumer?.[kafkaCtx]) {
|
|
118
|
+
tx.trace.attributes.addAttribute(
|
|
119
|
+
DESTINATIONS.TRANS_EVENT,
|
|
120
|
+
'kafka.consume.client_id',
|
|
121
|
+
consumer[kafkaCtx].clientId
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return new MessageSpec({
|
|
127
|
+
destinationType: `Topic/Consume`,
|
|
128
|
+
destinationName: data?.topic,
|
|
129
|
+
headers: data?.message?.headers
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const instrumentProducer = require('./producer')
|
|
9
|
+
const instrumentConsumer = require('./consumer')
|
|
10
|
+
const { KAFKA } = require('../../metrics/names')
|
|
11
|
+
|
|
12
|
+
module.exports = function initialize(agent, kafkajs, _moduleName, shim) {
|
|
13
|
+
if (agent.config.feature_flag.kafkajs_instrumentation === false) {
|
|
14
|
+
shim.logger.debug(
|
|
15
|
+
'`config.feature_flag.kafkajs_instrumentation is false, skipping instrumentation of kafkajs`'
|
|
16
|
+
)
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
shim.setLibrary(shim.KAFKA)
|
|
21
|
+
instrumentConsumer({ shim, kafkajs, recordMethodMetric })
|
|
22
|
+
instrumentProducer({ shim, kafkajs, recordMethodMetric })
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Convenience method for logging the tracking metrics for producer and consumer
|
|
27
|
+
*
|
|
28
|
+
* @param {object} params to function
|
|
29
|
+
* @param {Agent} params.agent instance of agent
|
|
30
|
+
* @param {string} params.name name of function getting instrumented
|
|
31
|
+
*/
|
|
32
|
+
function recordMethodMetric({ agent, name }) {
|
|
33
|
+
agent.metrics.getOrCreateMetric(`${KAFKA.PREFIX}/${name}`).incrementCallCount()
|
|
34
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const { MessageSpec } = require('../../shim/specs')
|
|
9
|
+
const getByPath = require('../../util/get')
|
|
10
|
+
|
|
11
|
+
module.exports = function instrumentProducer({ shim, kafkajs, recordMethodMetric }) {
|
|
12
|
+
const { agent } = shim
|
|
13
|
+
shim.wrap(kafkajs.Kafka.prototype, 'producer', function nrProducerWrapper(shim, orig) {
|
|
14
|
+
return function nrProducer() {
|
|
15
|
+
const params = shim.argsToArray.apply(shim, arguments)
|
|
16
|
+
const producer = orig.apply(this, params)
|
|
17
|
+
|
|
18
|
+
// The `.producer()` method returns an object with `send` and `sendBatch`
|
|
19
|
+
// methods. The `send` method is merely a wrapper around `sendBatch`, but
|
|
20
|
+
// we cannot simply wrap `sendBatch` because the `send` method does not
|
|
21
|
+
// use the object scoped instance (i.e. `this.sendBatch`); it utilizes
|
|
22
|
+
// the closure scoped instance of `sendBatch`. So we must wrap each
|
|
23
|
+
// method.
|
|
24
|
+
|
|
25
|
+
shim.recordProduce(producer, 'send', function nrSend(shim, fn, name, args) {
|
|
26
|
+
recordMethodMetric({ agent, name })
|
|
27
|
+
const data = args[0]
|
|
28
|
+
return new MessageSpec({
|
|
29
|
+
promise: true,
|
|
30
|
+
destinationName: data.topic,
|
|
31
|
+
destinationType: shim.TOPIC,
|
|
32
|
+
messageHeaders: (inject) => {
|
|
33
|
+
return data.messages.map((msg) => {
|
|
34
|
+
if (msg.headers) {
|
|
35
|
+
return inject(msg.headers)
|
|
36
|
+
}
|
|
37
|
+
msg.headers = {}
|
|
38
|
+
return inject(msg.headers)
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
shim.recordProduce(producer, 'sendBatch', function nrSendBatch(shim, fn, name, args) {
|
|
45
|
+
recordMethodMetric({ agent, name })
|
|
46
|
+
const data = args[0]
|
|
47
|
+
const firstMessage = getByPath(data, 'topicMessages[0].messages[0]')
|
|
48
|
+
|
|
49
|
+
if (firstMessage) {
|
|
50
|
+
firstMessage.headers = firstMessage.headers ?? {}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return new MessageSpec({
|
|
54
|
+
promise: true,
|
|
55
|
+
destinationName: data.topicMessages[0].topic,
|
|
56
|
+
destinationType: shim.TOPIC,
|
|
57
|
+
messageHeaders: (inject) => {
|
|
58
|
+
return data.topicMessages.map((tm) => {
|
|
59
|
+
return tm.messages.map((m) => {
|
|
60
|
+
if (m.headers) {
|
|
61
|
+
return inject(m.headers)
|
|
62
|
+
}
|
|
63
|
+
m.headers = {}
|
|
64
|
+
return inject(m.headers)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return producer
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
}
|
package/lib/instrumentations.js
CHANGED
|
@@ -29,6 +29,7 @@ module.exports = function instrumentations() {
|
|
|
29
29
|
'fastify': { type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK },
|
|
30
30
|
'generic-pool': { type: InstrumentationDescriptor.TYPE_GENERIC },
|
|
31
31
|
'ioredis': { type: InstrumentationDescriptor.TYPE_DATASTORE },
|
|
32
|
+
'kafkajs': { type: InstrumentationDescriptor.TYPE_MESSAGE },
|
|
32
33
|
'koa': { module: './instrumentation/koa' },
|
|
33
34
|
'langchain': { module: './instrumentation/langchain' },
|
|
34
35
|
'memcached': { type: InstrumentationDescriptor.TYPE_DATASTORE },
|
package/lib/metrics/names.js
CHANGED
|
@@ -340,54 +340,59 @@ const LOGGING = {
|
|
|
340
340
|
LOCAL_DECORATING: `${SUPPORTABILITY.LOGGING}/LocalDecorating/${NODEJS.PREFIX}`
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
+
const KAFKA = {
|
|
344
|
+
PREFIX: `${SUPPORTABILITY.FEATURES}/Instrumentation/kafkajs`
|
|
345
|
+
}
|
|
346
|
+
|
|
343
347
|
module.exports = {
|
|
344
348
|
ACTION_DELIMITER: '/',
|
|
345
349
|
AI,
|
|
346
|
-
ALL
|
|
350
|
+
ALL,
|
|
347
351
|
APDEX: 'Apdex',
|
|
348
|
-
CASSANDRA
|
|
352
|
+
CASSANDRA,
|
|
349
353
|
CLIENT_APPLICATION: 'ClientApplication',
|
|
350
354
|
CONTROLLER: 'Controller',
|
|
351
|
-
CPU
|
|
355
|
+
CPU,
|
|
352
356
|
CUSTOM: 'Custom',
|
|
353
|
-
CUSTOM_EVENTS
|
|
357
|
+
CUSTOM_EVENTS,
|
|
354
358
|
DATA_USAGE,
|
|
355
|
-
DB
|
|
359
|
+
DB,
|
|
356
360
|
DISTRIBUTED_TRACE,
|
|
357
|
-
ERRORS
|
|
358
|
-
EVENTS
|
|
359
|
-
EVENT_HARVEST
|
|
360
|
-
EXPRESS
|
|
361
|
-
EXTERNAL
|
|
361
|
+
ERRORS,
|
|
362
|
+
EVENTS,
|
|
363
|
+
EVENT_HARVEST,
|
|
364
|
+
EXPRESS,
|
|
365
|
+
EXTERNAL,
|
|
362
366
|
FEATURES,
|
|
363
|
-
FS
|
|
364
|
-
FUNCTION
|
|
365
|
-
GC
|
|
366
|
-
HAPI
|
|
367
|
+
FS,
|
|
368
|
+
FUNCTION,
|
|
369
|
+
GC,
|
|
370
|
+
HAPI,
|
|
367
371
|
HTTP: 'HttpDispatcher',
|
|
368
|
-
INFINITE_TRACING
|
|
369
|
-
|
|
372
|
+
INFINITE_TRACING,
|
|
373
|
+
KAFKA,
|
|
374
|
+
LOOP,
|
|
370
375
|
LOGGING,
|
|
371
|
-
MEMCACHE
|
|
372
|
-
MEMORY
|
|
373
|
-
MESSAGE_TRANSACTION
|
|
374
|
-
MIDDLEWARE
|
|
375
|
-
MONGODB
|
|
376
|
-
MYSQL
|
|
377
|
-
NODEJS
|
|
376
|
+
MEMCACHE,
|
|
377
|
+
MEMORY,
|
|
378
|
+
MESSAGE_TRANSACTION,
|
|
379
|
+
MIDDLEWARE,
|
|
380
|
+
MONGODB,
|
|
381
|
+
MYSQL,
|
|
382
|
+
NODEJS,
|
|
378
383
|
NORMALIZED: 'NormalizedUri',
|
|
379
|
-
OTHER_TRANSACTION
|
|
380
|
-
POSTGRES
|
|
384
|
+
OTHER_TRANSACTION,
|
|
385
|
+
POSTGRES,
|
|
386
|
+
PRISMA,
|
|
381
387
|
QUEUETIME: 'WebFrontend/QueueTime',
|
|
382
|
-
REDIS
|
|
383
|
-
RESTIFY
|
|
384
|
-
SPAN_EVENTS
|
|
385
|
-
SUPPORTABILITY
|
|
386
|
-
TRANSACTION_ERROR
|
|
387
|
-
TRUNCATED
|
|
388
|
+
REDIS,
|
|
389
|
+
RESTIFY,
|
|
390
|
+
SPAN_EVENTS,
|
|
391
|
+
SUPPORTABILITY,
|
|
392
|
+
TRANSACTION_ERROR,
|
|
393
|
+
TRUNCATED,
|
|
388
394
|
URI: 'Uri',
|
|
389
|
-
UTILIZATION
|
|
390
|
-
VIEW
|
|
391
|
-
WEB
|
|
392
|
-
PRISMA: PRISMA
|
|
395
|
+
UTILIZATION,
|
|
396
|
+
VIEW,
|
|
397
|
+
WEB
|
|
393
398
|
}
|
|
@@ -246,6 +246,16 @@ function recordProduce(nodule, properties, recordNamer) {
|
|
|
246
246
|
if (msgDesc.headers) {
|
|
247
247
|
shim.insertCATRequestHeaders(msgDesc.headers, true)
|
|
248
248
|
}
|
|
249
|
+
|
|
250
|
+
if (msgDesc.messageHeaders) {
|
|
251
|
+
// Some message broker clients, like kafkajs, allow for sending multiple
|
|
252
|
+
// messages in one send. Clients are likely to pick up such messages
|
|
253
|
+
// individually. Thus, we need to propagate any distributed trace
|
|
254
|
+
// headers to every message in the payload.
|
|
255
|
+
msgDesc.messageHeaders((headers, altNames = true) => {
|
|
256
|
+
shim.insertCATRequestHeaders(headers, altNames)
|
|
257
|
+
})
|
|
258
|
+
}
|
|
249
259
|
}
|
|
250
260
|
msgDesc.recorder = genericRecorder
|
|
251
261
|
return msgDesc
|
|
@@ -56,13 +56,25 @@ function createSubscriberWrapper({ shim, fn, spec, destNameIsArg }) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
if (consumerIdx !== null) {
|
|
59
|
+
if (consumerIdx !== null && !spec.functions) {
|
|
60
60
|
args[consumerIdx] = shim.wrap(
|
|
61
61
|
args[consumerIdx],
|
|
62
62
|
makeWrapConsumer({ spec, queue, destinationName, destNameIsArg })
|
|
63
63
|
)
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
if (consumerIdx !== null && spec.functions) {
|
|
67
|
+
spec.functions.forEach((name) => {
|
|
68
|
+
// only wrap the function if it exists on consumer
|
|
69
|
+
if (args[consumerIdx][name]) {
|
|
70
|
+
args[consumerIdx][name] = shim.wrap(
|
|
71
|
+
args[consumerIdx][name],
|
|
72
|
+
makeWrapConsumer({ spec, queue, destinationName, destNameIsArg })
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
return fn.apply(this, args)
|
|
67
79
|
}
|
|
68
80
|
}
|
|
@@ -27,6 +27,30 @@ class MessageSubscribeSpec extends MessageSpec {
|
|
|
27
27
|
*/
|
|
28
28
|
consumer
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Indicates names of functions to be wrapped for message consumption.
|
|
32
|
+
* This must be used in tandem with consumer.
|
|
33
|
+
* @type {Array<string>|null}
|
|
34
|
+
* @example
|
|
35
|
+
* // Wrap the eachMessage method on a consumer
|
|
36
|
+
* class Consumer() {
|
|
37
|
+
* constructor() {}
|
|
38
|
+
* async run(consumer) {
|
|
39
|
+
* consumer.eachMessage({ message })
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* const spec = new MessageSubscribeSpec({
|
|
44
|
+
* name: 'Consumer#run'
|
|
45
|
+
* promise: true
|
|
46
|
+
* consumer: shim.FIRST,
|
|
47
|
+
* functions: ['eachMessage']
|
|
48
|
+
* })
|
|
49
|
+
*
|
|
50
|
+
* shim.recordSubscribedConsume(Consumer.prototype, 'run', spec)
|
|
51
|
+
*/
|
|
52
|
+
functions
|
|
53
|
+
|
|
30
54
|
/* eslint-disable jsdoc/require-param-description */
|
|
31
55
|
/**
|
|
32
56
|
* @param {MessageSubscribeSpecParams} params
|
|
@@ -35,6 +59,7 @@ class MessageSubscribeSpec extends MessageSpec {
|
|
|
35
59
|
super(params)
|
|
36
60
|
|
|
37
61
|
this.consumer = params.consumer ?? null
|
|
62
|
+
this.functions = Array.isArray(params.functions) ? params.functions : null
|
|
38
63
|
}
|
|
39
64
|
}
|
|
40
65
|
|
|
@@ -14,11 +14,23 @@ const OperationSpec = require('./operation')
|
|
|
14
14
|
* @property {number|string} [destinationName]
|
|
15
15
|
* @property {string|null} [destinationType]
|
|
16
16
|
* @property {Object<string, string>|null} [headers]
|
|
17
|
+
* @property {MessageBrokerHeadersFn|null} [messageHeaders]
|
|
17
18
|
* @property {MessageHandlerFunction|null} [messageHandler]
|
|
18
19
|
* @property {number|string|null} [queue]
|
|
19
20
|
* @property {string|null} [routingKey]
|
|
20
21
|
*/
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Function} MessageBrokerHeadersFn
|
|
25
|
+
* @param {Function} inject A function with the signature
|
|
26
|
+
* `function(headers, useAlternateHeaderNames)`. The passed in headers object
|
|
27
|
+
* will be updated with distributed trace headers. When the second parameter
|
|
28
|
+
* is `true` (the default), alternate style (not HTTP style) header names will
|
|
29
|
+
* be used, i.e. names that are safe for non-HTTP transports.
|
|
30
|
+
* @returns {object[]} An array of objects, wherein each object will be updated
|
|
31
|
+
* with distributed trace headers.
|
|
32
|
+
*/
|
|
33
|
+
|
|
22
34
|
/**
|
|
23
35
|
* Spec that describes how to instrument a message broker.
|
|
24
36
|
*/
|
|
@@ -46,6 +58,16 @@ class MessageSpec extends OperationSpec {
|
|
|
46
58
|
*/
|
|
47
59
|
headers
|
|
48
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Function that returns an iterable set of message header objects. The
|
|
63
|
+
* header objects will be modified to include distributed tracing headers so
|
|
64
|
+
* that they will be included in the payloads delivered, and read from, the
|
|
65
|
+
* message broker.
|
|
66
|
+
*
|
|
67
|
+
* @type {MessageBrokerHeadersFn}
|
|
68
|
+
*/
|
|
69
|
+
messageHeaders
|
|
70
|
+
|
|
49
71
|
/**
|
|
50
72
|
* A function to handle the result of the instrumented message broker
|
|
51
73
|
* function.
|
|
@@ -81,6 +103,7 @@ class MessageSpec extends OperationSpec {
|
|
|
81
103
|
this.destinationName = params.destinationName ?? null
|
|
82
104
|
this.destinationType = params.destinationType ?? null
|
|
83
105
|
this.headers = params.headers ?? null
|
|
106
|
+
this.messageHeaders = params.messageHeaders ?? null
|
|
84
107
|
this.messageHandler = params.messageHandler ?? null
|
|
85
108
|
this.queue = params.queue ?? null
|
|
86
109
|
this.routingKey = params.routingKey ?? null
|
package/lib/symbols.js
CHANGED
|
@@ -11,6 +11,7 @@ module.exports = {
|
|
|
11
11
|
databaseName: Symbol('databaseName'),
|
|
12
12
|
disableDT: Symbol('Disable distributed tracing'), // description for backwards compatibility
|
|
13
13
|
executorContext: Symbol('executorContext'),
|
|
14
|
+
kafkaCtx: Symbol('kafkaCtx'),
|
|
14
15
|
koaBody: Symbol('body'),
|
|
15
16
|
koaBodySet: Symbol('bodySet'),
|
|
16
17
|
koaRouter: Symbol('koaRouter'),
|
|
@@ -313,6 +313,9 @@ class TraceContext {
|
|
|
313
313
|
return traceParentInfo
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
+
if (Buffer.isBuffer(traceparent)) {
|
|
317
|
+
traceparent = traceparent.toString()
|
|
318
|
+
}
|
|
316
319
|
const trimmed = traceparent.trim()
|
|
317
320
|
const parts = trimmed.split('-')
|
|
318
321
|
|
|
@@ -445,10 +448,14 @@ class TraceContext {
|
|
|
445
448
|
}
|
|
446
449
|
|
|
447
450
|
_parseTraceState(params) {
|
|
448
|
-
const {
|
|
451
|
+
const { hasTrustKey, expectedNrKey } = params
|
|
452
|
+
let { tracestate } = params
|
|
449
453
|
let nrTraceStateValue = null
|
|
450
454
|
const finalListMembers = []
|
|
451
455
|
const vendors = []
|
|
456
|
+
if (Buffer.isBuffer(tracestate)) {
|
|
457
|
+
tracestate = tracestate.toString()
|
|
458
|
+
}
|
|
452
459
|
const incomingListMembers = tracestate.split(',')
|
|
453
460
|
for (let i = 0; i < incomingListMembers.length; i++) {
|
|
454
461
|
const listMember = incomingListMembers[i].trim()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newrelic",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.19.0",
|
|
4
4
|
"author": "New Relic Node.js agent team <nodejs@newrelic.com>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"contributors": [
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"scripts": {
|
|
156
156
|
"bench": "node ./bin/run-bench.js",
|
|
157
157
|
"docker-env": "./bin/docker-env-vars.sh",
|
|
158
|
-
"docs": "
|
|
158
|
+
"docs": "rm -rf ./out && jsdoc -c ./jsdoc-conf.jsonc --private -r .",
|
|
159
159
|
"integration": "npm run prepare-test && npm run sub-install && time c8 -o ./coverage/integration tap --test-regex='(\\/|^test\\/integration\\/.*\\.tap\\.js)$' --timeout=600 --no-coverage --reporter classic",
|
|
160
160
|
"integration:esm": "time c8 -o ./coverage/integration-esm tap --node-arg='--loader=./esm-loader.mjs' --test-regex='(test\\/integration\\/.*\\.tap\\.mjs)$' --timeout=600 --no-coverage --reporter classic",
|
|
161
161
|
"prepare-test": "npm run ssl && npm run docker-env",
|
|
@@ -164,6 +164,7 @@
|
|
|
164
164
|
"public-docs": "jsdoc -c ./jsdoc-conf.jsonc && cp examples/shim/*.png out/",
|
|
165
165
|
"publish-docs": "./bin/publish-docs.sh",
|
|
166
166
|
"services": "docker compose up -d --wait",
|
|
167
|
+
"services:stop": "docker compose down",
|
|
167
168
|
"smoke": "npm run ssl && time tap test/smoke/**/**/*.tap.js --timeout=180 --no-coverage",
|
|
168
169
|
"ssl": "./bin/ssl.sh",
|
|
169
170
|
"sub-install": "node test/bin/install_sub_deps",
|
|
@@ -194,7 +195,7 @@
|
|
|
194
195
|
"@grpc/grpc-js": "^1.9.4",
|
|
195
196
|
"@grpc/proto-loader": "^0.7.5",
|
|
196
197
|
"@newrelic/ritm": "^7.2.0",
|
|
197
|
-
"@newrelic/security-agent": "^1.
|
|
198
|
+
"@newrelic/security-agent": "^1.3.0",
|
|
198
199
|
"@tyriar/fibonacci-heap": "^2.0.7",
|
|
199
200
|
"concat-stream": "^2.0.0",
|
|
200
201
|
"https-proxy-agent": "^7.0.1",
|
|
@@ -246,19 +247,16 @@
|
|
|
246
247
|
"koa-router": "^12.0.1",
|
|
247
248
|
"lint-staged": "^11.0.0",
|
|
248
249
|
"lockfile-lint": "^4.9.6",
|
|
249
|
-
"memcached": ">=0.2.8",
|
|
250
250
|
"nock": "11.8.0",
|
|
251
251
|
"proxy": "^2.1.1",
|
|
252
252
|
"proxyquire": "^1.8.0",
|
|
253
|
-
"q": "*",
|
|
254
253
|
"rfdc": "^1.3.1",
|
|
255
254
|
"rimraf": "^2.6.3",
|
|
256
255
|
"should": "*",
|
|
257
256
|
"sinon": "^4.5.0",
|
|
258
257
|
"superagent": "^9.0.1",
|
|
259
258
|
"tap": "^16.3.4",
|
|
260
|
-
"temp": "^0.8.1"
|
|
261
|
-
"when": "*"
|
|
259
|
+
"temp": "^0.8.1"
|
|
262
260
|
},
|
|
263
261
|
"repository": {
|
|
264
262
|
"type": "git",
|