newrelic 11.13.0 → 11.15.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 +78 -25
- package/README.md +1 -1
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/api.js +1 -1
- package/lib/errors/index.js +1 -0
- package/lib/instrumentation/cassandra-driver.js +3 -1
- package/lib/instrumentation/mongodb/common.js +46 -74
- package/lib/instrumentation/mongodb/v2-mongo.js +10 -6
- package/lib/instrumentation/mongodb/v3-mongo.js +7 -10
- package/lib/instrumentation/mongodb/v4-mongo.js +24 -20
- package/lib/instrumentation/pg.js +3 -3
- package/lib/instrumentation-descriptor.js +215 -0
- package/lib/instrumentation-tracker.js +222 -0
- package/lib/instrumentations.js +30 -30
- package/lib/llm-events/langchain/event.js +0 -2
- package/lib/llm-events/openai/chat-completion-summary.js +0 -1
- package/lib/llm-events/openai/event.js +0 -3
- package/lib/shim/conglomerate-shim.js +15 -14
- package/lib/shim/datastore-shim.js +18 -15
- package/lib/shim/index.js +8 -10
- package/lib/shim/message-shim/consume.js +1 -2
- package/lib/shim/message-shim/index.js +19 -39
- package/lib/shim/message-shim/subscribe-consume.js +3 -4
- package/lib/shim/promise-shim.js +32 -27
- package/lib/shim/shim.js +10 -16
- package/lib/shim/specs/wrap.js +2 -10
- package/lib/shim/webframework-shim/common.js +0 -20
- package/lib/shim/webframework-shim/index.js +18 -44
- package/lib/shim/webframework-shim/middleware-mounter.js +1 -9
- package/lib/shim/webframework-shim/middleware.js +7 -6
- package/lib/shimmer.js +83 -67
- package/lib/symbols.js +0 -2
- package/lib/util/idgen.js +31 -0
- package/package.json +6 -6
- package/lib/shim/constants.js +0 -42
package/NEWS.md
CHANGED
|
@@ -1,39 +1,92 @@
|
|
|
1
|
-
### v11.
|
|
1
|
+
### v11.15.0 (2024-04-09)
|
|
2
2
|
|
|
3
|
-
####
|
|
3
|
+
#### Bug fixes
|
|
4
4
|
|
|
5
|
-
*
|
|
6
|
-
* To enable set `config.ai_monitoring.enabled` or `NEW_RELIC_AI_MONITORING_ENABLED` to `true`.
|
|
7
|
-
* It is recommended for a full experience to set `config.span_events.max_samples_stored` to `10000`, `config.custom_insights_events.max_samples_stored` to `100000`, and `config.distributed_tracing.enabled` should not be set to false.
|
|
8
|
-
* **Note**: Enabling [high-security mode](https://docs.newrelic.com/docs/apm/agents/manage-apm-agents/configuration/high-security-mode/) will disable the AIM instrumentation and events.
|
|
9
|
-
* Added instrumentation for VectorStore.similaritySearch for langchain.js ([#2049](https://github.com/newrelic/node-newrelic/pull/2049)) ([3c50606](https://github.com/newrelic/node-newrelic/commit/3c50606a57a8dc18c91fe36e3b180bafd15a4cbc))
|
|
10
|
-
* Added setLlmTokenCountCallback API endpoint to register a callback for calculating token count when none is provided ([#2065](https://github.com/newrelic/node-newrelic/pull/2065)) ([d2faf1a](https://github.com/newrelic/node-newrelic/commit/d2faf1a4942aacefd8b92e0bc2dc11bd8b687328))
|
|
11
|
-
* Added token_count to LlmEmbedding and LlmChatCompletionMessage for openai ([#2061](https://github.com/newrelic/node-newrelic/pull/2061)) ([47a925e](https://github.com/newrelic/node-newrelic/commit/47a925eccce8e5b5d682b46277bbef5191f8b553))
|
|
12
|
-
* Added tool_id to langchain error event ([#2064](https://github.com/newrelic/node-newrelic/pull/2064)) ([793abe8](https://github.com/newrelic/node-newrelic/commit/793abe8c9854b80fb1cf42f839a7db6a646cdc0b))
|
|
5
|
+
* Fixed instrumenting the same module installed in different locations ([#2104](https://github.com/newrelic/node-newrelic/pull/2104)) ([88bdace](https://github.com/newrelic/node-newrelic/commit/88bdace6489c7d258ed3200f1550367f35824bc1))
|
|
13
6
|
|
|
14
|
-
####
|
|
15
|
-
|
|
16
|
-
* Added flag for verbosity during docs publishing ([#2060](https://github.com/newrelic/node-newrelic/pull/2060)) ([fe0d41a](https://github.com/newrelic/node-newrelic/commit/fe0d41a86cba8da6173f5935e61c62b7dca75344))
|
|
17
|
-
* Added some delays to docs publishing ([#2062](https://github.com/newrelic/node-newrelic/pull/2062)) ([a602fd4](https://github.com/newrelic/node-newrelic/commit/a602fd48e929437e4bc933c4ce276989013c53f1))
|
|
18
|
-
* Changed casing of OpenAI in vendor property ([#2068](https://github.com/newrelic/node-newrelic/pull/2068)) ([64b4ca2](https://github.com/newrelic/node-newrelic/commit/64b4ca2750c9de8d9028fef515c15019e358a5d9))
|
|
19
|
-
* Changed token_count to only use tokenCountCallback ([#2070](https://github.com/newrelic/node-newrelic/pull/2070)) ([66f94b0](https://github.com/newrelic/node-newrelic/commit/66f94b05aa7018af6fa1db1d2d87de9013f23a5b))
|
|
20
|
-
* Removed langchain_instrumentation feature flag as the instrumentation is feature complete ([#2073](https://github.com/newrelic/node-newrelic/pull/2073)) ([925a463](https://github.com/newrelic/node-newrelic/commit/925a463c708b29c78567aecf78ac89ac226b7995))
|
|
21
|
-
* updated @newrelic/aws-sdk and @newrelic/koa to latest ([#2074](https://github.com/newrelic/node-newrelic/pull/2074)) ([0747ca4](https://github.com/newrelic/node-newrelic/commit/0747ca4f0f6615e1fbfcc734a36059960facf23e))
|
|
22
|
-
|
|
23
|
-
### v11.12.0 (2024-03-04)
|
|
7
|
+
#### Code refactoring
|
|
24
8
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* Added instrumentation for `chain.stream` for langchain js. ([#2052](https://github.com/newrelic/node-newrelic/pull/2052)) ([03abfce](https://github.com/newrelic/node-newrelic/commit/03abfce666d3c48abd0994c44817bb5cbe8655a9))
|
|
9
|
+
* **mongodb:** Removed instrumentation that handles connecting via unix domain socket. ([#2129](https://github.com/newrelic/node-newrelic/pull/2129)) ([808323f](https://github.com/newrelic/node-newrelic/commit/808323f0832952870fd1e94474b3fd3e0ab1b8c4))
|
|
10
|
+
* Updated shim classes to no longer construct specs. ([#2096](https://github.com/newrelic/node-newrelic/pull/2096)) ([158c295](https://github.com/newrelic/node-newrelic/commit/158c29566f6a5993ec77f84aeaa266ceab0bf4f0))
|
|
28
11
|
|
|
29
12
|
#### Miscellaneous chores
|
|
30
13
|
|
|
31
|
-
*
|
|
14
|
+
* **deps-dev:** Bumped express from 4.18.2 to 4.19.2 ([#2101](https://github.com/newrelic/node-newrelic/pull/2101)) ([639cb78](https://github.com/newrelic/node-newrelic/commit/639cb785dff7568ad227091512013c2dfb81e5f9))
|
|
15
|
+
* **deps:** Updated @newrelic/security-agent to v1.1.1 ([#2092](https://github.com/newrelic/node-newrelic/pull/2092)) ([3272aa3](https://github.com/newrelic/node-newrelic/commit/3272aa3da2260ce18c71c24608ffdda512ca6817))
|
|
16
|
+
* Fixed incorrect pinning of @elastic/transport ([#2120](https://github.com/newrelic/node-newrelic/pull/2120)) ([7b5bdaa](https://github.com/newrelic/node-newrelic/commit/7b5bdaac1b1081636636cd7ca7c6b484f5251f76))
|
|
17
|
+
* Removed scrollbar styling in generated API docs ([#2091](https://github.com/newrelic/node-newrelic/pull/2091)) ([cb0fa11](https://github.com/newrelic/node-newrelic/commit/cb0fa11c81290bb93cb30e974fdb1ece82a1e80e))
|
|
18
|
+
* Removed transaction_id and legacy token count attributes from llm events for openai and langchain ([#2093](https://github.com/newrelic/node-newrelic/pull/2093)) ([df2a0fd](https://github.com/newrelic/node-newrelic/commit/df2a0fd7c99a7bbf024c1e33c7fdff512b45c970))
|
|
32
19
|
|
|
33
20
|
#### Tests
|
|
34
21
|
|
|
35
|
-
* Updated
|
|
22
|
+
* Updated test/integration/core/dns reverse test to remove flakiness ([#2121](https://github.com/newrelic/node-newrelic/pull/2121)) ([c32cb27](https://github.com/newrelic/node-newrelic/commit/c32cb2739ece3adcf5bd42e646071b3f59e691ba))
|
|
23
|
+
* Updated elastic tests to skip broken version ([#2119](https://github.com/newrelic/node-newrelic/pull/2119)) ([5d0d1bb](https://github.com/newrelic/node-newrelic/commit/5d0d1bb4994b41d43ab9b4eb110fea036ac307bc))
|
|
24
|
+
|
|
25
|
+
#### Continuous integration
|
|
36
26
|
|
|
27
|
+
* Removed usage of `use_new_release` from prepare release workflow ([#2124](https://github.com/newrelic/node-newrelic/pull/2124)) ([007ddb4](https://github.com/newrelic/node-newrelic/commit/007ddb4dce6cf5ab463a1868fe4cfa203d3e9ff2))
|
|
28
|
+
* Updated `prepare-release.js` to not require changelog.json ([#2106](https://github.com/newrelic/node-newrelic/pull/2106)) ([328a570](https://github.com/newrelic/node-newrelic/commit/328a570bbe9f359d23a21317ccd8a8bc52b473b4))
|
|
29
|
+
* Updated prepare release to provide a drop down for release type ([#2133](https://github.com/newrelic/node-newrelic/pull/2133)) ([846269b](https://github.com/newrelic/node-newrelic/commit/846269bb256f287c5fb9be32bdb62e9786e3cfe4))
|
|
30
|
+
* Updated versioned security agent workflow ([#2100](https://github.com/newrelic/node-newrelic/pull/2100)) ([f787b15](https://github.com/newrelic/node-newrelic/commit/f787b15f94c416d547af1ab4b2d7c31665b417b7))
|
|
31
|
+
* Fixed typo in constant name for prepare release script ([#2094](https://github.com/newrelic/node-newrelic/pull/2094)) ([3b887d9](https://github.com/newrelic/node-newrelic/commit/3b887d96c70a2cc5e3833cdc8b65de99b643f7a1))
|
|
32
|
+
|
|
33
|
+
### v11.14.0 (2024-03-20)
|
|
34
|
+
|
|
35
|
+
#### Features
|
|
36
|
+
|
|
37
|
+
* Added `guid` attribute to `TransactionError` events ([#2079](https://github.com/newrelic/node-newrelic/pull/2079)) ([3468fb1](https://github.com/newrelic/node-newrelic/commit/3468fb14635b10c30a9a814dc0d084aeacfd9e10))
|
|
38
|
+
* Added instrumentation for `initializeUnorderedBulkOp`, and `initializeOrderedBulkOp` in mongodb 4+ ([#2086](https://github.com/newrelic/node-newrelic/pull/2086)) ([666ae6e](https://github.com/newrelic/node-newrelic/commit/666ae6ea4be8167748e31fe9b1d086aee5d0135d))
|
|
39
|
+
* Added support for Mongo v5+ ([#2085](https://github.com/newrelic/node-newrelic/pull/2085)) ([00f6feb](https://github.com/newrelic/node-newrelic/commit/00f6febb4893ed2abe902644514af3ab629cdbc1))
|
|
40
|
+
|
|
41
|
+
#### Security improvements
|
|
42
|
+
|
|
43
|
+
* **deps:** bump follow-redirects from 1.15.5 to 1.15.6 ([#2078](https://github.com/newrelic/node-newrelic/pull/2078)) ([aa86482](https://github.com/newrelic/node-newrelic/commit/aa86482738ba6b17bf6c2c7362931a3ad57736dd))
|
|
44
|
+
|
|
45
|
+
#### Documentation
|
|
46
|
+
|
|
47
|
+
* Changed bug bounty URL ([#2081](https://github.com/newrelic/node-newrelic/pull/2081)) ([f4586d7](https://github.com/newrelic/node-newrelic/commit/f4586d71cbe9c886181fbfe4b414cf0f9d630873))
|
|
48
|
+
|
|
49
|
+
#### Miscellaneous chores
|
|
50
|
+
|
|
51
|
+
* Added instrumentation tracking class ([#2084](https://github.com/newrelic/node-newrelic/pull/2084)) ([07d7e7d](https://github.com/newrelic/node-newrelic/commit/07d7e7d50edf9cd8a1cd1b465b24bc589409c5dc))
|
|
52
|
+
* **deps:** pin @newrelic/security-agent to 1.0.1 ([#2089](https://github.com/newrelic/node-newrelic/pull/2089)) ([e133c76](https://github.com/newrelic/node-newrelic/commit/e133c76a34f7d2af16610f00958651a6cff8824d))
|
|
53
|
+
|
|
54
|
+
### v11.13.0 (2024-03-13)
|
|
55
|
+
|
|
56
|
+
#### Features
|
|
57
|
+
|
|
58
|
+
* Added AI Monitoring(AIM) for OpenAI, Amazon Bedrock, and Langchain.
|
|
59
|
+
* To enable set `config.ai_monitoring.enabled` or `NEW_RELIC_AI_MONITORING_ENABLED` to `true`.
|
|
60
|
+
* It is recommended for a full experience to set `config.span_events.max_samples_stored` to `10000`, `config.custom_insights_events.max_samples_stored` to `100000`, and `config.distributed_tracing.enabled` should not be set to false.
|
|
61
|
+
* **Note**: Enabling [high-security mode](https://docs.newrelic.com/docs/apm/agents/manage-apm-agents/configuration/high-security-mode/) will disable the AIM instrumentation and events.
|
|
62
|
+
* Added instrumentation for VectorStore.similaritySearch for langchain.js ([#2049](https://github.com/newrelic/node-newrelic/pull/2049)) ([3c50606](https://github.com/newrelic/node-newrelic/commit/3c50606a57a8dc18c91fe36e3b180bafd15a4cbc))
|
|
63
|
+
* Added setLlmTokenCountCallback API endpoint to register a callback for calculating token count when none is provided ([#2065](https://github.com/newrelic/node-newrelic/pull/2065)) ([d2faf1a](https://github.com/newrelic/node-newrelic/commit/d2faf1a4942aacefd8b92e0bc2dc11bd8b687328))
|
|
64
|
+
* Added token_count to LlmEmbedding and LlmChatCompletionMessage for openai ([#2061](https://github.com/newrelic/node-newrelic/pull/2061)) ([47a925e](https://github.com/newrelic/node-newrelic/commit/47a925eccce8e5b5d682b46277bbef5191f8b553))
|
|
65
|
+
* Added tool_id to langchain error event ([#2064](https://github.com/newrelic/node-newrelic/pull/2064)) ([793abe8](https://github.com/newrelic/node-newrelic/commit/793abe8c9854b80fb1cf42f839a7db6a646cdc0b))
|
|
66
|
+
|
|
67
|
+
#### Miscellaneous chores
|
|
68
|
+
|
|
69
|
+
* Added flag for verbosity during docs publishing ([#2060](https://github.com/newrelic/node-newrelic/pull/2060)) ([fe0d41a](https://github.com/newrelic/node-newrelic/commit/fe0d41a86cba8da6173f5935e61c62b7dca75344))
|
|
70
|
+
* Added some delays to docs publishing ([#2062](https://github.com/newrelic/node-newrelic/pull/2062)) ([a602fd4](https://github.com/newrelic/node-newrelic/commit/a602fd48e929437e4bc933c4ce276989013c53f1))
|
|
71
|
+
* Changed casing of OpenAI in vendor property ([#2068](https://github.com/newrelic/node-newrelic/pull/2068)) ([64b4ca2](https://github.com/newrelic/node-newrelic/commit/64b4ca2750c9de8d9028fef515c15019e358a5d9))
|
|
72
|
+
* Changed token_count to only use tokenCountCallback ([#2070](https://github.com/newrelic/node-newrelic/pull/2070)) ([66f94b0](https://github.com/newrelic/node-newrelic/commit/66f94b05aa7018af6fa1db1d2d87de9013f23a5b))
|
|
73
|
+
* Removed langchain_instrumentation feature flag as the instrumentation is feature complete ([#2073](https://github.com/newrelic/node-newrelic/pull/2073)) ([925a463](https://github.com/newrelic/node-newrelic/commit/925a463c708b29c78567aecf78ac89ac226b7995))
|
|
74
|
+
* updated @newrelic/aws-sdk and @newrelic/koa to latest ([#2074](https://github.com/newrelic/node-newrelic/pull/2074)) ([0747ca4](https://github.com/newrelic/node-newrelic/commit/0747ca4f0f6615e1fbfcc734a36059960facf23e))
|
|
75
|
+
|
|
76
|
+
### v11.12.0 (2024-03-04)
|
|
77
|
+
|
|
78
|
+
#### Features
|
|
79
|
+
|
|
80
|
+
* Added instrumentation for `chain.stream` for langchain js. ([#2052](https://github.com/newrelic/node-newrelic/pull/2052)) ([03abfce](https://github.com/newrelic/node-newrelic/commit/03abfce666d3c48abd0994c44817bb5cbe8655a9))
|
|
81
|
+
|
|
82
|
+
#### Miscellaneous chores
|
|
83
|
+
|
|
84
|
+
* Added @azure/openai and @langchain/community/llms/bedrock as tracking packages so we can measure usage with angler ([#2053](https://github.com/newrelic/node-newrelic/pull/2053)) ([4830ea3](https://github.com/newrelic/node-newrelic/commit/4830ea3285726f8cc8fb60820c4cf2d3790e5250))
|
|
85
|
+
|
|
86
|
+
#### Tests
|
|
87
|
+
|
|
88
|
+
* Updated aws-sdk branch to main as the necessary code was merged. ([#2051](https://github.com/newrelic/node-newrelic/pull/2051)) ([1e52a5c](https://github.com/newrelic/node-newrelic/commit/1e52a5cd7a8acc8970dbdc6b1bf774c06aa6f5fb))
|
|
89
|
+
|
|
37
90
|
### v11.11.0 (2024-02-27)
|
|
38
91
|
|
|
39
92
|
#### Features
|
package/README.md
CHANGED
|
@@ -234,7 +234,7 @@ If you have any questions, or to execute our corporate CLA, required if your con
|
|
|
234
234
|
|
|
235
235
|
As noted in our [security policy](../../security/policy), New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.
|
|
236
236
|
|
|
237
|
-
If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through [
|
|
237
|
+
If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through [our bug bounty program](https://docs.newrelic.com/docs/security/security-privacy/information-security/report-security-vulnerabilities/).
|
|
238
238
|
|
|
239
239
|
If you would like to contribute to this project, review [these guidelines](./CONTRIBUTING.md).
|
|
240
240
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -712,7 +712,7 @@ This product includes source derived from [@newrelic/aws-sdk](https://github.com
|
|
|
712
712
|
|
|
713
713
|
### @newrelic/koa
|
|
714
714
|
|
|
715
|
-
This product includes source derived from [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa) ([v9.
|
|
715
|
+
This product includes source derived from [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa) ([v9.1.0](https://github.com/newrelic/node-newrelic-koa/tree/v9.1.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-koa/blob/v9.1.0/LICENSE):
|
|
716
716
|
|
|
717
717
|
```
|
|
718
718
|
Apache License
|
|
@@ -951,7 +951,7 @@ SOFTWARE.
|
|
|
951
951
|
|
|
952
952
|
### @newrelic/security-agent
|
|
953
953
|
|
|
954
|
-
This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.
|
|
954
|
+
This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.1.1](https://github.com/newrelic/csec-node-agent/tree/v1.1.1)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v1.1.1/LICENSE):
|
|
955
955
|
|
|
956
956
|
```
|
|
957
957
|
## New Relic Software License v1.0
|
package/api.js
CHANGED
|
@@ -26,7 +26,7 @@ const {
|
|
|
26
26
|
const LlmFeedbackMessage = require('./lib/llm-events/feedback-message')
|
|
27
27
|
|
|
28
28
|
const ATTR_DEST = require('./lib/config/attribute-filter').DESTINATIONS
|
|
29
|
-
const MODULE_TYPE = require('./lib/
|
|
29
|
+
const MODULE_TYPE = require('./lib/instrumentation-descriptor').TYPES
|
|
30
30
|
const NAMES = require('./lib/metrics/names')
|
|
31
31
|
const obfuscate = require('./lib/util/sql/obfuscate')
|
|
32
32
|
const { DESTINATIONS } = require('./lib/config/attribute-filter')
|
package/lib/errors/index.js
CHANGED
|
@@ -28,7 +28,9 @@ module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
|
|
|
28
28
|
shim.recordOperation(
|
|
29
29
|
ClientProto,
|
|
30
30
|
['connect', 'shutdown'],
|
|
31
|
-
|
|
31
|
+
function operationSpec(shim, _fn, name) {
|
|
32
|
+
return new OperationSpec({ callback: shim.LAST, name })
|
|
33
|
+
}
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
if (semver.satisfies(cassandraVersion, '>=4.4.0')) {
|
|
@@ -11,7 +11,6 @@ const {
|
|
|
11
11
|
} = require('../../shim/specs')
|
|
12
12
|
const { CURSOR_OPS, COLLECTION_OPS, DB_OPS } = require('./constants')
|
|
13
13
|
const common = module.exports
|
|
14
|
-
common.NR_ATTRS = Symbol('NR_ATTRS')
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Instruments all methods from constants.CURSOR_OPS on a given
|
|
@@ -23,12 +22,9 @@ common.NR_ATTRS = Symbol('NR_ATTRS')
|
|
|
23
22
|
common.instrumentCursor = function instrumentCursor(shim, Cursor) {
|
|
24
23
|
if (Cursor && Cursor.prototype) {
|
|
25
24
|
const proto = Cursor.prototype
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
shim.recordQuery(proto, 'each', common.makeQueryDescFunc(shim, 'each'))
|
|
31
|
-
shim.recordOperation(proto, 'pipe', new OperationSpec({ opaque: true }))
|
|
25
|
+
shim.recordQuery(proto, CURSOR_OPS, common.makeQueryDescFunc)
|
|
26
|
+
shim.recordQuery(proto, 'each', common.makeQueryDescFunc)
|
|
27
|
+
shim.recordOperation(proto, 'pipe', new OperationSpec({ opaque: true, name: 'pipe' }))
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
30
|
|
|
@@ -42,9 +38,7 @@ common.instrumentCursor = function instrumentCursor(shim, Cursor) {
|
|
|
42
38
|
common.instrumentCollection = function instrumentCollection(shim, Collection) {
|
|
43
39
|
if (Collection && Collection.prototype) {
|
|
44
40
|
const proto = Collection.prototype
|
|
45
|
-
|
|
46
|
-
shim.recordQuery(proto, COLLECTION_OPS[i], common.makeQueryDescFunc(shim, COLLECTION_OPS[i]))
|
|
47
|
-
}
|
|
41
|
+
shim.recordQuery(proto, COLLECTION_OPS, common.makeQueryDescFunc)
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
44
|
|
|
@@ -72,9 +66,20 @@ common.instrumentBulkOperation = function instrumentBulkOperation(shim, BulkOper
|
|
|
72
66
|
common.instrumentDb = function instrumentDb(shim, Db) {
|
|
73
67
|
if (Db && Db.prototype) {
|
|
74
68
|
const proto = Db.prototype
|
|
75
|
-
shim.recordOperation(proto, DB_OPS,
|
|
69
|
+
shim.recordOperation(proto, DB_OPS, function makeOperationDescFunc(shim, _fn, methodName) {
|
|
70
|
+
return new OperationSpec({
|
|
71
|
+
callback: shim.LAST,
|
|
72
|
+
opaque: true,
|
|
73
|
+
promise: true,
|
|
74
|
+
name: methodName
|
|
75
|
+
})
|
|
76
|
+
})
|
|
76
77
|
// link to client.connect(removed in v4.0)
|
|
77
|
-
shim.recordOperation(
|
|
78
|
+
shim.recordOperation(
|
|
79
|
+
Db,
|
|
80
|
+
'connect',
|
|
81
|
+
new OperationSpec({ callback: shim.LAST, promise: true, name: 'connect' })
|
|
82
|
+
)
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
|
|
@@ -82,29 +87,26 @@ common.instrumentDb = function instrumentDb(shim, Db) {
|
|
|
82
87
|
* Sets up the desc for all instrumented query methods
|
|
83
88
|
*
|
|
84
89
|
* @param {Shim} shim instance of shim
|
|
85
|
-
* @param {
|
|
86
|
-
* @
|
|
90
|
+
* @param {Function} _fn function getting instrumented
|
|
91
|
+
* @param {string} methodName name of function
|
|
92
|
+
* @returns {QuerySpec} query spec
|
|
87
93
|
*/
|
|
88
|
-
common.makeQueryDescFunc = function makeQueryDescFunc(shim, methodName) {
|
|
94
|
+
common.makeQueryDescFunc = function makeQueryDescFunc(shim, _fn, methodName) {
|
|
89
95
|
if (methodName === 'each') {
|
|
90
|
-
return function eachDescFunc() {
|
|
91
|
-
const parameters = getInstanceAttributeParameters(shim, this)
|
|
92
|
-
return new QuerySpec({ query: methodName, parameters, rowCallback: shim.LAST, opaque: true })
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return function queryDescFunc() {
|
|
97
|
-
// segment name does not actually use query string
|
|
98
|
-
// method name is set as query so the query parser has access to the op name
|
|
99
96
|
const parameters = getInstanceAttributeParameters(shim, this)
|
|
100
|
-
return new QuerySpec({
|
|
101
|
-
query: methodName,
|
|
102
|
-
parameters,
|
|
103
|
-
promise: true,
|
|
104
|
-
callback: shim.LAST,
|
|
105
|
-
opaque: true
|
|
106
|
-
})
|
|
97
|
+
return new QuerySpec({ query: methodName, parameters, rowCallback: shim.LAST, opaque: true })
|
|
107
98
|
}
|
|
99
|
+
|
|
100
|
+
// segment name does not actually use query string
|
|
101
|
+
// method name is set as query so the query parser has access to the op name
|
|
102
|
+
const parameters = getInstanceAttributeParameters(shim, this)
|
|
103
|
+
return new QuerySpec({
|
|
104
|
+
query: methodName,
|
|
105
|
+
parameters,
|
|
106
|
+
promise: true,
|
|
107
|
+
callback: shim.LAST,
|
|
108
|
+
opaque: true
|
|
109
|
+
})
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
/**
|
|
@@ -133,7 +135,7 @@ common.makeBulkDescFunc = function makeBulkDescFunc(shim) {
|
|
|
133
135
|
*
|
|
134
136
|
* @param {Shim} shim instance of shim
|
|
135
137
|
* @param {object} instrumenter instance of mongo APM class
|
|
136
|
-
* @param {object} [options
|
|
138
|
+
* @param {object} [options] provide command names to skip updating host/port as they are unrelated to the active query. This is only in v3 because after every command is runs `endSessions` which runs on the admin database
|
|
137
139
|
*/
|
|
138
140
|
common.captureAttributesOnStarted = function captureAttributesOnStarted(
|
|
139
141
|
shim,
|
|
@@ -152,13 +154,10 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(
|
|
|
152
154
|
if (connId) {
|
|
153
155
|
// used in v3 when connection is a cluster pool
|
|
154
156
|
if (typeof connId === 'number') {
|
|
155
|
-
setHostPort(shim, evnt.address, evnt.databaseName
|
|
157
|
+
setHostPort(shim, evnt.address, evnt.databaseName)
|
|
156
158
|
// used in v3 when connection is to 1 host
|
|
157
159
|
} else if (typeof connId === 'string') {
|
|
158
160
|
setHostPort(shim, connId, evnt.databaseName)
|
|
159
|
-
// v2 contains `domainSocket`, get socket connection from `host`
|
|
160
|
-
} else if (connId.domainSocket) {
|
|
161
|
-
shim.captureInstanceAttributes('localhost', connId.host, evnt.databaseName)
|
|
162
161
|
// v2 remote connection get `host` `port` from respective properties
|
|
163
162
|
} else {
|
|
164
163
|
shim.captureInstanceAttributes(connId.host, connId.port, evnt.databaseName)
|
|
@@ -169,37 +168,14 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(
|
|
|
169
168
|
|
|
170
169
|
/**
|
|
171
170
|
* Extracts the host and port from a connection string
|
|
172
|
-
* This also handles if connection string is a domain socket
|
|
173
|
-
* Mongo sticks the path to the domain socket in the "host" slot, but we
|
|
174
|
-
* want it in the "port", so if we have a domain socket we need to change
|
|
175
|
-
* the order of our parameters.
|
|
176
171
|
*
|
|
177
172
|
* @param {Shim} shim instance of shim
|
|
178
173
|
* @param {string} connStr mongo connection string
|
|
179
174
|
* @param {string} db database name
|
|
180
|
-
* @param {object} client mongo client instance
|
|
181
175
|
*/
|
|
182
|
-
function setHostPort(shim, connStr, db
|
|
176
|
+
function setHostPort(shim, connStr, db) {
|
|
183
177
|
const parts = common.parseAddress(connStr)
|
|
184
|
-
|
|
185
|
-
// the address is `undefined:undefined`. we will instead attempt
|
|
186
|
-
// to get connection details from the client symbol NR_ATTRS
|
|
187
|
-
// added in `lib/instrumentation/mongodb/v3-mongo` when a client connects
|
|
188
|
-
// with a URL string
|
|
189
|
-
if (parts.includes('undefined')) {
|
|
190
|
-
try {
|
|
191
|
-
const attrs = client[common.NR_ATTRS]
|
|
192
|
-
const socket = decodeURIComponent(attrs.split(',')[0].split('mongodb://')[1])
|
|
193
|
-
shim.captureInstanceAttributes('localhost', socket, db)
|
|
194
|
-
} catch (err) {
|
|
195
|
-
shim.logger.debug(err, 'Could not extract host/port from mongo command')
|
|
196
|
-
}
|
|
197
|
-
// connected using domain socket but the "host"(e.g: /path/to/mongo-socket-port.sock)
|
|
198
|
-
} else if (parts.length && parts[0][0] === '/') {
|
|
199
|
-
shim.captureInstanceAttributes('localhost', parts[0], db)
|
|
200
|
-
} else {
|
|
201
|
-
shim.captureInstanceAttributes(parts[0], parts[1], db)
|
|
202
|
-
}
|
|
178
|
+
shim.captureInstanceAttributes(parts[0], parts[1], db)
|
|
203
179
|
}
|
|
204
180
|
|
|
205
181
|
/**
|
|
@@ -214,7 +190,6 @@ function setHostPort(shim, connStr, db, client) {
|
|
|
214
190
|
*/
|
|
215
191
|
function getInstanceAttributeParameters(shim, mongo) {
|
|
216
192
|
let params
|
|
217
|
-
|
|
218
193
|
if (mongo?.s?.topology) {
|
|
219
194
|
shim.logger.trace('Adding datastore instance attributes from mongo.s.db + mongo.s.topology')
|
|
220
195
|
const databaseName = mongo?.s?.db?.databaseName || mongo?.s?.namespace?.db || null
|
|
@@ -224,6 +199,10 @@ function getInstanceAttributeParameters(shim, mongo) {
|
|
|
224
199
|
const databaseName = mongo?.s?.db?.databaseName || null
|
|
225
200
|
const hosts = mongo.s.db.s.client.s.options.hosts
|
|
226
201
|
params = getParametersFromHosts(hosts, databaseName)
|
|
202
|
+
} else if (mongo?.s?.db?.client?.topology) {
|
|
203
|
+
const databaseName = mongo?.s?.namespace?.db
|
|
204
|
+
const topology = mongo.s.db.client.topology
|
|
205
|
+
params = getParametersFromTopology(topology, databaseName)
|
|
227
206
|
} else {
|
|
228
207
|
shim.logger.trace('Could not find datastore instance attributes.')
|
|
229
208
|
params = new DatastoreParameters()
|
|
@@ -240,13 +219,8 @@ function getInstanceAttributeParameters(shim, mongo) {
|
|
|
240
219
|
* @returns {object} db params
|
|
241
220
|
*/
|
|
242
221
|
function getParametersFromHosts(hosts, database) {
|
|
243
|
-
|
|
244
|
-
const [{ socketPath }] = hosts
|
|
222
|
+
const [{ host, port }] = hosts
|
|
245
223
|
|
|
246
|
-
if (socketPath) {
|
|
247
|
-
port = socketPath
|
|
248
|
-
host = 'localhost'
|
|
249
|
-
}
|
|
250
224
|
return new DatastoreParameters({
|
|
251
225
|
host,
|
|
252
226
|
port_path_or_id: port,
|
|
@@ -272,15 +246,13 @@ function getParametersFromTopology(conf, database) {
|
|
|
272
246
|
;[{ host, port }] = conf.s.options.servers
|
|
273
247
|
}
|
|
274
248
|
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
port = host
|
|
279
|
-
host = 'localhost'
|
|
249
|
+
// hosts is an array but we will always pull the first for consistency
|
|
250
|
+
if (conf?.s?.options?.hosts?.length) {
|
|
251
|
+
;[{ host, port }] = conf.s.options.hosts
|
|
280
252
|
}
|
|
281
253
|
|
|
282
254
|
return new DatastoreParameters({
|
|
283
|
-
host
|
|
255
|
+
host,
|
|
284
256
|
port_path_or_id: port,
|
|
285
257
|
database_name: database
|
|
286
258
|
})
|
|
@@ -38,7 +38,7 @@ module.exports = function instrument(shim, mongodb) {
|
|
|
38
38
|
const recordDesc = {
|
|
39
39
|
Gridstore: {
|
|
40
40
|
isQuery: false,
|
|
41
|
-
makeDescFunc: function makeGridDesc(opName) {
|
|
41
|
+
makeDescFunc: function makeGridDesc(shim, fn, opName) {
|
|
42
42
|
return new OperationSpec({ name: 'GridFS-' + opName, callback: shim.LAST })
|
|
43
43
|
}
|
|
44
44
|
},
|
|
@@ -50,8 +50,8 @@ module.exports = function instrument(shim, mongodb) {
|
|
|
50
50
|
Collection: { isQuery: true, makeDescFunc: makeQueryDescFunc },
|
|
51
51
|
Db: {
|
|
52
52
|
isQuery: false,
|
|
53
|
-
makeDescFunc: function makeDbDesc() {
|
|
54
|
-
return new OperationSpec({ callback: shim.LAST })
|
|
53
|
+
makeDescFunc: function makeDbDesc(shim, fn, method) {
|
|
54
|
+
return new OperationSpec({ callback: shim.LAST, name: method })
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -95,10 +95,10 @@ module.exports = function instrument(shim, mongodb) {
|
|
|
95
95
|
const { isQuery, makeDescFunc } = recordDesc[objectName]
|
|
96
96
|
const proto = object.prototype
|
|
97
97
|
if (isQuery) {
|
|
98
|
-
shim.recordQuery(proto, method, makeDescFunc
|
|
98
|
+
shim.recordQuery(proto, method, makeDescFunc)
|
|
99
99
|
} else if (isQuery === false) {
|
|
100
100
|
// could be unset
|
|
101
|
-
shim.recordOperation(proto, method, makeDescFunc
|
|
101
|
+
shim.recordOperation(proto, method, makeDescFunc)
|
|
102
102
|
} else {
|
|
103
103
|
shim.logger.trace('No wrapping method found for %s', objectName)
|
|
104
104
|
}
|
|
@@ -108,7 +108,11 @@ module.exports = function instrument(shim, mongodb) {
|
|
|
108
108
|
// the cursor object implements Readable stream and internally calls nextObject on
|
|
109
109
|
// each read, in which case we do not want to record each nextObject() call
|
|
110
110
|
if (/Cursor$/.test(objectName)) {
|
|
111
|
-
shim.recordOperation(
|
|
111
|
+
shim.recordOperation(
|
|
112
|
+
object.prototype,
|
|
113
|
+
'pipe',
|
|
114
|
+
new OperationSpec({ opaque: true, name: 'pipe' })
|
|
115
|
+
)
|
|
112
116
|
}
|
|
113
117
|
}
|
|
114
118
|
}
|
|
@@ -11,15 +11,15 @@ const {
|
|
|
11
11
|
instrumentBulkOperation,
|
|
12
12
|
instrumentCollection,
|
|
13
13
|
instrumentCursor,
|
|
14
|
-
instrumentDb
|
|
15
|
-
NR_ATTRS
|
|
14
|
+
instrumentDb
|
|
16
15
|
} = require('./common')
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* parser used to grab the collection and operation
|
|
20
19
|
* on every mongo operation
|
|
21
20
|
*
|
|
22
|
-
* @param {object} operation
|
|
21
|
+
* @param {object} operation mongodb operation
|
|
22
|
+
* @returns {object} { operation, collection } parsed operation and collection
|
|
23
23
|
*/
|
|
24
24
|
function queryParser(operation) {
|
|
25
25
|
let collection = this.collectionName || 'unknown'
|
|
@@ -40,15 +40,12 @@ function queryParser(operation) {
|
|
|
40
40
|
* to a Symbol on the MongoClient to be used later to extract the host/port in cases where the topology
|
|
41
41
|
* is a cluster of domain sockets
|
|
42
42
|
*
|
|
43
|
-
* @param {Shim} shim
|
|
43
|
+
* @param {Shim} shim instance of shim
|
|
44
44
|
* @param {object} mongodb resolved package
|
|
45
45
|
*/
|
|
46
46
|
function instrumentClient(shim, mongodb) {
|
|
47
|
-
shim.recordOperation(mongodb.MongoClient, 'connect', function wrappedConnect(shim
|
|
48
|
-
|
|
49
|
-
// captureAttributesOnStarted listener
|
|
50
|
-
this[NR_ATTRS] = args[0]
|
|
51
|
-
return new RecorderSpec({ callback: shim.LAST })
|
|
47
|
+
shim.recordOperation(mongodb.MongoClient, 'connect', function wrappedConnect(shim) {
|
|
48
|
+
return new RecorderSpec({ callback: shim.LAST, name: 'connect' })
|
|
52
49
|
})
|
|
53
50
|
}
|
|
54
51
|
|
|
@@ -61,7 +58,7 @@ function instrumentClient(shim, mongodb) {
|
|
|
61
58
|
* as well as sets up a listener for when commands start to properly
|
|
62
59
|
* add necessary attributes to segments
|
|
63
60
|
*
|
|
64
|
-
* @param {Shim} shim
|
|
61
|
+
* @param {Shim} shim instance of shim
|
|
65
62
|
* @param {object} mongodb resolved package
|
|
66
63
|
*/
|
|
67
64
|
module.exports = function instrument(shim, mongodb) {
|
|
@@ -6,20 +6,30 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const { OperationSpec } = require('../../shim/specs')
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
instrumentBulkOperation,
|
|
11
|
+
instrumentCollection,
|
|
12
|
+
instrumentCursor,
|
|
13
|
+
instrumentDb,
|
|
14
|
+
parseAddress
|
|
15
|
+
} = require('./common')
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
18
|
* parser used to grab the collection and operation
|
|
13
19
|
* from a running query
|
|
14
20
|
*
|
|
15
|
-
* @param {object} operation
|
|
21
|
+
* @param {object} operation mongodb operation
|
|
22
|
+
* @returns {object} { operation, collection } parsed operation and collection
|
|
16
23
|
*/
|
|
17
24
|
function queryParser(operation) {
|
|
18
25
|
let collection = this.collectionName || 'unknown'
|
|
19
26
|
|
|
20
27
|
// cursor methods have collection on namespace.collection
|
|
21
|
-
if (this
|
|
28
|
+
if (this?.namespace?.collection) {
|
|
22
29
|
collection = this.namespace.collection
|
|
30
|
+
// (un)ordered bulk operations have collection on different key
|
|
31
|
+
} else if (this?.s?.collection?.collectionName) {
|
|
32
|
+
collection = this.s.collection.collectionName
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
return { operation, collection }
|
|
@@ -30,23 +40,15 @@ function queryParser(operation) {
|
|
|
30
40
|
* update host, port and database_name
|
|
31
41
|
* on segment attributes
|
|
32
42
|
*
|
|
33
|
-
* @param {Shim} shim
|
|
34
|
-
* @param {CommandStartedEvent} evnt
|
|
43
|
+
* @param {Shim} shim instance of shim
|
|
44
|
+
* @param {CommandStartedEvent} evnt mongodb event
|
|
35
45
|
*/
|
|
36
46
|
function cmdStartedHandler(shim, evnt) {
|
|
37
47
|
if (evnt.connectionId) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// which looks like mongodb:///tmp/mongodb-27017.sock"
|
|
43
|
-
if (['undefined'].includes(host, port)) {
|
|
44
|
-
host = 'localhost'
|
|
45
|
-
const hosts = this.s.options.hosts
|
|
46
|
-
if (hosts && hosts.length && hosts[0].socketPath) {
|
|
47
|
-
port = hosts[0].socketPath
|
|
48
|
-
}
|
|
49
|
-
} else if (['127.0.0.1', '::1', '[::1]'].includes(host)) {
|
|
48
|
+
const address = parseAddress(evnt.address)
|
|
49
|
+
let [host] = address
|
|
50
|
+
const [, port] = address
|
|
51
|
+
if (['127.0.0.1', '::1', '[::1]'].includes(host)) {
|
|
50
52
|
host = 'localhost'
|
|
51
53
|
}
|
|
52
54
|
|
|
@@ -59,12 +61,13 @@ function cmdStartedHandler(shim, evnt) {
|
|
|
59
61
|
* enable APM(monitorCommands) and add the
|
|
60
62
|
* `commandStarted` listener
|
|
61
63
|
*
|
|
62
|
-
* @param {Shim} shim
|
|
64
|
+
* @param {Shim} shim instance of shim
|
|
65
|
+
* @returns {OperationSpec} spec to capture connect method
|
|
63
66
|
*/
|
|
64
67
|
function wrapConnect(shim) {
|
|
65
68
|
this.monitorCommands = true
|
|
66
69
|
this.on('commandStarted', cmdStartedHandler.bind(this, shim))
|
|
67
|
-
return new OperationSpec({ callback: shim.LAST })
|
|
70
|
+
return new OperationSpec({ callback: shim.LAST, name: 'connect' })
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
/**
|
|
@@ -73,7 +76,7 @@ function wrapConnect(shim) {
|
|
|
73
76
|
* so we can properly update the segment attributes with a more accurate
|
|
74
77
|
* host/port/database name
|
|
75
78
|
*
|
|
76
|
-
* @param {Shim} shim
|
|
79
|
+
* @param {Shim} shim instance of shim
|
|
77
80
|
* @param {MongoClient} MongoClient reference
|
|
78
81
|
*/
|
|
79
82
|
function instrumentMongoClient(shim, MongoClient) {
|
|
@@ -88,4 +91,5 @@ module.exports = function instrument(shim, mongodb) {
|
|
|
88
91
|
instrumentCursor(shim, mongodb.AggregationCursor)
|
|
89
92
|
instrumentCollection(shim, mongodb.Collection)
|
|
90
93
|
instrumentDb(shim, mongodb.Db)
|
|
94
|
+
instrumentBulkOperation(shim, shim.require('./lib/bulk/common'))
|
|
91
95
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const { nrEsmProxy } = require('../symbols')
|
|
9
|
-
const { RecorderSpec, QuerySpec } = require('../shim/specs')
|
|
9
|
+
const { RecorderSpec, QuerySpec, ClassWrapSpec } = require('../shim/specs')
|
|
10
10
|
const DatastoreParameters = require('../shim/specs/params/datastore')
|
|
11
11
|
|
|
12
12
|
function getQuery(shim, original, name, args) {
|
|
@@ -58,12 +58,12 @@ module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
|
58
58
|
// wrapping for native
|
|
59
59
|
function instrumentPGNative(pg) {
|
|
60
60
|
shim.wrapReturn(pg, 'Client', clientFactoryWrapper)
|
|
61
|
-
shim.wrapClass(pg, 'Pool', { post: poolPostConstructor, es6: true })
|
|
61
|
+
shim.wrapClass(pg, 'Pool', new ClassWrapSpec({ post: poolPostConstructor, es6: true }))
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
function poolPostConstructor(shim) {
|
|
65
65
|
if (!shim.isWrapped(this.Client)) {
|
|
66
|
-
shim.wrapClass(this, 'Client', clientPostConstructor)
|
|
66
|
+
shim.wrapClass(this, 'Client', new ClassWrapSpec({ post: clientPostConstructor }))
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|