newrelic 8.5.1 → 8.7.1
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 +80 -0
- package/THIRD_PARTY_NOTICES.md +3 -3
- package/api.js +103 -136
- package/lib/agent.js +11 -2
- package/lib/config/index.js +11 -8
- package/lib/context-manager/create-context-manager.js +32 -0
- package/lib/context-manager/diagnostics/legacy-diagnostic-context-manager.js +36 -0
- package/lib/context-manager/legacy-context-manager.js +66 -0
- package/lib/instrumentation/promise.js +28 -41
- package/lib/metrics/names.js +5 -1
- package/lib/serverless/aws-lambda.js +8 -2
- package/lib/shim/message-shim.js +45 -90
- package/lib/shim/shim.js +139 -324
- package/lib/shim/transaction-shim.js +9 -39
- package/lib/shimmer.js +171 -11
- package/lib/transaction/tracer/index.js +22 -29
- package/package.json +7 -5
package/NEWS.md
CHANGED
|
@@ -1,3 +1,83 @@
|
|
|
1
|
+
### v8.7.1 (2022-01-18)
|
|
2
|
+
|
|
3
|
+
* Bumped @newrelic/aws-sdk to ^4.1.1.
|
|
4
|
+
|
|
5
|
+
* Upgraded `@newrelic/test-utilities` to ^6.3.0.
|
|
6
|
+
|
|
7
|
+
Includes `helpers.getShim` so sub packages properly execute.
|
|
8
|
+
|
|
9
|
+
* Resolved dependabot and certain npm audit warnings.
|
|
10
|
+
|
|
11
|
+
* Automation and CI improvements:
|
|
12
|
+
* Added a script to be used by agent developers to add a PR to `docs-website` after the release of agent.
|
|
13
|
+
* Changed the trigger for post release jobs.
|
|
14
|
+
* Updated the `create-release-tag` script to pass in workflows to check before creating tag.
|
|
15
|
+
* Fixed `create-release-tag` to properly filter out all async workflow run checks
|
|
16
|
+
* Updated agent release to pass in a different list of workflows vs the default
|
|
17
|
+
* Fixed release creation reusable workflow by passing in repo to `bin/create-release-tag.js` and `bin/create-github-release.js`.
|
|
18
|
+
* Added `workflow_dispatch` to Agent Post Release workflow for manual testing.
|
|
19
|
+
* Added a reusable workflow to create a release tag, publish to NPM and publish a GitHub release.
|
|
20
|
+
* Updated agent release workflow to reference reusable workflow.
|
|
21
|
+
* Added a new workflow to update RPM and publish API docs on a published release event type.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### v8.7.0 (2022-01-04)
|
|
25
|
+
|
|
26
|
+
* Updated `onResolved` instrumentation hook to only be called the first time we see a specific module filepath resolved.
|
|
27
|
+
|
|
28
|
+
* Removed `tracer.segment` in place of direct usage of context manager.
|
|
29
|
+
|
|
30
|
+
* Fixed an issue where multiple calls to `instrumentLoadedModule` resulted in re-instrumenting the same module.
|
|
31
|
+
|
|
32
|
+
* Fixed issue where `instrumentLoadedModule` would return `true` even if the instrumentation handler indicated it did not apply instrumentation.
|
|
33
|
+
|
|
34
|
+
* Added support metrics for tracking when instrumentation was applied per module.
|
|
35
|
+
|
|
36
|
+
* `Supportability/Features/Instrumentation/OnResolved/<module-name>`
|
|
37
|
+
* `Supportability/Features/Instrumentation/OnResolved/<module-name>/Version/<major version>`
|
|
38
|
+
* `Supportability/Features/Instrumentation/OnRequire/<module-name>`
|
|
39
|
+
* `Supportability/Features/Instrumentation/OnRequire/<module-name>/Version/<major version>`
|
|
40
|
+
|
|
41
|
+
* Fixed issue where expected status code ranges would not be parsed until ignored status codes were also defined.
|
|
42
|
+
|
|
43
|
+
* Added an input `changelog_file` to pass in name of changelog. This defaults to `NEWS.md` but some repos use `CHANGELOG.md`
|
|
44
|
+
|
|
45
|
+
* Abstracted `bin/prepare-release.js` to work against other repositories.
|
|
46
|
+
|
|
47
|
+
* Added reusable prepare-release workflow that can be referenced in all other newrelic Node.js repositories.
|
|
48
|
+
|
|
49
|
+
* Updated pending PRs workflow to check all repos the team owns.
|
|
50
|
+
|
|
51
|
+
* Changed the event type from `pull_request` to `pull_request_target` to allow for auto assign of PRs to the Node.js Engineering Board
|
|
52
|
+
|
|
53
|
+
* Fixed add to board workflow to properly pass repository secrets into reusable board workflow.
|
|
54
|
+
|
|
55
|
+
* Changes token used to post issues to org level project board
|
|
56
|
+
|
|
57
|
+
* Runs versioned tests for external modules against tests defined in the external repository instead of tests published in npm modules.
|
|
58
|
+
|
|
59
|
+
* Added a reusable workflow to automatically add issues to the Node.js Engineering Board when created.
|
|
60
|
+
|
|
61
|
+
* Added CI job to update system configurations with new agent version on release.
|
|
62
|
+
|
|
63
|
+
* Moved `methods.js` under bluebird versioned test folder.
|
|
64
|
+
|
|
65
|
+
### v8.6.0 (2021-11-17)
|
|
66
|
+
|
|
67
|
+
* Added `onResolved` instrumentation hook to apply instrumentation prior to module load.
|
|
68
|
+
|
|
69
|
+
This hook fires after the module filepath has been resolved just prior to the module being loaded by the CommonJS module loader.
|
|
70
|
+
|
|
71
|
+
* Fixed issue where `recordConsume` was not binding consumer if it was a promise
|
|
72
|
+
|
|
73
|
+
* Pinned mongo versioned tests to `<4.2.0` until we can address https://github.com/newrelic/node-newrelic/issues/982
|
|
74
|
+
|
|
75
|
+
* Introduced a context management API to be used in place of manually calling tracer.segment get/set.
|
|
76
|
+
|
|
77
|
+
### v8.5.2 (2021-11-09)
|
|
78
|
+
|
|
79
|
+
* Fixed issue where unhandled promise rejections were not getting logged as errors in a lambda execution
|
|
80
|
+
|
|
1
81
|
### v8.5.1 (2021-11-03)
|
|
2
82
|
|
|
3
83
|
* Fixed bug where failure to retrieve CPU/Memory details for certain Linux distros could result in a crash.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -504,7 +504,7 @@ This product includes source derived from [@grpc/proto-loader](https://github.co
|
|
|
504
504
|
|
|
505
505
|
### @newrelic/aws-sdk
|
|
506
506
|
|
|
507
|
-
This product includes source derived from [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk) ([v4.
|
|
507
|
+
This product includes source derived from [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk) ([v4.1.1](https://github.com/newrelic/node-newrelic-aws-sdk/tree/v4.1.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-aws-sdk/blob/v4.1.1/LICENSE):
|
|
508
508
|
|
|
509
509
|
```
|
|
510
510
|
Apache License
|
|
@@ -1770,7 +1770,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
1770
1770
|
|
|
1771
1771
|
### @newrelic/test-utilities
|
|
1772
1772
|
|
|
1773
|
-
This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.
|
|
1773
|
+
This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.3.0](https://github.com/newrelic/node-test-utilities/tree/v6.3.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-test-utilities/blob/v6.3.0/LICENSE):
|
|
1774
1774
|
|
|
1775
1775
|
```
|
|
1776
1776
|
Apache License
|
|
@@ -3292,7 +3292,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
3292
3292
|
|
|
3293
3293
|
### tap
|
|
3294
3294
|
|
|
3295
|
-
This product includes source derived from [tap](https://github.com/tapjs/node-tap) ([v15.
|
|
3295
|
+
This product includes source derived from [tap](https://github.com/tapjs/node-tap) ([v15.1.6](https://github.com/tapjs/node-tap/tree/v15.1.6)), distributed under the [ISC License](https://github.com/tapjs/node-tap/blob/v15.1.6/LICENSE):
|
|
3296
3296
|
|
|
3297
3297
|
```
|
|
3298
3298
|
The ISC License
|
package/api.js
CHANGED
|
@@ -14,7 +14,6 @@ const hashes = require('./lib/util/hashes')
|
|
|
14
14
|
const properties = require('./lib/util/properties')
|
|
15
15
|
const stringify = require('json-stringify-safe')
|
|
16
16
|
const shimmer = require('./lib/shimmer')
|
|
17
|
-
const shims = require('./lib/shim')
|
|
18
17
|
const isValidType = require('./lib/util/attribute-types')
|
|
19
18
|
const TransactionShim = require('./lib/shim/transaction-shim')
|
|
20
19
|
const TransactionHandle = require('./lib/transaction/handle')
|
|
@@ -55,7 +54,8 @@ const CUSTOM_EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/
|
|
|
55
54
|
* You do not need to directly instantiate this class, as an instance of this is
|
|
56
55
|
* the return from `require('newrelic')`.
|
|
57
56
|
*
|
|
58
|
-
* @
|
|
57
|
+
* @param agent
|
|
58
|
+
* @class
|
|
59
59
|
*/
|
|
60
60
|
function API(agent) {
|
|
61
61
|
this.agent = agent
|
|
@@ -139,6 +139,7 @@ API.prototype.getTransaction = function getTransaction() {
|
|
|
139
139
|
* utilization.full_hostname. If utilization.full_hostname is null or empty,
|
|
140
140
|
* this will be the hostname specified in the connect request as host.
|
|
141
141
|
*
|
|
142
|
+
* @param omitSupportability
|
|
142
143
|
* @returns {LinkingMetadata} The linking object with the data above
|
|
143
144
|
*/
|
|
144
145
|
API.prototype.getLinkingMetadata = function getLinkingMetadata(omitSupportability) {
|
|
@@ -186,7 +187,6 @@ API.prototype.getLinkingMetadata = function getLinkingMetadata(omitSupportabilit
|
|
|
186
187
|
*
|
|
187
188
|
* @param {string} name The string you would like to report to New Relic
|
|
188
189
|
* as the dispatcher.
|
|
189
|
-
*
|
|
190
190
|
* @param {string} [version] The dispatcher version you would like to
|
|
191
191
|
* report to New Relic
|
|
192
192
|
*/
|
|
@@ -414,7 +414,6 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
414
414
|
*
|
|
415
415
|
* @param {Error} error
|
|
416
416
|
* The error to be traced.
|
|
417
|
-
*
|
|
418
417
|
* @param {object} [customAttributes]
|
|
419
418
|
* Optional. Any custom attributes to be displayed in the New Relic UI.
|
|
420
419
|
*/
|
|
@@ -526,7 +525,7 @@ API.prototype.addIgnoringRule = function addIgnoringRule(pattern) {
|
|
|
526
525
|
* Do *not* reuse the headers between users, or even between requests.
|
|
527
526
|
*
|
|
528
527
|
* @param {string} [options.nonce] - Nonce to inject into `<script>` header.
|
|
529
|
-
*
|
|
528
|
+
* @param options
|
|
530
529
|
* @returns {string} The `<script>` header to be injected.
|
|
531
530
|
*/
|
|
532
531
|
API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options) {
|
|
@@ -545,7 +544,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
545
544
|
*
|
|
546
545
|
* @param {number} num - Error code from `RUM_ISSUES`.
|
|
547
546
|
* @param {bool} [quite=false] - Be quiet about this failure.
|
|
548
|
-
*
|
|
547
|
+
* @param quiet
|
|
549
548
|
* @see RUM_ISSUES
|
|
550
549
|
*/
|
|
551
550
|
function _gracefail(num, quiet) {
|
|
@@ -687,9 +686,9 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
687
686
|
|
|
688
687
|
/**
|
|
689
688
|
* @callback startSegmentCallback
|
|
690
|
-
* @param {
|
|
689
|
+
* @param {Function} cb
|
|
691
690
|
* The function to time with the created segment.
|
|
692
|
-
* @
|
|
691
|
+
* @returns {Promise=} Returns a promise if cb returns a promise.
|
|
693
692
|
*/
|
|
694
693
|
|
|
695
694
|
/**
|
|
@@ -701,23 +700,18 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
701
700
|
* // The returned promise here will signify the end of the segment.
|
|
702
701
|
* return myAsyncTask().then(myNextTask)
|
|
703
702
|
* })
|
|
704
|
-
*
|
|
705
703
|
* @param {string} name
|
|
706
704
|
* The name to give the new segment. This will also be the name of the metric.
|
|
707
|
-
*
|
|
708
705
|
* @param {bool} record
|
|
709
706
|
* Indicates if the segment should be recorded as a metric. Metrics will show
|
|
710
707
|
* up on the transaction breakdown table and server breakdown graph. Segments
|
|
711
708
|
* just show up in transaction traces.
|
|
712
|
-
*
|
|
713
709
|
* @param {startSegmentCallback} handler
|
|
714
710
|
* The function to track as a segment.
|
|
715
|
-
*
|
|
716
|
-
* @param {function} [callback]
|
|
711
|
+
* @param {Function} [callback]
|
|
717
712
|
* An optional callback for the handler. This will indicate the end of the
|
|
718
713
|
* timing if provided.
|
|
719
|
-
*
|
|
720
|
-
* @return {*} Returns the result of calling `handler`.
|
|
714
|
+
* @returns {*} Returns the result of calling `handler`.
|
|
721
715
|
*/
|
|
722
716
|
API.prototype.startSegment = function startSegment(name, record, handler, callback) {
|
|
723
717
|
this.agent.metrics
|
|
@@ -775,11 +769,9 @@ API.prototype.startSegment = function startSegment(name, record, handler, callba
|
|
|
775
769
|
* transaction.end()
|
|
776
770
|
* }, 100)
|
|
777
771
|
* })
|
|
778
|
-
*
|
|
779
772
|
* @param {string} url
|
|
780
773
|
* The URL of the transaction. It is used to name and group related transactions in APM,
|
|
781
774
|
* so it should be a generic name and not iclude any variable parameters.
|
|
782
|
-
*
|
|
783
775
|
* @param {Function} handle
|
|
784
776
|
* Function that represents the transaction work.
|
|
785
777
|
*/
|
|
@@ -862,20 +854,16 @@ API.prototype.startBackgroundTransaction = startBackgroundTransaction
|
|
|
862
854
|
* transaction.end()
|
|
863
855
|
* }, 100)
|
|
864
856
|
* })
|
|
865
|
-
*
|
|
866
857
|
* @param {string} name
|
|
867
858
|
* The name of the transaction. It is used to name and group related
|
|
868
859
|
* transactions in APM, so it should be a generic name and not iclude any
|
|
869
860
|
* variable parameters.
|
|
870
|
-
*
|
|
871
861
|
* @param {string} [group]
|
|
872
862
|
* Optional, used for grouping background transactions in APM. For more
|
|
873
863
|
* information see:
|
|
874
864
|
* https://docs.newrelic.com/docs/apm/applications-menu/monitoring/transactions-page#txn-type-dropdown
|
|
875
|
-
*
|
|
876
865
|
* @param {Function} handle
|
|
877
866
|
* Function that represents the background work.
|
|
878
|
-
*
|
|
879
867
|
* @memberOf API#
|
|
880
868
|
*/
|
|
881
869
|
function startBackgroundTransaction(name, group, handle) {
|
|
@@ -972,9 +960,9 @@ API.prototype.endTransaction = function endTransaction() {
|
|
|
972
960
|
* Record a custom metric, usually associated with a particular duration.
|
|
973
961
|
* The `name` must be a string following standard metric naming rules. The `value` will
|
|
974
962
|
* usually be a number, but it can also be an object.
|
|
975
|
-
*
|
|
963
|
+
* When `value` is a numeric value, it should represent the magnitude of a measurement
|
|
976
964
|
* associated with an event; for example, the duration for a particular method call.
|
|
977
|
-
*
|
|
965
|
+
* When `value` is an object, it must contain count, total, min, max, and sumOfSquares
|
|
978
966
|
* keys, all with number values. This form is useful to aggregate metrics on your own
|
|
979
967
|
* and report them periodically; for example, from a setInterval. These values will
|
|
980
968
|
* be aggregated with any previously collected values for the same metric. The names
|
|
@@ -1151,18 +1139,15 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
|
|
|
1151
1139
|
* - `newrelic.instrument(moduleName, onRequire [,onError])`
|
|
1152
1140
|
* - `newrelic.instrument(options)`
|
|
1153
1141
|
*
|
|
1154
|
-
* @param {object} options
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
* @param {
|
|
1158
|
-
*
|
|
1159
|
-
*
|
|
1160
|
-
* @param {function} options.onRequire
|
|
1161
|
-
* The function to call when the module is required
|
|
1162
|
-
*
|
|
1163
|
-
* @param {function} [options.onError]
|
|
1164
|
-
* If provided, should `onRequire` throw an error, the error will be passed to
|
|
1142
|
+
* @param {object} options The options for this custom instrumentation.
|
|
1143
|
+
* @param {string} options.moduleName The module name given to require to load the module
|
|
1144
|
+
* @param {Function} options.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1145
|
+
* @param {Function} options.onRequire The function to call when the module has been loaded
|
|
1146
|
+
* @param {Function} [options.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1165
1147
|
* this function.
|
|
1148
|
+
* @param moduleName
|
|
1149
|
+
* @param onRequire
|
|
1150
|
+
* @param onError
|
|
1166
1151
|
*/
|
|
1167
1152
|
API.prototype.instrument = function instrument(moduleName, onRequire, onError) {
|
|
1168
1153
|
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/instrument')
|
|
@@ -1187,18 +1172,15 @@ API.prototype.instrument = function instrument(moduleName, onRequire, onError) {
|
|
|
1187
1172
|
* - `newrelic.instrumentConglomerate(moduleName, onRequire [, onError])`
|
|
1188
1173
|
* - `newrelic.isntrumentConglomerate(options)`
|
|
1189
1174
|
*
|
|
1190
|
-
* @param {object} options
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
* @param {
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1196
|
-
* @param {function} options.onRequire
|
|
1197
|
-
* The function to call when the module is required
|
|
1198
|
-
*
|
|
1199
|
-
* @param {function} [options.onError]
|
|
1200
|
-
* If provided, should `onRequire` throw an error, the error will be passed to
|
|
1175
|
+
* @param {object} options The options for this custom instrumentation.
|
|
1176
|
+
* @param {string} options.moduleName The module name given to require to load the module
|
|
1177
|
+
* @param {Function} options.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1178
|
+
* @param {Function} options.onRequire The function to call when the module has been loaded
|
|
1179
|
+
* @param {Function} [options.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1201
1180
|
* this function.
|
|
1181
|
+
* @param moduleName
|
|
1182
|
+
* @param onRequire
|
|
1183
|
+
* @param onError
|
|
1202
1184
|
*/
|
|
1203
1185
|
API.prototype.instrumentConglomerate = function instrumentConglomerate(
|
|
1204
1186
|
moduleName,
|
|
@@ -1224,18 +1206,15 @@ API.prototype.instrumentConglomerate = function instrumentConglomerate(
|
|
|
1224
1206
|
* - `newrelic.instrumentDatastore(moduleName, onRequire [,onError])`
|
|
1225
1207
|
* - `newrelic.instrumentDatastore(options)`
|
|
1226
1208
|
*
|
|
1227
|
-
* @param {object} options
|
|
1228
|
-
*
|
|
1229
|
-
*
|
|
1230
|
-
* @param {
|
|
1231
|
-
*
|
|
1232
|
-
*
|
|
1233
|
-
* @param {function} options.onRequire
|
|
1234
|
-
* The function to call when the module is required
|
|
1235
|
-
*
|
|
1236
|
-
* @param {function} [options.onError]
|
|
1237
|
-
* If provided, should `onRequire` throw an error, the error will be passed to
|
|
1209
|
+
* @param {object} options The options for this custom instrumentation.
|
|
1210
|
+
* @param {string} options.moduleName The module name given to require to load the module
|
|
1211
|
+
* @param {Function} options.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1212
|
+
* @param {Function} options.onRequire The function to call when the module has been loaded
|
|
1213
|
+
* @param {Function} [options.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1238
1214
|
* this function.
|
|
1215
|
+
* @param moduleName
|
|
1216
|
+
* @param onRequire
|
|
1217
|
+
* @param onError
|
|
1239
1218
|
*/
|
|
1240
1219
|
API.prototype.instrumentDatastore = function instrumentDatastore(moduleName, onRequire, onError) {
|
|
1241
1220
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1256,77 +1235,21 @@ API.prototype.instrumentDatastore = function instrumentDatastore(moduleName, onR
|
|
|
1256
1235
|
shimmer.registerInstrumentation(opts)
|
|
1257
1236
|
}
|
|
1258
1237
|
|
|
1259
|
-
/**
|
|
1260
|
-
* Applies an instrumentation to an already loaded module.
|
|
1261
|
-
*
|
|
1262
|
-
* // oh no, express was loaded before newrelic
|
|
1263
|
-
* const express = require('express')
|
|
1264
|
-
* const newrelic = require('newrelic')
|
|
1265
|
-
*
|
|
1266
|
-
* // phew, we can use instrumentLoadedModule to make
|
|
1267
|
-
* // sure express is still instrumented
|
|
1268
|
-
* newrelic.instrumentLoadedModule('express', express)
|
|
1269
|
-
*
|
|
1270
|
-
* @param {string} moduleName
|
|
1271
|
-
* The module's name/identifier. Will be normalized
|
|
1272
|
-
* into an instrumentation key.
|
|
1273
|
-
*
|
|
1274
|
-
* @param {object} module
|
|
1275
|
-
* The actual module object or function we're instrumenting
|
|
1276
|
-
*/
|
|
1277
|
-
API.prototype.instrumentLoadedModule = function instrumentLoadedModule(moduleName, module) {
|
|
1278
|
-
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1279
|
-
NAMES.SUPPORTABILITY.API + '/instrumentLoadedModule'
|
|
1280
|
-
)
|
|
1281
|
-
metric.incrementCallCount()
|
|
1282
|
-
try {
|
|
1283
|
-
const instrumentationName = shimmer.getInstrumentationNameFromModuleName(moduleName)
|
|
1284
|
-
if (!shimmer.registeredInstrumentations[instrumentationName]) {
|
|
1285
|
-
logger.warn("No instrumentation registered for '%s'.", instrumentationName)
|
|
1286
|
-
return false
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
const instrumentation = shimmer.registeredInstrumentations[instrumentationName]
|
|
1290
|
-
if (!instrumentation.onRequire) {
|
|
1291
|
-
logger.warn("No onRequire function registered for '%s'.", instrumentationName)
|
|
1292
|
-
return false
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
const resolvedName = require.resolve(moduleName)
|
|
1296
|
-
|
|
1297
|
-
const shim = shims.createShimFromType(
|
|
1298
|
-
instrumentation.type,
|
|
1299
|
-
this.agent,
|
|
1300
|
-
moduleName,
|
|
1301
|
-
resolvedName
|
|
1302
|
-
)
|
|
1303
|
-
|
|
1304
|
-
instrumentation.onRequire(shim, module, moduleName)
|
|
1305
|
-
|
|
1306
|
-
return true
|
|
1307
|
-
} catch (error) {
|
|
1308
|
-
logger.error('instrumentLoadedModule encountered an error, module not instrumentend: %s', error)
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
1238
|
/**
|
|
1313
1239
|
* Registers an instrumentation function.
|
|
1314
1240
|
*
|
|
1315
1241
|
* - `newrelic.instrumentWebframework(moduleName, onRequire [,onError])`
|
|
1316
1242
|
* - `newrelic.instrumentWebframework(options)`
|
|
1317
1243
|
*
|
|
1318
|
-
* @param {object} options
|
|
1319
|
-
*
|
|
1320
|
-
*
|
|
1321
|
-
* @param {
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
* @param {function} options.onRequire
|
|
1325
|
-
* The function to call when the module is required
|
|
1326
|
-
*
|
|
1327
|
-
* @param {function} [options.onError]
|
|
1328
|
-
* If provided, should `onRequire` throw an error, the error will be passed to
|
|
1244
|
+
* @param {object} options The options for this custom instrumentation.
|
|
1245
|
+
* @param {string} options.moduleName The module name given to require to load the module
|
|
1246
|
+
* @param {Function} options.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1247
|
+
* @param {Function} options.onRequire The function to call when the module has been loaded
|
|
1248
|
+
* @param {Function} [options.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1329
1249
|
* this function.
|
|
1250
|
+
* @param moduleName
|
|
1251
|
+
* @param onRequire
|
|
1252
|
+
* @param onError
|
|
1330
1253
|
*/
|
|
1331
1254
|
API.prototype.instrumentWebframework = function instrumentWebframework(
|
|
1332
1255
|
moduleName,
|
|
@@ -1357,18 +1280,15 @@ API.prototype.instrumentWebframework = function instrumentWebframework(
|
|
|
1357
1280
|
* - `newrelic.instrumentMessages(moduleName, onRequire [,onError])`
|
|
1358
1281
|
* - `newrelic.instrumentMessages(options)`
|
|
1359
1282
|
*
|
|
1360
|
-
* @param {object} options
|
|
1361
|
-
*
|
|
1362
|
-
*
|
|
1363
|
-
* @param {
|
|
1364
|
-
*
|
|
1365
|
-
*
|
|
1366
|
-
* @param {function} options.onRequire
|
|
1367
|
-
* The function to call when the module is required
|
|
1368
|
-
*
|
|
1369
|
-
* @param {function} [options.onError]
|
|
1370
|
-
* If provided, should `onRequire` throw an error, the error will be passed to
|
|
1283
|
+
* @param {object} options The options for this custom instrumentation.
|
|
1284
|
+
* @param {string} options.moduleName The module name given to require to load the module
|
|
1285
|
+
* @param {Function} options.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1286
|
+
* @param {Function} options.onRequire The function to call when the module has been loaded
|
|
1287
|
+
* @param {Function} [options.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1371
1288
|
* this function.
|
|
1289
|
+
* @param moduleName
|
|
1290
|
+
* @param onRequire
|
|
1291
|
+
* @param onError
|
|
1372
1292
|
*/
|
|
1373
1293
|
API.prototype.instrumentMessages = function instrumentMessages(moduleName, onRequire, onError) {
|
|
1374
1294
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1389,6 +1309,40 @@ API.prototype.instrumentMessages = function instrumentMessages(moduleName, onReq
|
|
|
1389
1309
|
shimmer.registerInstrumentation(opts)
|
|
1390
1310
|
}
|
|
1391
1311
|
|
|
1312
|
+
/**
|
|
1313
|
+
* Applies an instrumentation to an already loaded module.
|
|
1314
|
+
*
|
|
1315
|
+
* // oh no, express was loaded before newrelic
|
|
1316
|
+
* const express = require('express')
|
|
1317
|
+
* const newrelic = require('newrelic')
|
|
1318
|
+
*
|
|
1319
|
+
* // phew, we can use instrumentLoadedModule to make
|
|
1320
|
+
* // sure express is still instrumented
|
|
1321
|
+
* newrelic.instrumentLoadedModule('express', express)
|
|
1322
|
+
*
|
|
1323
|
+
* @param {string} moduleName
|
|
1324
|
+
* The module's name/identifier. Will be normalized
|
|
1325
|
+
* into an instrumentation key.
|
|
1326
|
+
* @param {object} module
|
|
1327
|
+
* The actual module object or function we're instrumenting
|
|
1328
|
+
*/
|
|
1329
|
+
API.prototype.instrumentLoadedModule = function instrumentLoadedModule(moduleName, module) {
|
|
1330
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1331
|
+
NAMES.SUPPORTABILITY.API + '/instrumentLoadedModule'
|
|
1332
|
+
)
|
|
1333
|
+
metric.incrementCallCount()
|
|
1334
|
+
|
|
1335
|
+
try {
|
|
1336
|
+
const resolvedName = require.resolve(moduleName)
|
|
1337
|
+
|
|
1338
|
+
return shimmer.instrumentPostLoad(this.agent, module, moduleName, resolvedName)
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
logger.error('instrumentLoadedModule encountered an error, module not instrumented: %s', error)
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
return false
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1392
1346
|
/**
|
|
1393
1347
|
* Returns the current trace and span id.
|
|
1394
1348
|
*
|
|
@@ -1424,19 +1378,16 @@ API.prototype.getTraceMetadata = function getTraceMetadata() {
|
|
|
1424
1378
|
*
|
|
1425
1379
|
* @param {object} [options]
|
|
1426
1380
|
* Object with shut down options.
|
|
1427
|
-
*
|
|
1428
1381
|
* @param {boolean} [options.collectPendingData=false]
|
|
1429
1382
|
* If true, the agent will send any pending data to the collector before
|
|
1430
1383
|
* shutting down.
|
|
1431
|
-
*
|
|
1432
1384
|
* @param {number} [options.timeout=0]
|
|
1433
1385
|
* Time in milliseconds to wait before shutting down.
|
|
1434
|
-
*
|
|
1435
1386
|
* @param {boolean} [options.waitForIdle=false]
|
|
1436
1387
|
* If true, the agent will not shut down until there are no active transactions.
|
|
1437
|
-
*
|
|
1438
|
-
* @param {function} [callback]
|
|
1388
|
+
* @param {Function} [callback]
|
|
1439
1389
|
* Callback function that runs when agent stops.
|
|
1390
|
+
* @param cb
|
|
1440
1391
|
*/
|
|
1441
1392
|
API.prototype.shutdown = function shutdown(options, cb) {
|
|
1442
1393
|
this.agent.metrics.getOrCreateMetric(`${NAMES.SUPPORTABILITY.API}/shutdown`).incrementCallCount()
|
|
@@ -1458,6 +1409,11 @@ API.prototype.shutdown = function shutdown(options, cb) {
|
|
|
1458
1409
|
_doShutdown(this, options, callback)
|
|
1459
1410
|
}
|
|
1460
1411
|
|
|
1412
|
+
/**
|
|
1413
|
+
* @param api
|
|
1414
|
+
* @param options
|
|
1415
|
+
* @param callback
|
|
1416
|
+
*/
|
|
1461
1417
|
function _doShutdown(api, options, callback) {
|
|
1462
1418
|
const agent = api.agent
|
|
1463
1419
|
|
|
@@ -1473,6 +1429,9 @@ function _doShutdown(api, options, callback) {
|
|
|
1473
1429
|
return
|
|
1474
1430
|
}
|
|
1475
1431
|
|
|
1432
|
+
/**
|
|
1433
|
+
* @param error
|
|
1434
|
+
*/
|
|
1476
1435
|
function afterHarvest(error) {
|
|
1477
1436
|
if (error) {
|
|
1478
1437
|
logger.error(error, 'An error occurred while running last harvest before shutdown.')
|
|
@@ -1506,6 +1465,10 @@ function _doShutdown(api, options, callback) {
|
|
|
1506
1465
|
}
|
|
1507
1466
|
}
|
|
1508
1467
|
|
|
1468
|
+
/**
|
|
1469
|
+
* @param object
|
|
1470
|
+
* @param maxLength
|
|
1471
|
+
*/
|
|
1509
1472
|
function _checkKeyLength(object, maxLength) {
|
|
1510
1473
|
const keys = Object.keys(object)
|
|
1511
1474
|
let badKey = false
|
|
@@ -1534,6 +1497,10 @@ API.prototype.setLambdaHandler = function setLambdaHandler(handler) {
|
|
|
1534
1497
|
return this.awsLambda.patchLambdaHandler(handler)
|
|
1535
1498
|
}
|
|
1536
1499
|
|
|
1500
|
+
/**
|
|
1501
|
+
* @param attributes
|
|
1502
|
+
* @param name
|
|
1503
|
+
*/
|
|
1537
1504
|
function _filterAttributes(attributes, name) {
|
|
1538
1505
|
const filteredAttributes = Object.create(null)
|
|
1539
1506
|
Object.keys(attributes).forEach((attributeKey) => {
|
package/lib/agent.js
CHANGED
|
@@ -29,6 +29,7 @@ const TxSegmentNormalizer = require('./metrics/normalizer/tx_segment')
|
|
|
29
29
|
const uninstrumented = require('./uninstrumented')
|
|
30
30
|
const util = require('util')
|
|
31
31
|
const createSpanEventAggregator = require('./spans/create-span-event-aggregator')
|
|
32
|
+
const createContextManager = require('./context-manager/create-context-manager')
|
|
32
33
|
|
|
33
34
|
// Map of valid states to whether or not data collection is valid
|
|
34
35
|
const STATES = {
|
|
@@ -53,6 +54,8 @@ const DEFAULT_HARVEST_INTERVAL_MS = 60000
|
|
|
53
54
|
* This constructor can throw if, for some reason, the configuration isn't
|
|
54
55
|
* available. Don't try to recover here, because without configuration the
|
|
55
56
|
* agent can't be brought up to a useful state.
|
|
57
|
+
*
|
|
58
|
+
* @param config
|
|
56
59
|
*/
|
|
57
60
|
function Agent(config) {
|
|
58
61
|
EventEmitter.call(this)
|
|
@@ -136,8 +139,9 @@ function Agent(config) {
|
|
|
136
139
|
|
|
137
140
|
this.errors = new ErrorCollector(config, errorTraceAggregator, errorEventAggregator, this.metrics)
|
|
138
141
|
|
|
142
|
+
this._contextManager = createContextManager(this.config)
|
|
139
143
|
// Transaction tracing.
|
|
140
|
-
this.tracer = new Tracer(this)
|
|
144
|
+
this.tracer = new Tracer(this, this._contextManager)
|
|
141
145
|
this.traces = new TransactionTraceAggregator(
|
|
142
146
|
{
|
|
143
147
|
periodMs: DEFAULT_HARVEST_INTERVAL_MS,
|
|
@@ -185,7 +189,6 @@ util.inherits(Agent, EventEmitter)
|
|
|
185
189
|
* the configuration.
|
|
186
190
|
*
|
|
187
191
|
* @config {boolean} agent_enabled Whether to start up the agent.
|
|
188
|
-
*
|
|
189
192
|
* @param {Function} callback Continuation and error handler.
|
|
190
193
|
*/
|
|
191
194
|
Agent.prototype.start = function start(callback) {
|
|
@@ -248,6 +251,7 @@ Agent.prototype.start = function start(callback) {
|
|
|
248
251
|
|
|
249
252
|
/**
|
|
250
253
|
* Forces all aggregators to send the data collected.
|
|
254
|
+
*
|
|
251
255
|
* @param {Function} callback The callback to invoke when all data types have been sent.
|
|
252
256
|
*/
|
|
253
257
|
Agent.prototype.forceHarvestAll = function forceHarvestAll(callback) {
|
|
@@ -416,6 +420,9 @@ Agent.prototype.startAggregators = function startAggregators() {
|
|
|
416
420
|
/**
|
|
417
421
|
* Completes any final setup upon full connection to New Relic
|
|
418
422
|
* servers and sets the agent state to 'started'.
|
|
423
|
+
*
|
|
424
|
+
* @param shouldImmediatelyHarvest
|
|
425
|
+
* @param callback
|
|
419
426
|
*/
|
|
420
427
|
Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callback) {
|
|
421
428
|
this._reconfigureAggregators(this.config)
|
|
@@ -485,6 +492,8 @@ Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
|
|
|
485
492
|
* FIXME: make it possible to dispose of the agent, as well as do a
|
|
486
493
|
* "hard" restart. This requires working with shimmer to strip the
|
|
487
494
|
* current instrumentation and patch to the module loader.
|
|
495
|
+
*
|
|
496
|
+
* @param callback
|
|
488
497
|
*/
|
|
489
498
|
Agent.prototype.stop = function stop(callback) {
|
|
490
499
|
if (!callback) {
|