newrelic 11.18.0 → 11.20.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 +91 -33
- package/README.md +2 -5
- package/THIRD_PARTY_NOTICES.md +6 -92
- package/api.js +10 -10
- package/lib/config/attribute-filter.js +1 -1
- package/lib/config/default.js +3 -3
- package/lib/feature_flags.js +2 -1
- package/lib/instrumentation/amqplib/amqplib.js +1 -1
- package/lib/instrumentation/aws-sdk/util.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/llm-events/aws-bedrock/bedrock-command.js +12 -2
- package/lib/llm-events/aws-bedrock/bedrock-response.js +12 -1
- package/lib/llm-events/aws-bedrock/stream-handler.js +28 -0
- package/lib/metrics/names.js +40 -35
- package/lib/shim/datastore-shim.js +2 -2
- 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/name-state.js +1 -1
- package/lib/transaction/tracecontext.js +8 -1
- package/lib/util/hashes.js +3 -2
- package/lib/utilization/docker-info.js +1 -1
- package/lib/utilization/gcp-info.js +4 -2
- package/package.json +6 -8
package/NEWS.md
CHANGED
|
@@ -1,36 +1,94 @@
|
|
|
1
|
-
### v11.
|
|
2
|
-
|
|
3
|
-
#### Features
|
|
4
|
-
|
|
5
|
-
* Added support for
|
|
6
|
-
|
|
7
|
-
#### Code refactoring
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
#### Documentation
|
|
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.20.0 (2024-06-24)
|
|
2
|
+
|
|
3
|
+
#### Features
|
|
4
|
+
|
|
5
|
+
* Added support for Anthropic Claude 3 messages API ([#2278](https://github.com/newrelic/node-newrelic/pull/2278)) ([7e3cab9](https://github.com/newrelic/node-newrelic/commit/7e3cab9739a9924b904ce78380fd70b1e30cd89f))
|
|
6
|
+
|
|
7
|
+
#### Code refactoring
|
|
8
|
+
|
|
9
|
+
* Replaced instances of `substr()` with `substring()` ([#2274](https://github.com/newrelic/node-newrelic/pull/2274)) ([8f96c73](https://github.com/newrelic/node-newrelic/commit/8f96c734862d42f459dd4de8ed9d498ef7d693de))
|
|
10
|
+
|
|
11
|
+
#### Documentation
|
|
12
|
+
|
|
13
|
+
* Fixed typos in API jsdoc ([#2287](https://github.com/newrelic/node-newrelic/pull/2287)) ([7b3c8d1](https://github.com/newrelic/node-newrelic/commit/7b3c8d1445ea9876b36eda31d979dac9b65dad14))
|
|
14
|
+
* Updated compatibility report ([#2285](https://github.com/newrelic/node-newrelic/pull/2285)) ([b1b5e3e](https://github.com/newrelic/node-newrelic/commit/b1b5e3e54074cc8b535927f4edad07925618260c))
|
|
15
|
+
|
|
16
|
+
#### Miscellaneous chores
|
|
17
|
+
|
|
18
|
+
* Added a missing library we instrument to be picked up by the compatibility report ([#2261](https://github.com/newrelic/node-newrelic/pull/2261)) ([6c964b2](https://github.com/newrelic/node-newrelic/commit/6c964b2029874353908486228113a468959b1597))
|
|
19
|
+
* Added a script that generates Dashboard json for reporting on libraries by version ([#2267](https://github.com/newrelic/node-newrelic/pull/2267)) ([d2877c1](https://github.com/newrelic/node-newrelic/commit/d2877c17c7c2f4432b2ce4056c94200a2e7334b2))
|
|
20
|
+
* Added AI support docs for automation ([#2249](https://github.com/newrelic/node-newrelic/pull/2249)) ([e2efc1f](https://github.com/newrelic/node-newrelic/commit/e2efc1fb202a3e87be710f352546a00df6bf6cef))
|
|
21
|
+
* Fixed comment about transaction_tracer.transaction_threshold ([#2258](https://github.com/newrelic/node-newrelic/pull/2258)) ([7cd6aef](https://github.com/newrelic/node-newrelic/commit/7cd6aef7ecc32d8647f0313b36be368bfa14a0e9))
|
|
22
|
+
* Made elastic versioned tests work on Node 16 ([#2284](https://github.com/newrelic/node-newrelic/pull/2284)) ([143b475](https://github.com/newrelic/node-newrelic/commit/143b4757c27d497a25d1b3c7fd56b32bcede619f))
|
|
23
|
+
* Updated docker compose configuration ([#2268](https://github.com/newrelic/node-newrelic/pull/2268)) ([eb1cce9](https://github.com/newrelic/node-newrelic/commit/eb1cce9143fe87eed1bdd077471942f85cf14f21))
|
|
24
|
+
* Updated GitHub Actions versions ([#2272](https://github.com/newrelic/node-newrelic/pull/2272)) ([07a841b](https://github.com/newrelic/node-newrelic/commit/07a841b9acf0a0dcb1a495c5cb0ee8f77e283fc9))
|
|
25
|
+
* Updated mysql tests to use MySQL 8.3 ([#2280](https://github.com/newrelic/node-newrelic/pull/2280)) ([11e0f8c](https://github.com/newrelic/node-newrelic/commit/11e0f8cf63a5f792419382635496a29c0286c737))
|
|
26
|
+
* Updated mysql2 tests to fix CI issue ([#2282](https://github.com/newrelic/node-newrelic/pull/2282)) ([5a37971](https://github.com/newrelic/node-newrelic/commit/5a37971b03fe8d69b39db66d97ecfc1176c42902))
|
|
27
|
+
* Updated versioned security agent workflow with simpler setup ([#2259](https://github.com/newrelic/node-newrelic/pull/2259)) ([a886187](https://github.com/newrelic/node-newrelic/commit/a886187bf1bf29d2430e38223d0215436e006540))
|
|
28
|
+
|
|
29
|
+
#### Continuous integration
|
|
30
|
+
|
|
31
|
+
* Added ability to run a build step in create release ([#2273](https://github.com/newrelic/node-newrelic/pull/2273)) ([4c2f24c](https://github.com/newrelic/node-newrelic/commit/4c2f24cb6e94dd05f269998eeb763196c3fac274))
|
|
32
|
+
* Updated security agent workflow to use large runners when available ([#2271](https://github.com/newrelic/node-newrelic/pull/2271)) ([181ec1b](https://github.com/newrelic/node-newrelic/commit/181ec1bfa8d420514fca3d6de6c3989e796a29db))
|
|
33
|
+
* Updated security agent workflow to use large runners when available ([#2270](https://github.com/newrelic/node-newrelic/pull/2270)) ([761fcd5](https://github.com/newrelic/node-newrelic/commit/761fcd5ca5ae32ba922d0880979dbfff97604641))
|
|
34
|
+
|
|
35
|
+
### v11.19.0 (2024-06-06)
|
|
36
|
+
|
|
37
|
+
#### Features
|
|
38
|
+
|
|
39
|
+
* 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))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
#### Miscellaneous chores
|
|
43
|
+
|
|
44
|
+
* 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))
|
|
45
|
+
* Added kafkajs to compatibility list ([#2254](https://github.com/newrelic/node-newrelic/pull/2254)) ([f003ee7](https://github.com/newrelic/node-newrelic/commit/f003ee78204149c7905cb17cb4f084aeac1ba751))
|
|
46
|
+
* 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))
|
|
47
|
+
* Removed targets for kafka versioned tests ([#2235](https://github.com/newrelic/node-newrelic/pull/2235)) ([838bab2](https://github.com/newrelic/node-newrelic/commit/838bab2ff425f5acb111a19f397760ed01c1bdde))
|
|
48
|
+
* Updated flaky when test ([#2241](https://github.com/newrelic/node-newrelic/pull/2241)) ([4079a0a](https://github.com/newrelic/node-newrelic/commit/4079a0ae38e584181eec284963560341941c5dd3))
|
|
49
|
+
* 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))
|
|
50
|
+
* 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))
|
|
51
|
+
|
|
52
|
+
#### Tests
|
|
53
|
+
|
|
54
|
+
* Migrated `memcached` tests to versioned tests ([#2231](https://github.com/newrelic/node-newrelic/pull/2231)) ([0b3a928](https://github.com/newrelic/node-newrelic/commit/0b3a9284dc5bdc7755d176739186ea3c15cde23e))
|
|
55
|
+
* 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))
|
|
56
|
+
* 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))
|
|
57
|
+
* 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))
|
|
58
|
+
|
|
59
|
+
### v11.18.0 (2024-05-29)
|
|
60
|
+
|
|
61
|
+
#### Features
|
|
62
|
+
|
|
63
|
+
* 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))
|
|
64
|
+
|
|
65
|
+
#### Code refactoring
|
|
66
|
+
|
|
67
|
+
* 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))
|
|
68
|
+
|
|
69
|
+
#### Documentation
|
|
70
|
+
|
|
71
|
+
* Updated compatibility report ([#2223](https://github.com/newrelic/node-newrelic/pull/2223)) ([a256ca0](https://github.com/newrelic/node-newrelic/commit/a256ca0f2060efe576018527d37718a041ffc925))
|
|
72
|
+
|
|
73
|
+
#### Miscellaneous chores
|
|
74
|
+
|
|
75
|
+
* Removed outdated Slack reference ([#2198](https://github.com/newrelic/node-newrelic/pull/2198)) ([8110d42](https://github.com/newrelic/node-newrelic/commit/8110d426f402659d44bf786fec0503ca2413ee6b))
|
|
76
|
+
* Removed package-lock.json ([#2208](https://github.com/newrelic/node-newrelic/pull/2208)) ([b267695](https://github.com/newrelic/node-newrelic/commit/b26769502b4cb38f9133f76f427ee96ce718c15b))
|
|
77
|
+
* Removed unused express5 feature flag ([#2197](https://github.com/newrelic/node-newrelic/pull/2197)) ([366504b](https://github.com/newrelic/node-newrelic/commit/366504ba1e3bfed477a37be5d61f4e30e46b690d))
|
|
78
|
+
|
|
79
|
+
#### Tests
|
|
80
|
+
|
|
81
|
+
* 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))
|
|
82
|
+
* Fixed aws-sdk-v3 bedrock tests ([#2211](https://github.com/newrelic/node-newrelic/pull/2211)) ([050469e](https://github.com/newrelic/node-newrelic/commit/050469ecc59ccc9ba6a6e78527ac392f262ff939))
|
|
83
|
+
* 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))
|
|
84
|
+
|
|
85
|
+
#### Continuous integration
|
|
86
|
+
|
|
87
|
+
* 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))
|
|
88
|
+
* 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))
|
|
89
|
+
* Fixed CI jobs ([#2215](https://github.com/newrelic/node-newrelic/pull/2215)) ([8b030fb](https://github.com/newrelic/node-newrelic/commit/8b030fbf479cd348e9b75544bc753c1d618bfca7))
|
|
90
|
+
* Fixed should-run CI step ([#2214](https://github.com/newrelic/node-newrelic/pull/2214)) ([d0a481d](https://github.com/newrelic/node-newrelic/commit/d0a481d4b58706c4793fa12fa7706091eaffa0a4))
|
|
91
|
+
|
|
34
92
|
### v11.17.0 (2024-05-15)
|
|
35
93
|
|
|
36
94
|
#### 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/api.js
CHANGED
|
@@ -244,14 +244,14 @@ API.prototype.setControllerName = function setControllerName(name, action) {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
/**
|
|
247
|
-
* Add a custom attribute to the current transaction. Some attributes are
|
|
247
|
+
* Add a custom attribute to the current transaction and span. Some attributes are
|
|
248
248
|
* reserved (see CUSTOM_DENYLIST for the current, very short list), and
|
|
249
249
|
* as with most API methods, this must be called in the context of an
|
|
250
250
|
* active transaction. Most recently set value wins.
|
|
251
251
|
*
|
|
252
252
|
* @param {string} key The key you want displayed in the RPM UI.
|
|
253
253
|
* @param {string} value The value you want displayed. Must be serializable.
|
|
254
|
-
* @returns {false|undefined}
|
|
254
|
+
* @returns {false|undefined} Returns false when disabled/errored, otherwise undefined
|
|
255
255
|
*/
|
|
256
256
|
API.prototype.addCustomAttribute = function addCustomAttribute(key, value) {
|
|
257
257
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -298,7 +298,7 @@ API.prototype.addCustomAttribute = function addCustomAttribute(key, value) {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
/**
|
|
301
|
-
* Adds all custom attributes in an object to the current transaction.
|
|
301
|
+
* Adds all custom attributes in an object to the current transaction and span.
|
|
302
302
|
*
|
|
303
303
|
* See documentation for newrelic.addCustomAttribute for more information on
|
|
304
304
|
* setting custom attributes.
|
|
@@ -360,7 +360,7 @@ API.prototype.addCustomSpanAttributes = function addCustomSpanAttributes(atts) {
|
|
|
360
360
|
*
|
|
361
361
|
* @param {string} key The key you want displayed in the RPM UI.
|
|
362
362
|
* @param {string} value The value you want displayed. Must be serializable.
|
|
363
|
-
* @returns {false|undefined}
|
|
363
|
+
* @returns {false|undefined} Returns false when disabled/errored, otherwise undefined
|
|
364
364
|
*/
|
|
365
365
|
API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, value) {
|
|
366
366
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -807,7 +807,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options =
|
|
|
807
807
|
* Only the first 13 chars of the license should be used for hashing with
|
|
808
808
|
* the transaction name.
|
|
809
809
|
*/
|
|
810
|
-
const key = config.license_key.
|
|
810
|
+
const key = config.license_key.substring(0, 13)
|
|
811
811
|
rumHash.transactionName = hashes.obfuscateNameUsingKey(name, key)
|
|
812
812
|
|
|
813
813
|
rumHash.queueTime = trans.queueTime
|
|
@@ -938,7 +938,7 @@ API.prototype.startSegment = function startSegment(name, record, handler, callba
|
|
|
938
938
|
* })
|
|
939
939
|
* @param {string} url
|
|
940
940
|
* The URL of the transaction. It is used to name and group related transactions in APM,
|
|
941
|
-
* so it should be a generic name and not
|
|
941
|
+
* so it should be a generic name and not include any variable parameters.
|
|
942
942
|
* @param {Function} handle
|
|
943
943
|
* Function that represents the transaction work.
|
|
944
944
|
* @returns {null|*} Returns null if handle is not a function, otherwise the return value of handle
|
|
@@ -1026,7 +1026,7 @@ API.prototype.startBackgroundTransaction = startBackgroundTransaction
|
|
|
1026
1026
|
* })
|
|
1027
1027
|
* @param {string} name
|
|
1028
1028
|
* The name of the transaction. It is used to name and group related
|
|
1029
|
-
* transactions in APM, so it should be a generic name and not
|
|
1029
|
+
* transactions in APM, so it should be a generic name and not include any
|
|
1030
1030
|
* variable parameters.
|
|
1031
1031
|
* @param {string} [group]
|
|
1032
1032
|
* Optional, used for grouping background transactions in APM. For more
|
|
@@ -1297,14 +1297,14 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
|
|
|
1297
1297
|
// Filter all object type valued attributes out
|
|
1298
1298
|
const filteredAttributes = _filterAttributes(attributes, `${eventType} custom event`)
|
|
1299
1299
|
|
|
1300
|
-
const
|
|
1300
|
+
const intrinsics = {
|
|
1301
1301
|
type: eventType,
|
|
1302
1302
|
timestamp: Date.now()
|
|
1303
1303
|
}
|
|
1304
1304
|
|
|
1305
1305
|
const tx = this.agent.getTransaction()
|
|
1306
1306
|
const priority = (tx && tx.priority) || Math.random()
|
|
1307
|
-
this.agent.customEventAggregator.add([
|
|
1307
|
+
this.agent.customEventAggregator.add([intrinsics, filteredAttributes], priority)
|
|
1308
1308
|
}
|
|
1309
1309
|
|
|
1310
1310
|
/**
|
|
@@ -1342,7 +1342,7 @@ API.prototype.instrument = function instrument(moduleName, onRequire, onError) {
|
|
|
1342
1342
|
* Registers an instrumentation function.
|
|
1343
1343
|
*
|
|
1344
1344
|
* - `newrelic.instrumentConglomerate(moduleName, onRequire [, onError])`
|
|
1345
|
-
* - `newrelic.
|
|
1345
|
+
* - `newrelic.instrumentConglomerate(options)`
|
|
1346
1346
|
*
|
|
1347
1347
|
* @param {string|object} moduleName The module name given to require to load the module, or the instrumentation specification
|
|
1348
1348
|
* @param {string} moduleName.moduleName The module name given to require to load the module
|
package/lib/config/default.js
CHANGED
|
@@ -519,12 +519,12 @@ defaultConfig.definition = () => ({
|
|
|
519
519
|
env: 'NEW_RELIC_TRACER_ENABLED'
|
|
520
520
|
},
|
|
521
521
|
/**
|
|
522
|
-
*
|
|
523
|
-
* transaction trace.
|
|
522
|
+
* Sets the time, in seconds, for a transaction to be considered slow.
|
|
523
|
+
* When a transaction exceeds this threshold, a transaction trace will be recorded. When set to 'apdex_f', the threshold will be set to
|
|
524
524
|
* 4 * apdex_t, which with a default apdex_t value of 500 milliseconds will
|
|
525
525
|
* be 2 seconds.
|
|
526
526
|
*
|
|
527
|
-
* If a
|
|
527
|
+
* If a number is provided, it is set in seconds.
|
|
528
528
|
*/
|
|
529
529
|
transaction_threshold: {
|
|
530
530
|
formatter: float,
|
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 },
|
|
@@ -35,7 +35,7 @@ class BedrockCommand {
|
|
|
35
35
|
result = this.#body.maxTokens
|
|
36
36
|
} else if (this.isClaude() === true) {
|
|
37
37
|
result = this.#body.max_tokens_to_sample
|
|
38
|
-
} else if (this.isCohere() === true) {
|
|
38
|
+
} else if (this.isClaude3() === true || this.isCohere() === true) {
|
|
39
39
|
result = this.#body.max_tokens
|
|
40
40
|
} else if (this.isLlama2() === true) {
|
|
41
41
|
result = this.#body.max_gen_length
|
|
@@ -83,6 +83,11 @@ class BedrockCommand {
|
|
|
83
83
|
this.isLlama2() === true
|
|
84
84
|
) {
|
|
85
85
|
result = this.#body.prompt
|
|
86
|
+
} else if (this.isClaude3() === true) {
|
|
87
|
+
result = this.#body?.messages?.reduce((acc, curr) => {
|
|
88
|
+
acc += curr?.content ?? ''
|
|
89
|
+
return acc
|
|
90
|
+
}, '')
|
|
86
91
|
}
|
|
87
92
|
return result
|
|
88
93
|
}
|
|
@@ -96,6 +101,7 @@ class BedrockCommand {
|
|
|
96
101
|
result = this.#body.textGenerationConfig?.temperature
|
|
97
102
|
} else if (
|
|
98
103
|
this.isClaude() === true ||
|
|
104
|
+
this.isClaude3() === true ||
|
|
99
105
|
this.isAi21() === true ||
|
|
100
106
|
this.isCohere() === true ||
|
|
101
107
|
this.isLlama2() === true
|
|
@@ -110,7 +116,11 @@ class BedrockCommand {
|
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
isClaude() {
|
|
113
|
-
return this.#modelId.startsWith('anthropic.claude')
|
|
119
|
+
return this.#modelId.startsWith('anthropic.claude-v')
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
isClaude3() {
|
|
123
|
+
return this.#modelId.startsWith('anthropic.claude-3')
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
isCohere() {
|
|
@@ -30,10 +30,12 @@ class BedrockResponse {
|
|
|
30
30
|
#completions = []
|
|
31
31
|
#id
|
|
32
32
|
|
|
33
|
+
/* eslint-disable sonarjs/cognitive-complexity */
|
|
33
34
|
/**
|
|
34
35
|
* @param {object} params
|
|
35
36
|
* @param {AwsBedrockMiddlewareResponse} params.response
|
|
36
37
|
* @param {BedrockCommand} params.bedrockCommand
|
|
38
|
+
* @param params.isError
|
|
37
39
|
*/
|
|
38
40
|
constructor({ response, bedrockCommand, isError = false }) {
|
|
39
41
|
this.#innerResponse = isError ? response.$response : response.response
|
|
@@ -57,6 +59,14 @@ class BedrockResponse {
|
|
|
57
59
|
} else if (cmd.isClaude() === true) {
|
|
58
60
|
// TODO: can we make this thing give more than one completion?
|
|
59
61
|
body.completion && this.#completions.push(body.completion)
|
|
62
|
+
} else if (cmd.isClaude3() === true) {
|
|
63
|
+
if (body?.type === 'message_stop') {
|
|
64
|
+
// Streamed response
|
|
65
|
+
this.#completions = body.completions
|
|
66
|
+
} else {
|
|
67
|
+
this.#completions = body?.content?.map((c) => c.text)
|
|
68
|
+
}
|
|
69
|
+
this.#id = body.id
|
|
60
70
|
} else if (cmd.isCohere() === true) {
|
|
61
71
|
this.#completions = body.generations?.map((g) => g.text) ?? []
|
|
62
72
|
this.#id = body.id
|
|
@@ -66,6 +76,7 @@ class BedrockResponse {
|
|
|
66
76
|
this.#completions = body.results?.map((r) => r.outputText) ?? []
|
|
67
77
|
}
|
|
68
78
|
}
|
|
79
|
+
/* eslint-enable sonarjs/cognitive-complexity */
|
|
69
80
|
|
|
70
81
|
/**
|
|
71
82
|
* The prompt responses returned by the model.
|
|
@@ -92,7 +103,7 @@ class BedrockResponse {
|
|
|
92
103
|
const cmd = this.#command
|
|
93
104
|
if (cmd.isAi21() === true) {
|
|
94
105
|
result = this.#parsedBody.completions?.[0]?.finishReason.reason
|
|
95
|
-
} else if (cmd.isClaude() === true) {
|
|
106
|
+
} else if (cmd.isClaude() === true || cmd.isClaude3() === true) {
|
|
96
107
|
result = this.#parsedBody.stop_reason
|
|
97
108
|
} else if (cmd.isCohere() === true) {
|
|
98
109
|
result = this.#parsedBody.generations?.find((r) => r.finish_reason !== null)?.finish_reason
|
|
@@ -105,6 +105,9 @@ class StreamHandler {
|
|
|
105
105
|
if (bedrockCommand.isClaude() === true) {
|
|
106
106
|
this.stopReasonKey = 'stop_reason'
|
|
107
107
|
this.generator = handleClaude
|
|
108
|
+
} else if (bedrockCommand.isClaude3() === true) {
|
|
109
|
+
this.stopReasonKey = 'stop_reason'
|
|
110
|
+
this.generator = handleClaude3
|
|
108
111
|
} else if (bedrockCommand.isCohere() === true) {
|
|
109
112
|
this.stopReasonKey = 'generations.0.finish_reason'
|
|
110
113
|
this.generator = handleCohere
|
|
@@ -207,6 +210,31 @@ async function* handleClaude() {
|
|
|
207
210
|
}
|
|
208
211
|
}
|
|
209
212
|
|
|
213
|
+
async function* handleClaude3() {
|
|
214
|
+
let currentBody = {}
|
|
215
|
+
let stopReason
|
|
216
|
+
const completions = []
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
for await (const event of this.stream) {
|
|
220
|
+
yield event
|
|
221
|
+
const parsed = this.parseEvent(event)
|
|
222
|
+
this.updateHeaders(parsed)
|
|
223
|
+
currentBody = parsed
|
|
224
|
+
if (parsed.type === 'content_block_delta') {
|
|
225
|
+
completions.push(parsed.delta.text)
|
|
226
|
+
} else if (parsed.type === 'message_delta') {
|
|
227
|
+
stopReason = parsed.delta.stop_reason
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} finally {
|
|
231
|
+
currentBody.completions = completions
|
|
232
|
+
currentBody.stop_reason = stopReason
|
|
233
|
+
this.response.output.body = currentBody
|
|
234
|
+
this.finish()
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
210
238
|
async function* handleCohere() {
|
|
211
239
|
let currentBody = {}
|
|
212
240
|
const generations = []
|
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
|
}
|
|
@@ -376,10 +376,10 @@ function parseQuery(query, nodule) {
|
|
|
376
376
|
// strip enclosing special characters from collection (table) name
|
|
377
377
|
if (typeof collection === 'string' && collection.length > 2) {
|
|
378
378
|
if (/^[\[{'"`]/.test(collection)) {
|
|
379
|
-
collection = collection.
|
|
379
|
+
collection = collection.substring(1)
|
|
380
380
|
}
|
|
381
381
|
if (/[\]}'"`]$/.test(collection)) {
|
|
382
|
-
collection = collection.
|
|
382
|
+
collection = collection.substring(0, collection.length - 1)
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
385
|
|
|
@@ -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'),
|
|
@@ -187,7 +187,7 @@ NameState.prototype.getPath = function getPath() {
|
|
|
187
187
|
if (a[0] !== '/' && path[path.length - 1] !== '/') {
|
|
188
188
|
path += '/'
|
|
189
189
|
} else if (a[0] === '/' && path[path.length - 1] === '/') {
|
|
190
|
-
a = a.
|
|
190
|
+
a = a.substring(1)
|
|
191
191
|
}
|
|
192
192
|
path += a
|
|
193
193
|
}
|
|
@@ -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/lib/util/hashes.js
CHANGED
|
@@ -41,7 +41,8 @@ function calculatePathHash(appName, pathName, referingPathHash) {
|
|
|
41
41
|
const result = (rotated ^ hash) >>> 0
|
|
42
42
|
|
|
43
43
|
// This is a trick to pad it out to 8 chars regardless of length.
|
|
44
|
-
|
|
44
|
+
const str = '00000000' + result.toString(16)
|
|
45
|
+
return str.substring(str.length - 8)
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
function getHash(appName, txName) {
|
|
@@ -78,7 +79,7 @@ function int32ToByteArray(int32) {
|
|
|
78
79
|
// Lookup table for converting byte values to hex
|
|
79
80
|
const byteToHex = []
|
|
80
81
|
for (let i = 0; i < 256; ++i) {
|
|
81
|
-
byteToHex[i] = (i + 0x100).toString(16).
|
|
82
|
+
byteToHex[i] = (i + 0x100).toString(16).substring(1)
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
function makeId(length = 16) {
|
|
@@ -54,8 +54,10 @@ function fetchGCPInfo(agent, callback) {
|
|
|
54
54
|
agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.GCP_ERROR).incrementCallCount()
|
|
55
55
|
} else {
|
|
56
56
|
// normalize
|
|
57
|
-
results.machineType = results.machineType.
|
|
58
|
-
|
|
57
|
+
results.machineType = results.machineType.substring(
|
|
58
|
+
results.machineType.lastIndexOf('/') + 1
|
|
59
|
+
)
|
|
60
|
+
results.zone = results.zone.substring(results.zone.lastIndexOf('/') + 1)
|
|
59
61
|
|
|
60
62
|
resultDict = results
|
|
61
63
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newrelic",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.20.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",
|
|
@@ -163,7 +163,8 @@
|
|
|
163
163
|
"lint:fix": "eslint --fix, ./*.{js,mjs} lib test bin examples",
|
|
164
164
|
"public-docs": "jsdoc -c ./jsdoc-conf.jsonc && cp examples/shim/*.png out/",
|
|
165
165
|
"publish-docs": "./bin/publish-docs.sh",
|
|
166
|
-
"services": "docker compose up -d --wait",
|
|
166
|
+
"services": "DOCKER_PLATFORM=linux/$(uname -m) 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",
|