newrelic 8.7.1 → 8.9.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 +94 -0
- package/README.md +6 -2
- package/THIRD_PARTY_NOTICES.md +7 -7
- package/index.js +2 -3
- package/lib/config/default.js +2 -0
- package/lib/config/env.js +2 -0
- package/lib/config/index.js +10 -2
- package/lib/instrumentation/mongodb/common.js +39 -2
- package/lib/instrumentation/mongodb/v3-mongo.js +4 -0
- package/lib/logger.js +10 -9
- package/lib/shim/shim.js +4 -5
- package/lib/shim/webframework-shim.js +71 -128
- package/lib/util/logger.js +36 -1
- package/lib/utilization/aws-info.js +35 -16
- package/lib/utilization/common.js +7 -3
- package/package.json +8 -8
package/NEWS.md
CHANGED
|
@@ -1,3 +1,97 @@
|
|
|
1
|
+
### v8.9.1 (2022-03-22)
|
|
2
|
+
|
|
3
|
+
* Fixed `shim.wrapReturn` to call `Reflect.construct` in construct Proxy trap. Also including `newTarget` to work with inherited classes.
|
|
4
|
+
|
|
5
|
+
* Added link to New Relic Node.js Examples repository.
|
|
6
|
+
|
|
7
|
+
* Excluded installing dependencies in `versioned-external` folders when running integration tests.
|
|
8
|
+
|
|
9
|
+
### v8.9.0 (2022-03-15)
|
|
10
|
+
|
|
11
|
+
* Added support for `initializeUnorderedBulkOp`, and `initializeOrderedBulkOp` in mongodb v3 instrumentation.
|
|
12
|
+
|
|
13
|
+
Thanks to Denis Lantsman (@dlants) for the contribution.
|
|
14
|
+
|
|
15
|
+
* Updated logger to delay logging until configuration is parsed. The logger will now queue all log entries that occur before the agent can parse the configuration.
|
|
16
|
+
|
|
17
|
+
Thanks to Cody Landry (@codylandry) for the contribution.
|
|
18
|
+
|
|
19
|
+
* Added `NEW_RELIC_ALLOW_ALL_HEADERS` as a boolean environment variable, same behavior as existing `allow_all_headers`.
|
|
20
|
+
|
|
21
|
+
* Updated the AWS IMDBS v2 endpoint to use `latest` to align with the internal agent specification.
|
|
22
|
+
|
|
23
|
+
* Bumped `@newrelic/koa` to ^6.1.1.
|
|
24
|
+
|
|
25
|
+
* Added Next.js to External Modules list in README.
|
|
26
|
+
|
|
27
|
+
* Updated mysql and mysql2 versioned tests to run against their own databases on the MySQL instance.
|
|
28
|
+
|
|
29
|
+
* Removed upper-bound testing from restify versioned tests so future major versions will be covered.
|
|
30
|
+
|
|
31
|
+
* Removed upper-bound testing from mysql2 versioned tests to cover existing and future major versions.
|
|
32
|
+
|
|
33
|
+
Continues to skip version 1.6.2 which had a bug that broke tests which was resolved in 1.6.3.
|
|
34
|
+
|
|
35
|
+
* Updated @hapi/hapi Node 16 versioned test runs to run against @hapi/hapi >=20.1.2 so future major releases will be ran.
|
|
36
|
+
|
|
37
|
+
* Fixed sparse checkout of non-default branch for external versioned tests.
|
|
38
|
+
|
|
39
|
+
* Added external versioned tests for the Apollo Server plugin instrumentation.
|
|
40
|
+
|
|
41
|
+
* Added nock delay to test timeouts in utilization integration tests.
|
|
42
|
+
|
|
43
|
+
* Added newrelic-node-nextjs to external versioned tests to be run on every PR.
|
|
44
|
+
|
|
45
|
+
* Updated external version test running to support more test scenarios.
|
|
46
|
+
* Adds `test/versioned-external` to lint ignore to avoid issues for scripts in tests that auto run linting tools (next/react).
|
|
47
|
+
* Adds `index.js` and `nr-hooks.js` to files automatically checked-out for test runs.
|
|
48
|
+
|
|
49
|
+
### v8.8.0 (2022-02-23)
|
|
50
|
+
|
|
51
|
+
* Updated AWS metadata capture to utilize IMDSv2.
|
|
52
|
+
|
|
53
|
+
* Fixed link to discuss.newrelic.com in README
|
|
54
|
+
|
|
55
|
+
* Updated minimum Node version warning to output current Node version from process.
|
|
56
|
+
|
|
57
|
+
* Bumped `@newrelic/native-metrics` to ^7.1.1.
|
|
58
|
+
|
|
59
|
+
* Added `Nextjs` to a framework constant within the webframework-shim.
|
|
60
|
+
|
|
61
|
+
* Updated shim to pass active segment to inContext callback.
|
|
62
|
+
|
|
63
|
+
* Bumped `@grpc/grpc-js` to ^1.5.5.
|
|
64
|
+
|
|
65
|
+
* Bumped `@grpc/proto-loader` to ^0.6.9.
|
|
66
|
+
|
|
67
|
+
* Bumped `@newrelic/superagent` to ^5.1.0.
|
|
68
|
+
|
|
69
|
+
* Bumped `@newrelic/koa` to ^6.1.0.
|
|
70
|
+
|
|
71
|
+
* Bumped `async` to ^3.2.3.
|
|
72
|
+
|
|
73
|
+
* Resolved several npm audit warnings for dev deps.
|
|
74
|
+
|
|
75
|
+
* Fixed Post Release workflow by properly configuring git credentials so it can push API docs to branch
|
|
76
|
+
* Added `set -e` in publish docs script to exit on possible failures
|
|
77
|
+
* Removed redundant `npm ci` in publish API docs script
|
|
78
|
+
|
|
79
|
+
* Added ability to ignore certain PRs in `bin/pending-prs.js` report to slack
|
|
80
|
+
|
|
81
|
+
* Updated README to include `@newrelic/pino-enricher` as an external module.
|
|
82
|
+
|
|
83
|
+
* Fixed documentation in a sample of the Datastore Instrumentation for Node.js.
|
|
84
|
+
|
|
85
|
+
* Added a new `mongo:5` container to `npm run sevices` to test mongodb driver >=4.2.0.
|
|
86
|
+
|
|
87
|
+
* Fixed conditions in post release workflow to function when triggered via successful release and manual invoked.
|
|
88
|
+
|
|
89
|
+
* Updated method for retrieving agent version from repository by using `cat package.json | jq .version`
|
|
90
|
+
|
|
91
|
+
* Fixed minor formatting and spelling issues in `create-docs-pr.js`.
|
|
92
|
+
|
|
93
|
+
* Fixed an issue with the docs PR script that assumed `\n` in the NEWS.md file when extract version and release date
|
|
94
|
+
|
|
1
95
|
### v8.7.1 (2022-01-18)
|
|
2
96
|
|
|
3
97
|
* Bumped @newrelic/aws-sdk to ^4.1.1.
|
package/README.md
CHANGED
|
@@ -67,8 +67,10 @@ For more information on getting started, [check the Node.js docs](https://docs.n
|
|
|
67
67
|
There are several modules that can be installed and configured to accompany the Node.js agent:
|
|
68
68
|
|
|
69
69
|
* [@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.
|
|
70
|
-
* [@newrelic/winston-enricher](https://github.com/newrelic/newrelic-winston-
|
|
70
|
+
* [@newrelic/winston-enricher](https://github.com/newrelic/newrelic-node-log-extensions/tree/main/packages/winston-log-enricher): Provides distributed trace and span information output as JSON-formatted log messages in Winston. This is most commonly used with the New Relic Logs product.
|
|
71
|
+
* [@newrelic/pino-enricher](https://github.com/newrelic/newrelic-node-log-extensions/tree/main/packages/pino-log-enricher): Provides distributed trace and span information output as JSON-formatted log messages in Pino. This is most commonly used with the New Relic Logs product.
|
|
71
72
|
* [@newrelic/mysql](https://github.com/newrelic/node-newrelic-mysql)(**Experimental**): Standalone instrumentation for [mysql2](https://github.com/sidorares/node-mysql2#readme) and [mysql2/promise](https://github.com/sidorares/node-mysql2/blob/master/documentation/Promise-Wrapper.md) as well as the same instrumentation for [mysql](https://github.com/mysqljs/mysql#readme) within the Node.js agent.
|
|
73
|
+
* [@newrelic/next](https://github.com/newrelic/newrelic-node-nextjs): Provides instrumentation for the [Next.js](https://github.com/vercel/next.js/) npm package.
|
|
72
74
|
|
|
73
75
|
There are several modules included within the Node.js agent to add more instrumentation for 3rd party modules:
|
|
74
76
|
|
|
@@ -143,6 +145,8 @@ Here are some resources for learning more about the agent:
|
|
|
143
145
|
|
|
144
146
|
- [The changelog](https://github.com/newrelic/node-newrelic/blob/main/NEWS.md)
|
|
145
147
|
|
|
148
|
+
- [Example applications](https://github.com/newrelic/newrelic-node-examples) - Working examples of New Relic features in Node.js.
|
|
149
|
+
|
|
146
150
|
## Support
|
|
147
151
|
|
|
148
152
|
Should you need assistance with New Relic products, you are in good hands with several support channels.
|
|
@@ -152,7 +156,7 @@ If the issue has been confirmed as a bug or is a feature request, please file a
|
|
|
152
156
|
**Support Channels**
|
|
153
157
|
|
|
154
158
|
* [New Relic Documentation](https://docs.newrelic.com/docs/agents/nodejs-agent/getting-started/introduction-new-relic-nodejs): Comprehensive guidance for using our platform
|
|
155
|
-
* [New Relic Community](https://discuss.newrelic.com/c/
|
|
159
|
+
* [New Relic Community](https://discuss.newrelic.com/tags/c/telemetry-data-platform/agents/nodeagent): The best place to engage in troubleshooting questions
|
|
156
160
|
* [New Relic Developer](https://developer.newrelic.com/): Resources for building a custom observability applications
|
|
157
161
|
* [New Relic University](https://learn.newrelic.com/): A range of online training for New Relic users of every level
|
|
158
162
|
* [New Relic Technical Support](https://support.newrelic.com/) 24/7/365 ticketed support. Read more about our [Technical Support Offerings](https://docs.newrelic.com/docs/licenses/license-information/general-usage-licenses/support-plan).
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -86,7 +86,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
86
86
|
|
|
87
87
|
### @grpc/grpc-js
|
|
88
88
|
|
|
89
|
-
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.
|
|
89
|
+
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.5.5](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.5.5)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.5.5/LICENSE):
|
|
90
90
|
|
|
91
91
|
```
|
|
92
92
|
Apache License
|
|
@@ -295,7 +295,7 @@ This product includes source derived from [@grpc/grpc-js](https://github.com/grp
|
|
|
295
295
|
|
|
296
296
|
### @grpc/proto-loader
|
|
297
297
|
|
|
298
|
-
This product includes source derived from [@grpc/proto-loader](https://github.com/grpc/grpc-node) ([v0.
|
|
298
|
+
This product includes source derived from [@grpc/proto-loader](https://github.com/grpc/grpc-node) ([v0.6.9](https://github.com/grpc/grpc-node/tree/v0.6.9)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/blob/v0.6.9/LICENSE):
|
|
299
299
|
|
|
300
300
|
```
|
|
301
301
|
Apache License
|
|
@@ -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) ([v6.0
|
|
715
|
+
This product includes source derived from [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa) ([v6.1.0](https://github.com/newrelic/node-newrelic-koa/tree/v6.1.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-koa/blob/v6.1.0/LICENSE):
|
|
716
716
|
|
|
717
717
|
```
|
|
718
718
|
Apache License
|
|
@@ -921,7 +921,7 @@ Apache License
|
|
|
921
921
|
|
|
922
922
|
### @newrelic/superagent
|
|
923
923
|
|
|
924
|
-
This product includes source derived from [@newrelic/superagent](https://github.com/newrelic/node-newrelic-superagent) ([v5.0
|
|
924
|
+
This product includes source derived from [@newrelic/superagent](https://github.com/newrelic/node-newrelic-superagent) ([v5.1.0](https://github.com/newrelic/node-newrelic-superagent/tree/v5.1.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-superagent/blob/v5.1.0/LICENSE):
|
|
925
925
|
|
|
926
926
|
```
|
|
927
927
|
Apache License
|
|
@@ -1159,7 +1159,7 @@ THE SOFTWARE.
|
|
|
1159
1159
|
|
|
1160
1160
|
### async
|
|
1161
1161
|
|
|
1162
|
-
This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.
|
|
1162
|
+
This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.3](https://github.com/caolan/async/tree/v3.2.3)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.3/LICENSE):
|
|
1163
1163
|
|
|
1164
1164
|
```
|
|
1165
1165
|
Copyright (c) 2010-2018 Caolan McMahon
|
|
@@ -2531,7 +2531,7 @@ SOFTWARE.
|
|
|
2531
2531
|
|
|
2532
2532
|
### jsdoc
|
|
2533
2533
|
|
|
2534
|
-
This product includes source derived from [jsdoc](https://github.com/jsdoc/jsdoc) ([v3.6.
|
|
2534
|
+
This product includes source derived from [jsdoc](https://github.com/jsdoc/jsdoc) ([v3.6.10](https://github.com/jsdoc/jsdoc/tree/v3.6.10)), distributed under the [Apache-2.0 License](https://github.com/jsdoc/jsdoc/blob/v3.6.10/LICENSE.md):
|
|
2535
2535
|
|
|
2536
2536
|
```
|
|
2537
2537
|
# License
|
|
@@ -3377,7 +3377,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
3377
3377
|
|
|
3378
3378
|
### @newrelic/native-metrics
|
|
3379
3379
|
|
|
3380
|
-
This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v7.
|
|
3380
|
+
This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v7.1.1](https://github.com/newrelic/node-native-metrics/tree/v7.1.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-native-metrics/blob/v7.1.1/LICENSE):
|
|
3381
3381
|
|
|
3382
3382
|
```
|
|
3383
3383
|
Apache License
|
package/index.js
CHANGED
|
@@ -45,10 +45,9 @@ function initialize() {
|
|
|
45
45
|
logger.debug('Process was running %s seconds before agent was loaded.', preAgentTime)
|
|
46
46
|
|
|
47
47
|
if (!psemver.satisfies(pkgJSON.engines.node)) {
|
|
48
|
-
// TODO: Update this message when Node v12 is deprecated.
|
|
49
48
|
message =
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
`New Relic for Node.js requires a version of Node ${pkgJSON.engines.node}. \n` +
|
|
50
|
+
`Please upgrade from your current Node version: ${process.version}. Not starting!`
|
|
52
51
|
|
|
53
52
|
logger.error(message)
|
|
54
53
|
throw new Error(message)
|
package/lib/config/default.js
CHANGED
|
@@ -134,6 +134,8 @@ exports.config = () => ({
|
|
|
134
134
|
* When true, all request headers except for those listed in attributes.exclude
|
|
135
135
|
* will be captured for all traces, unless otherwise specified in a destination's
|
|
136
136
|
* attributes include/exclude lists.
|
|
137
|
+
*
|
|
138
|
+
* @env NEW_RELIC_ALLOW_ALL_HEADERS
|
|
137
139
|
*/
|
|
138
140
|
allow_all_headers: false,
|
|
139
141
|
|
package/lib/config/env.js
CHANGED
|
@@ -21,6 +21,7 @@ const ENV_MAPPING = {
|
|
|
21
21
|
proxy_user: 'NEW_RELIC_PROXY_USER',
|
|
22
22
|
proxy_pass: 'NEW_RELIC_PROXY_PASS',
|
|
23
23
|
agent_enabled: 'NEW_RELIC_ENABLED',
|
|
24
|
+
allow_all_headers: 'NEW_RELIC_ALLOW_ALL_HEADERS',
|
|
24
25
|
attributes: {
|
|
25
26
|
enabled: 'NEW_RELIC_ATTRIBUTES_ENABLED',
|
|
26
27
|
exclude: 'NEW_RELIC_ATTRIBUTES_EXCLUDE',
|
|
@@ -206,6 +207,7 @@ const OBJECT_LIST_VARS = new Set(['NEW_RELIC_NAMING_RULES'])
|
|
|
206
207
|
// fancy--just use 'true' and 'false', everybody.
|
|
207
208
|
const BOOLEAN_VARS = new Set([
|
|
208
209
|
'NEW_RELIC_ENABLED',
|
|
210
|
+
'NEW_RELIC_ALLOW_ALL_HEADERS',
|
|
209
211
|
'NEW_RELIC_ATTRIBUTES_ENABLED',
|
|
210
212
|
'NEW_RELIC_ERROR_COLLECTOR_ENABLED',
|
|
211
213
|
'NEW_RELIC_ERROR_COLLECTOR_ATTRIBUTES_ENABLED',
|
package/lib/config/index.js
CHANGED
|
@@ -1623,7 +1623,8 @@ function initialize(config) {
|
|
|
1623
1623
|
/**
|
|
1624
1624
|
* When the logger is required here, it bootstraps itself and then
|
|
1625
1625
|
* injects itself into this module's closure via setLogger on the
|
|
1626
|
-
* instance of the logger it creates.
|
|
1626
|
+
* instance of the logger it creates. Logs are queued until config
|
|
1627
|
+
* has been loaded to apply logging settings to bootstrapping logs
|
|
1627
1628
|
*/
|
|
1628
1629
|
logger = require('../logger')
|
|
1629
1630
|
|
|
@@ -1712,7 +1713,14 @@ function getOrCreateInstance() {
|
|
|
1712
1713
|
|
|
1713
1714
|
// Config construction has potential to throw due to invalid settings.
|
|
1714
1715
|
// This allows the agent to return a stub api without crashing the process.
|
|
1715
|
-
_configInstance = Object.assign(defaultConfig(), {
|
|
1716
|
+
_configInstance = Object.assign(defaultConfig(), {
|
|
1717
|
+
agent_enabled: false,
|
|
1718
|
+
logging: {
|
|
1719
|
+
enabled: true,
|
|
1720
|
+
filepath: 'stdout'
|
|
1721
|
+
}
|
|
1722
|
+
})
|
|
1723
|
+
|
|
1716
1724
|
_configInstance.setLogger = Config.prototype.setLogger
|
|
1717
1725
|
}
|
|
1718
1726
|
}
|
|
@@ -43,6 +43,23 @@ common.instrumentCollection = function instrumentCollection(shim, Collection) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Instruments the execute method on
|
|
48
|
+
* the BulkOperationBase class
|
|
49
|
+
*
|
|
50
|
+
* @param {Shim} shim
|
|
51
|
+
* @param {BulkOperationModule} bulk operation module, typically from mongodb/lib/bulk/common
|
|
52
|
+
* @param BulkOperationModule
|
|
53
|
+
*/
|
|
54
|
+
common.instrumentBulkOperation = function instrumentBulkOperation(shim, BulkOperationModule) {
|
|
55
|
+
const BulkOperationBase = BulkOperationModule && BulkOperationModule.BulkOperationBase
|
|
56
|
+
|
|
57
|
+
if (BulkOperationBase && BulkOperationBase.prototype) {
|
|
58
|
+
const proto = BulkOperationBase.prototype
|
|
59
|
+
shim.recordBatchQuery(proto, 'execute', common.makeBulkDescFunc(shim, 'execute'))
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
46
63
|
/**
|
|
47
64
|
* Instruments all methods from constants.DB_OPS on
|
|
48
65
|
* the Db class.
|
|
@@ -84,6 +101,25 @@ common.makeQueryDescFunc = function makeQueryDescFunc(shim, methodName) {
|
|
|
84
101
|
}
|
|
85
102
|
}
|
|
86
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Sets up the desc for all instrumented bulk operations
|
|
106
|
+
*
|
|
107
|
+
* @param {Shim} shim
|
|
108
|
+
* @param {string} methodName
|
|
109
|
+
*/
|
|
110
|
+
common.makeBulkDescFunc = function makeBulkDescFunc(shim) {
|
|
111
|
+
return function bulkDescFunc() {
|
|
112
|
+
const parameters = getInstanceAttributeParameters(shim, this)
|
|
113
|
+
return {
|
|
114
|
+
query: this.isOrdered ? 'orderedBulk' : 'unorderedBulk',
|
|
115
|
+
parameters,
|
|
116
|
+
promise: true,
|
|
117
|
+
callback: shim.LAST,
|
|
118
|
+
opaque: true
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
87
123
|
/**
|
|
88
124
|
* Sets up a listener for `started` on instrumenter(mongo APM). This applies to
|
|
89
125
|
* mongo <4. The listener adds the following attributes to the active segment:
|
|
@@ -161,9 +197,10 @@ function setHostPort(shim, connStr, db, client) {
|
|
|
161
197
|
* @param obj
|
|
162
198
|
*/
|
|
163
199
|
function getInstanceAttributeParameters(shim, obj) {
|
|
164
|
-
if (obj.s && obj.s.
|
|
200
|
+
if (obj.s && obj.s.topology) {
|
|
165
201
|
shim.logger.trace('Adding datastore instance attributes from obj.s.db + obj.s.topology')
|
|
166
|
-
const databaseName =
|
|
202
|
+
const databaseName =
|
|
203
|
+
(obj.s.db && obj.s.db.databaseName) || (obj.s.namespace && obj.s.namespace.db) || null
|
|
167
204
|
const topology = obj.s.topology
|
|
168
205
|
if (topology.s && topology.s.options) {
|
|
169
206
|
return doCapture(topology.s.options, databaseName)
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const {
|
|
9
9
|
captureAttributesOnStarted,
|
|
10
|
+
instrumentBulkOperation,
|
|
10
11
|
instrumentCollection,
|
|
11
12
|
instrumentCursor,
|
|
12
13
|
instrumentDb,
|
|
@@ -27,6 +28,8 @@ function queryParser(operation) {
|
|
|
27
28
|
collection = this.operation.target
|
|
28
29
|
} else if (this.ns) {
|
|
29
30
|
collection = this.ns.split(/\./)[1] || collection
|
|
31
|
+
} else if (this.s && this.s.collection && this.s.collection.collectionName) {
|
|
32
|
+
collection = this.s.collection.collectionName
|
|
30
33
|
}
|
|
31
34
|
return { operation, collection }
|
|
32
35
|
}
|
|
@@ -68,6 +71,7 @@ module.exports = function instrument(shim, mongodb) {
|
|
|
68
71
|
instrumentCursor(shim, mongodb.Cursor)
|
|
69
72
|
instrumentCursor(shim, shim.require('./lib/aggregation_cursor'))
|
|
70
73
|
instrumentCursor(shim, shim.require('./lib/command_cursor'))
|
|
74
|
+
instrumentBulkOperation(shim, shim.require('./lib/bulk/common'))
|
|
71
75
|
instrumentCollection(shim, mongodb.Collection)
|
|
72
76
|
instrumentDb(shim, mongodb.Db)
|
|
73
77
|
|
package/lib/logger.js
CHANGED
|
@@ -9,12 +9,16 @@ const Logger = require('./util/logger')
|
|
|
9
9
|
const fs = require('./util/unwrapped-core').fs
|
|
10
10
|
|
|
11
11
|
// create bootstrapping logger
|
|
12
|
-
|
|
12
|
+
const logger = new Logger({
|
|
13
13
|
name: 'newrelic_bootstrap',
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
level: 'info',
|
|
15
|
+
|
|
16
|
+
// logger is configured below. Logs are queued until configured
|
|
17
|
+
configured: false
|
|
16
18
|
})
|
|
17
19
|
|
|
20
|
+
module.exports = logger
|
|
21
|
+
|
|
18
22
|
/**
|
|
19
23
|
* Don't load config until this point, because it requires this
|
|
20
24
|
* module, and if it gets loaded too early, module.exports will have no
|
|
@@ -28,8 +32,8 @@ if (config) {
|
|
|
28
32
|
enabled: config.logging.enabled
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
//
|
|
32
|
-
|
|
35
|
+
// configure logger
|
|
36
|
+
logger.configure(options)
|
|
33
37
|
|
|
34
38
|
if (config.logging.enabled) {
|
|
35
39
|
let stream
|
|
@@ -52,9 +56,6 @@ if (config) {
|
|
|
52
56
|
/* eslint-enable no-console */
|
|
53
57
|
})
|
|
54
58
|
}
|
|
55
|
-
|
|
59
|
+
logger.pipe(stream)
|
|
56
60
|
}
|
|
57
|
-
|
|
58
|
-
// now tell the config module to switch to the real logger
|
|
59
|
-
config.setLogger(module.exports)
|
|
60
61
|
}
|
package/lib/shim/shim.js
CHANGED
|
@@ -639,10 +639,9 @@ function wrapReturn(nodule, properties, spec, args) {
|
|
|
639
639
|
}
|
|
640
640
|
return true
|
|
641
641
|
},
|
|
642
|
-
construct: function constructTrap(
|
|
643
|
-
// Call the underlying function
|
|
644
|
-
|
|
645
|
-
let ret = new Target(...proxyArgs)
|
|
642
|
+
construct: function constructTrap(target, proxyArgs, newTarget) {
|
|
643
|
+
// Call the underlying function via Reflect.
|
|
644
|
+
let ret = Reflect.construct(target, proxyArgs, newTarget)
|
|
646
645
|
|
|
647
646
|
// Assemble the arguments to hand to the spec.
|
|
648
647
|
const _args = [shim, fn, fnName, ret]
|
|
@@ -1307,7 +1306,7 @@ function applySegment(func, segment, full, context, args, inContextCB) {
|
|
|
1307
1306
|
}
|
|
1308
1307
|
|
|
1309
1308
|
if (typeof inContextCB === 'function') {
|
|
1310
|
-
inContextCB()
|
|
1309
|
+
inContextCB(segment)
|
|
1311
1310
|
}
|
|
1312
1311
|
|
|
1313
1312
|
try {
|
|
@@ -29,10 +29,11 @@ const FRAMEWORK_NAMES = {
|
|
|
29
29
|
CONNECT: 'Connect',
|
|
30
30
|
DIRECTOR: 'Director',
|
|
31
31
|
EXPRESS: 'Expressjs',
|
|
32
|
+
FASTIFY: 'Fastify',
|
|
32
33
|
HAPI: 'Hapi',
|
|
33
34
|
KOA: 'Koa',
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
NEXT: 'Nextjs',
|
|
36
|
+
RESTIFY: 'Restify'
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
const MIDDLEWARE_TYPE_DETAILS = {
|
|
@@ -64,24 +65,19 @@ const TRANSACTION_INFO_KEY = '__NR_transactionInfo'
|
|
|
64
65
|
* Constructs a shim associated with the given agent instance, specialized for
|
|
65
66
|
* instrumenting web frameworks.
|
|
66
67
|
*
|
|
67
|
-
* @
|
|
68
|
-
* @
|
|
68
|
+
* @class
|
|
69
|
+
* @augments TransactionShim
|
|
69
70
|
* @classdesc
|
|
70
71
|
* A helper class for wrapping web framework modules.
|
|
71
|
-
*
|
|
72
72
|
* @param {Agent} agent
|
|
73
73
|
* The agent this shim will use.
|
|
74
|
-
*
|
|
75
74
|
* @param {string} moduleName
|
|
76
75
|
* The name of the module being instrumented.
|
|
77
|
-
*
|
|
78
76
|
* @param {string} resolvedName
|
|
79
77
|
* The full path to the loaded module.
|
|
80
|
-
*
|
|
81
78
|
* @param {string} [frameworkId]
|
|
82
79
|
* The name of the web framework being instrumented. If available, use one of
|
|
83
80
|
* the values from {@link WebFrameworkShim.FRAMEWORK_NAMES}.
|
|
84
|
-
*
|
|
85
81
|
* @see TransactionShim
|
|
86
82
|
* @see WebFrameworkShim.FRAMEWORK_NAMES
|
|
87
83
|
*/
|
|
@@ -130,123 +126,93 @@ WebFrameworkShim.prototype.captureUrlParams = captureUrlParams
|
|
|
130
126
|
|
|
131
127
|
/**
|
|
132
128
|
* @callback RouteParserFunction
|
|
133
|
-
*
|
|
134
129
|
* @summary
|
|
135
130
|
* Called whenever new middleware are mounted using the instrumented framework,
|
|
136
131
|
* this method should pull out a representation of the mounted path.
|
|
137
|
-
*
|
|
138
132
|
* @param {WebFrameworkShim} shim
|
|
139
133
|
* The shim in use for this instrumentation.
|
|
140
|
-
*
|
|
141
|
-
* @param {function} fn
|
|
134
|
+
* @param {Function} fn
|
|
142
135
|
* The function which received this route string/RegExp.
|
|
143
|
-
*
|
|
144
136
|
* @param {string} fnName
|
|
145
137
|
* The name of the function to which this route was given.
|
|
146
|
-
*
|
|
147
138
|
* @param {string|RegExp} route
|
|
148
139
|
* The route that was given to the function.
|
|
149
|
-
*
|
|
150
|
-
* @return {string|RegExp} The mount point from the given route.
|
|
140
|
+
* @returns {string|RegExp} The mount point from the given route.
|
|
151
141
|
*/
|
|
152
142
|
|
|
153
143
|
/**
|
|
154
144
|
* @callback RouteRequestFunction
|
|
155
|
-
*
|
|
156
145
|
* @summary
|
|
157
146
|
* Extracts the request object from the arguments to the middleware function.
|
|
158
|
-
*
|
|
159
147
|
* @param {WebFrameworkShim} shim - The shim used for instrumentation.
|
|
160
|
-
* @param {
|
|
148
|
+
* @param {Function} fn - The middleware function.
|
|
161
149
|
* @param {string} fnName - The name of the middleware function.
|
|
162
150
|
* @param {Array} args - The arguments to the middleware function.
|
|
163
|
-
*
|
|
164
|
-
* @return {Object} The request object.
|
|
151
|
+
* @returns {object} The request object.
|
|
165
152
|
*/
|
|
166
153
|
|
|
167
154
|
/**
|
|
168
155
|
* @callback RouteNextFunction
|
|
169
|
-
*
|
|
170
156
|
* @summary
|
|
171
157
|
* Used to wrap functions that users can call to continue to the next middleware.
|
|
172
|
-
*
|
|
173
158
|
* @param {WebFrameworkShim} shim - The shim used for instrumentation.
|
|
174
|
-
* @param {
|
|
159
|
+
* @param {Function} fn - The middleware function.
|
|
175
160
|
* @param {string} fnName - The name of the middleware function.
|
|
176
161
|
* @param {Array} args - The arguments to the middleware function.
|
|
177
162
|
* @param {NextWrapperFunction} wrap - A function to wrap an individual next function.
|
|
178
|
-
*
|
|
179
|
-
* @return {Object} The request object.
|
|
163
|
+
* @returns {object} The request object.
|
|
180
164
|
*/
|
|
181
165
|
|
|
182
166
|
/**
|
|
183
167
|
* @callback RouteParameterFunction
|
|
184
|
-
*
|
|
185
168
|
* @summary
|
|
186
169
|
* Extracts the route parameters from the arguments to the middleware function.
|
|
187
|
-
*
|
|
188
170
|
* @param {WebFrameworkShim} shim - The shim used for instrumentation.
|
|
189
|
-
* @param {
|
|
171
|
+
* @param {Function} fn - The middleware function.
|
|
190
172
|
* @param {string} fnName - The name of the middleware function.
|
|
191
173
|
* @param {Array} args - The arguments to the middleware function.
|
|
192
|
-
*
|
|
193
|
-
* @return {Object} A map of route parameter names to values.
|
|
174
|
+
* @returns {object} A map of route parameter names to values.
|
|
194
175
|
*/
|
|
195
176
|
|
|
196
177
|
/**
|
|
197
178
|
* @callback MiddlewareWrapperFunction
|
|
198
|
-
*
|
|
199
179
|
* @summary
|
|
200
180
|
* Called for each middleware passed to a mounting method. Should perform the
|
|
201
181
|
* wrapping of the middleware.
|
|
202
|
-
*
|
|
203
182
|
* @param {WebFrameworkShim} shim
|
|
204
183
|
* The shim used for instrumentation.
|
|
205
|
-
*
|
|
206
|
-
* @param {function} middleware
|
|
184
|
+
* @param {Function} middleware
|
|
207
185
|
* The middleware function to wrap.
|
|
208
|
-
*
|
|
209
186
|
* @param {string} fnName
|
|
210
187
|
* The name of the middleware function.
|
|
211
|
-
*
|
|
212
188
|
* @param {string} [route=null]
|
|
213
189
|
* The route the middleware is mounted on if one was found.
|
|
214
|
-
*
|
|
215
190
|
* @see WebFrameworkShim#recordMiddleware
|
|
216
191
|
* @see WebFrameworkShim#recordParamware
|
|
217
192
|
*/
|
|
218
193
|
|
|
219
194
|
/**
|
|
220
195
|
* @interface MiddlewareSpec
|
|
221
|
-
*
|
|
222
196
|
* @description
|
|
223
197
|
* Describes the interface for middleware functions with this instrumentation.
|
|
224
|
-
*
|
|
225
198
|
* @property {number|RouteRequestFunction} [req=shim.FIRST]
|
|
226
199
|
* Indicates which argument to the middleware is the request object. It can also be
|
|
227
200
|
* a function to extract the request object from the middleware arguments.
|
|
228
|
-
*
|
|
229
201
|
* @property {number} [res=shim.SECOND]
|
|
230
202
|
* Indicates which argument to the middleware is the response object.
|
|
231
|
-
*
|
|
232
203
|
* @property {number|RouteNextFunction} [next=shim.THIRD]
|
|
233
204
|
* Indicates which argument to the middleware function is the callback. When it is
|
|
234
205
|
* a function, it will be called with the arguments of the middleware and a function
|
|
235
206
|
* for wrapping calls that represent continuation from the current middleware.
|
|
236
|
-
*
|
|
237
207
|
* @property {string} [name]
|
|
238
208
|
* The name to use for this middleware. Defaults to `middleware.name`.
|
|
239
|
-
*
|
|
240
209
|
* @property {RouteParameterFunction} [params]
|
|
241
210
|
* A function to extract the route parameters from the middleware arguments.
|
|
242
211
|
* Defaults to using `req.params`.
|
|
243
|
-
*
|
|
244
212
|
* @property {string} [type='MIDDLEWARE']
|
|
245
|
-
*
|
|
246
|
-
* @property {string|function} [route=null]
|
|
213
|
+
* @property {string | Function} [route=null]
|
|
247
214
|
* Route/path used for naming segments and transaction name candidates. If a function,
|
|
248
215
|
* will be invoked just before segment creation with middleware invocation.
|
|
249
|
-
*
|
|
250
216
|
* @property {boolean} [appendPath=true]
|
|
251
217
|
* Indicates that the path associated with the middleware should be appended
|
|
252
218
|
* and popped from the stack of name candidates.
|
|
@@ -254,31 +220,25 @@ WebFrameworkShim.prototype.captureUrlParams = captureUrlParams
|
|
|
254
220
|
|
|
255
221
|
/**
|
|
256
222
|
* @interface MiddlewareMounterSpec
|
|
257
|
-
*
|
|
258
223
|
* @description
|
|
259
224
|
* Describes the arguments provided to mounting methods (e.g. `app.post()`).
|
|
260
|
-
*
|
|
261
225
|
* @property {number|string} [route=null]
|
|
262
226
|
* Tells which argument may be the mounting path for the other arguments. If
|
|
263
227
|
* the indicated argument is a function it is assumed the route was not provided
|
|
264
228
|
* and the indicated argument is a middleware function. If a string is provided
|
|
265
229
|
* it will be used as the mounting path.
|
|
266
|
-
*
|
|
267
230
|
* @property {MiddlewareWrapperFunction} [wrapper]
|
|
268
231
|
* A function to call for each middleware function passed to the mounter.
|
|
269
232
|
*/
|
|
270
233
|
|
|
271
234
|
/**
|
|
272
235
|
* @interface RenderSpec
|
|
273
|
-
* @
|
|
274
|
-
*
|
|
236
|
+
* @augments RecorderSpec
|
|
275
237
|
* @description
|
|
276
238
|
* Describes the interface for render methods.
|
|
277
|
-
*
|
|
278
239
|
* @property {number} [view=shim.FIRST]
|
|
279
240
|
* Identifies which argument is the name of the view being rendered. Defaults
|
|
280
241
|
* to {@link Shim#ARG_INDEXES shim.FIRST}.
|
|
281
|
-
*
|
|
282
242
|
* @see SegmentSpec
|
|
283
243
|
* @see RecorderSpec
|
|
284
244
|
*/
|
|
@@ -292,7 +252,6 @@ WebFrameworkShim.prototype.captureUrlParams = captureUrlParams
|
|
|
292
252
|
* - `setRouteParser(parser)`
|
|
293
253
|
*
|
|
294
254
|
* @memberof WebFrameworkShim.prototype
|
|
295
|
-
*
|
|
296
255
|
* @param {RouteParserFunction} parser - The parser function to use.
|
|
297
256
|
*/
|
|
298
257
|
function setRouteParser(parser) {
|
|
@@ -310,10 +269,8 @@ function setRouteParser(parser) {
|
|
|
310
269
|
* This should be the first thing the instrumentation does.
|
|
311
270
|
*
|
|
312
271
|
* @memberof WebFrameworkShim.prototype
|
|
313
|
-
*
|
|
314
272
|
* @param {WebFrameworkShim.FRAMEWORK_NAMES|string} framework
|
|
315
273
|
* The name of the framework.
|
|
316
|
-
*
|
|
317
274
|
* @see WebFrameworkShim.FRAMEWORK_NAMES
|
|
318
275
|
*/
|
|
319
276
|
function setFramework(framework) {
|
|
@@ -332,7 +289,6 @@ function setFramework(framework) {
|
|
|
332
289
|
* Sets the URI path to be used for naming the transaction currently in scope.
|
|
333
290
|
*
|
|
334
291
|
* @memberof WebFrameworkShim.prototype
|
|
335
|
-
*
|
|
336
292
|
* @param {string} uri - The URI path to use for the transaction.
|
|
337
293
|
*/
|
|
338
294
|
function setTransactionUri(uri) {
|
|
@@ -351,18 +307,14 @@ function setTransactionUri(uri) {
|
|
|
351
307
|
* - `recordRender(func [, spec])`
|
|
352
308
|
*
|
|
353
309
|
* @memberof WebFrameworkShim.prototype
|
|
354
|
-
*
|
|
355
|
-
* @param {Object|Function} nodule
|
|
310
|
+
* @param {object | Function} nodule
|
|
356
311
|
* The source for the properties to wrap, or a single function to wrap.
|
|
357
|
-
*
|
|
358
312
|
* @param {string|Array.<string>} [properties]
|
|
359
313
|
* One or more properties to wrap. If omitted, the `nodule` parameter is
|
|
360
314
|
* assumed to be the function to wrap.
|
|
361
|
-
*
|
|
362
315
|
* @param {RenderSpec} [spec]
|
|
363
316
|
* The spec for wrapping the render method.
|
|
364
|
-
*
|
|
365
|
-
* @return {Object|Function} The first parameter to this function, after
|
|
317
|
+
* @returns {object | Function} The first parameter to this function, after
|
|
366
318
|
* wrapping it or its properties.
|
|
367
319
|
*/
|
|
368
320
|
function recordRender(nodule, properties, spec) {
|
|
@@ -407,20 +359,15 @@ function recordRender(nodule, properties, spec) {
|
|
|
407
359
|
* - `wrapMiddlewareMounter(func [, spec])`
|
|
408
360
|
*
|
|
409
361
|
* @memberof WebFrameworkShim.prototype
|
|
410
|
-
*
|
|
411
|
-
* @param {Object|Function} nodule
|
|
362
|
+
* @param {object | Function} nodule
|
|
412
363
|
* The source for the properties to wrap, or a single function to wrap.
|
|
413
|
-
*
|
|
414
364
|
* @param {string|Array.<string>} [properties]
|
|
415
365
|
* One or more properties to wrap. If omitted, the `nodule` parameter is
|
|
416
366
|
* assumed to be the function to wrap.
|
|
417
|
-
*
|
|
418
367
|
* @param {MiddlewareMounterSpec} [spec]
|
|
419
368
|
* Spec describing the parameters for this middleware mount point.
|
|
420
|
-
*
|
|
421
|
-
* @return {Object|Function} The first parameter to this function, after
|
|
369
|
+
* @returns {object | Function} The first parameter to this function, after
|
|
422
370
|
* wrapping it or its properties.
|
|
423
|
-
*
|
|
424
371
|
* @see WebFrameworkShim#recordMiddleware
|
|
425
372
|
*/
|
|
426
373
|
function wrapMiddlewareMounter(nodule, properties, spec) {
|
|
@@ -470,6 +417,10 @@ function wrapMiddlewareMounter(nodule, properties, spec) {
|
|
|
470
417
|
}
|
|
471
418
|
|
|
472
419
|
_wrapMiddlewares.call(this, routeIdx, args)
|
|
420
|
+
/**
|
|
421
|
+
* @param _routeIdx
|
|
422
|
+
* @param middlewares
|
|
423
|
+
*/
|
|
473
424
|
function _wrapMiddlewares(_routeIdx, middlewares) {
|
|
474
425
|
for (let i = 0; i < middlewares.length; ++i) {
|
|
475
426
|
// If this argument is the route argument skip it.
|
|
@@ -512,20 +463,15 @@ function wrapMiddlewareMounter(nodule, properties, spec) {
|
|
|
512
463
|
* - `recordMiddleware(func [, spec])`
|
|
513
464
|
*
|
|
514
465
|
* @memberof WebFrameworkShim.prototype
|
|
515
|
-
*
|
|
516
|
-
* @param {Object|Function} nodule
|
|
466
|
+
* @param {object | Function} nodule
|
|
517
467
|
* The source for the properties to wrap, or a single function to wrap.
|
|
518
|
-
*
|
|
519
468
|
* @param {string|Array.<string>} [properties]
|
|
520
469
|
* One or more properties to wrap. If omitted, the `nodule` parameter is
|
|
521
470
|
* assumed to be the function to wrap.
|
|
522
|
-
*
|
|
523
471
|
* @param {MiddlewareSpec} [spec]
|
|
524
472
|
* The spec for wrapping the middleware.
|
|
525
|
-
*
|
|
526
|
-
* @return {Object|Function} The first parameter to this function, after
|
|
473
|
+
* @returns {object | Function} The first parameter to this function, after
|
|
527
474
|
* wrapping it or its properties.
|
|
528
|
-
*
|
|
529
475
|
* @see WebFrameworkShim#wrapMiddlewareMounter
|
|
530
476
|
*/
|
|
531
477
|
function recordMiddleware(nodule, properties, spec) {
|
|
@@ -560,18 +506,14 @@ function recordMiddleware(nodule, properties, spec) {
|
|
|
560
506
|
* processing as possible.
|
|
561
507
|
*
|
|
562
508
|
* @memberof WebFrameworkShim.prototype
|
|
563
|
-
*
|
|
564
|
-
* @param {Object|Function} nodule
|
|
509
|
+
* @param {object | Function} nodule
|
|
565
510
|
* The source for the properties to wrap, or a single function to wrap.
|
|
566
|
-
*
|
|
567
511
|
* @param {string|Array.<string>} [properties]
|
|
568
512
|
* One or more properties to wrap. If omitted, the `nodule` parameter is
|
|
569
513
|
* assumed to be the function to wrap.
|
|
570
|
-
*
|
|
571
514
|
* @param {MiddlewareSpec} [spec]
|
|
572
515
|
* The spec for wrapping the middleware.
|
|
573
|
-
*
|
|
574
|
-
* @return {Object|Function} The first parameter to this function, after
|
|
516
|
+
* @returns {object | Function} The first parameter to this function, after
|
|
575
517
|
* wrapping it or its properties.
|
|
576
518
|
*/
|
|
577
519
|
function recordParamware(nodule, properties, spec) {
|
|
@@ -610,10 +552,8 @@ function recordParamware(nodule, properties, spec) {
|
|
|
610
552
|
* caught by the user.
|
|
611
553
|
*
|
|
612
554
|
* @memberof WebFrameworkShim.prototype
|
|
613
|
-
*
|
|
614
555
|
* @param {Request} req - The request which caused the error.
|
|
615
556
|
* @param {*?} err - The error which has occurred.
|
|
616
|
-
*
|
|
617
557
|
* @see WebFrameworkShim#errorHandled
|
|
618
558
|
* @see WebFrameworkShim#setErrorPredicate
|
|
619
559
|
*/
|
|
@@ -628,10 +568,8 @@ function noticeError(req, err) {
|
|
|
628
568
|
* Indicates that the given error has been handled for this request.
|
|
629
569
|
*
|
|
630
570
|
* @memberof WebFrameworkShim.prototype
|
|
631
|
-
*
|
|
632
571
|
* @param {Request} req - The request which caused the error.
|
|
633
572
|
* @param {*} err - The error which has been handled.
|
|
634
|
-
*
|
|
635
573
|
* @see WebFrameworkShim#noticeError
|
|
636
574
|
* @see WebFrameworkShim#setErrorPredicate
|
|
637
575
|
*/
|
|
@@ -647,11 +585,9 @@ function errorHandled(req, err) {
|
|
|
647
585
|
* an error.
|
|
648
586
|
*
|
|
649
587
|
* @memberof WebFrameworkShim.prototype
|
|
650
|
-
*
|
|
651
588
|
* @param {function(object): bool} pred
|
|
652
589
|
* Function which should return true if the object passed to it is considered
|
|
653
590
|
* an error.
|
|
654
|
-
*
|
|
655
591
|
* @see WebFrameworkShim#noticeError
|
|
656
592
|
* @see WebFrameworkShim#errorHandled
|
|
657
593
|
*/
|
|
@@ -663,7 +599,6 @@ function setErrorPredicate(pred) {
|
|
|
663
599
|
* Marks the current path as a potential responder.
|
|
664
600
|
*
|
|
665
601
|
* @memberof WebFrameworkShim.prototype
|
|
666
|
-
*
|
|
667
602
|
* @param {Request} req - The request which caused the error.
|
|
668
603
|
*/
|
|
669
604
|
function savePossibleTransactionName(req) {
|
|
@@ -678,7 +613,6 @@ function savePossibleTransactionName(req) {
|
|
|
678
613
|
* responded.
|
|
679
614
|
*
|
|
680
615
|
* @memberof WebFrameworkShim.prototype
|
|
681
|
-
*
|
|
682
616
|
* @param {function(args, object): bool} pred
|
|
683
617
|
* Function which should return true if the object passed to it is considered
|
|
684
618
|
* a response.
|
|
@@ -691,8 +625,7 @@ function setResponsePredicate(pred) {
|
|
|
691
625
|
* Capture URL parameters from a request object as attributes of the current segment.
|
|
692
626
|
*
|
|
693
627
|
* @memberof WebFrameworkShim.prototype
|
|
694
|
-
*
|
|
695
|
-
* @param {Object} params
|
|
628
|
+
* @param {object} params
|
|
696
629
|
* An object with key-value pairs.
|
|
697
630
|
*/
|
|
698
631
|
function captureUrlParams(params) {
|
|
@@ -708,19 +641,14 @@ function captureUrlParams(params) {
|
|
|
708
641
|
* Default route parser function if one is not provided.
|
|
709
642
|
*
|
|
710
643
|
* @private
|
|
711
|
-
*
|
|
712
644
|
* @param {WebFrameworkShim} shim
|
|
713
645
|
* The shim in use for this instrumentation.
|
|
714
|
-
*
|
|
715
|
-
* @param {function} fn
|
|
646
|
+
* @param {Function} fn
|
|
716
647
|
* The function which received this route string/RegExp.
|
|
717
|
-
*
|
|
718
648
|
* @param {string} fnName
|
|
719
649
|
* The name of the function to which this route was given.
|
|
720
|
-
*
|
|
721
650
|
* @param {string|RegExp} route
|
|
722
651
|
* The route that was given to the function.
|
|
723
|
-
*
|
|
724
652
|
* @see RouteParserFunction
|
|
725
653
|
*/
|
|
726
654
|
function _defaultRouteParser(shim, fn, fnName, route) {
|
|
@@ -737,8 +665,7 @@ function _defaultRouteParser(shim, fn, fnName, route) {
|
|
|
737
665
|
* Default error predicate just returns true.
|
|
738
666
|
*
|
|
739
667
|
* @private
|
|
740
|
-
*
|
|
741
|
-
* @return {bool} True. Always.
|
|
668
|
+
* @returns {bool} True. Always.
|
|
742
669
|
*/
|
|
743
670
|
function _defaultErrorPredicate() {
|
|
744
671
|
return true
|
|
@@ -748,8 +675,7 @@ function _defaultErrorPredicate() {
|
|
|
748
675
|
* Default response predicate just returns false.
|
|
749
676
|
*
|
|
750
677
|
* @private
|
|
751
|
-
*
|
|
752
|
-
* @return {bool} False. Always.
|
|
678
|
+
* @returns {bool} False. Always.
|
|
753
679
|
*/
|
|
754
680
|
function _defaultResponsePredicate() {
|
|
755
681
|
return false
|
|
@@ -759,19 +685,18 @@ function _defaultResponsePredicate() {
|
|
|
759
685
|
* Wraps the given function in a middleware recorder function.
|
|
760
686
|
*
|
|
761
687
|
* @private
|
|
762
|
-
*
|
|
763
688
|
* @param {WebFrameworkShim} shim
|
|
764
689
|
* The shim used for this instrumentation.
|
|
765
|
-
*
|
|
766
|
-
* @param {function} middleware
|
|
690
|
+
* @param {Function} middleware
|
|
767
691
|
* The middleware function to record.
|
|
768
|
-
*
|
|
769
692
|
* @param {MiddlewareSpec} spec
|
|
770
693
|
* The spec describing the middleware.
|
|
771
|
-
*
|
|
772
|
-
* @return {function} The middleware function wrapped in a recorder.
|
|
694
|
+
* @returns {Function} The middleware function wrapped in a recorder.
|
|
773
695
|
*/
|
|
774
696
|
function _recordMiddleware(shim, middleware, spec) {
|
|
697
|
+
/**
|
|
698
|
+
*
|
|
699
|
+
*/
|
|
775
700
|
function getRoute() {
|
|
776
701
|
let route = spec.route || '/'
|
|
777
702
|
|
|
@@ -797,6 +722,9 @@ function _recordMiddleware(shim, middleware, spec) {
|
|
|
797
722
|
metricName = shim._metrics.MIDDLEWARE + metricName + name
|
|
798
723
|
}
|
|
799
724
|
|
|
725
|
+
/**
|
|
726
|
+
* @param route
|
|
727
|
+
*/
|
|
800
728
|
function getSegmentName(route) {
|
|
801
729
|
let segmentName = metricName
|
|
802
730
|
if (typeDetails.path) {
|
|
@@ -817,6 +745,12 @@ function _recordMiddleware(shim, middleware, spec) {
|
|
|
817
745
|
)
|
|
818
746
|
|
|
819
747
|
// TODO: let's please break these out
|
|
748
|
+
/**
|
|
749
|
+
* @param shim
|
|
750
|
+
* @param fn
|
|
751
|
+
* @param fnName
|
|
752
|
+
* @param args
|
|
753
|
+
*/
|
|
820
754
|
function middlewareWithCallbackRecorder(shim, fn, fnName, args) {
|
|
821
755
|
const route = getRoute()
|
|
822
756
|
|
|
@@ -909,6 +843,12 @@ function _recordMiddleware(shim, middleware, spec) {
|
|
|
909
843
|
}
|
|
910
844
|
}
|
|
911
845
|
|
|
846
|
+
/**
|
|
847
|
+
* @param shim
|
|
848
|
+
* @param fn
|
|
849
|
+
* @param fnName
|
|
850
|
+
* @param args
|
|
851
|
+
*/
|
|
912
852
|
function middlewareWithPromiseRecorder(shim, fn, fnName, args) {
|
|
913
853
|
const route = getRoute()
|
|
914
854
|
|
|
@@ -1007,6 +947,10 @@ function _recordMiddleware(shim, middleware, spec) {
|
|
|
1007
947
|
}
|
|
1008
948
|
}
|
|
1009
949
|
|
|
950
|
+
/**
|
|
951
|
+
* @param shim
|
|
952
|
+
* @param req
|
|
953
|
+
*/
|
|
1010
954
|
function _makeGetReq(shim, req) {
|
|
1011
955
|
return function getReqFromArgs(shim, fn, name, args) {
|
|
1012
956
|
const reqIdx = shim.normalizeIndex(args.length, req)
|
|
@@ -1018,6 +962,10 @@ function _makeGetReq(shim, req) {
|
|
|
1018
962
|
}
|
|
1019
963
|
}
|
|
1020
964
|
|
|
965
|
+
/**
|
|
966
|
+
* @param nextDetails
|
|
967
|
+
* @param txInfo
|
|
968
|
+
*/
|
|
1021
969
|
function _makeNextBinder(nextDetails, txInfo) {
|
|
1022
970
|
return function bindNext(shim, fn, _name, segment, args) {
|
|
1023
971
|
if (!segment) {
|
|
@@ -1029,6 +977,11 @@ function _makeNextBinder(nextDetails, txInfo) {
|
|
|
1029
977
|
|
|
1030
978
|
// Called from outside to wrap functions that could be called to continue
|
|
1031
979
|
// to the next middleware
|
|
980
|
+
/**
|
|
981
|
+
* @param nodule
|
|
982
|
+
* @param property
|
|
983
|
+
* @param isFinal
|
|
984
|
+
*/
|
|
1032
985
|
function nextWrapper(nodule, property, isFinal) {
|
|
1033
986
|
shim.wrap(nodule, property, function wrapper(shim, original) {
|
|
1034
987
|
const parentSegment = segment || shim.getSegment()
|
|
@@ -1077,11 +1030,9 @@ function _makeNextBinder(nextDetails, txInfo) {
|
|
|
1077
1030
|
* available.
|
|
1078
1031
|
*
|
|
1079
1032
|
* @private
|
|
1080
|
-
*
|
|
1081
1033
|
* @param {WebFrameworkShim} shim - The shim used for this instrumentation.
|
|
1082
1034
|
* @param {http.IncomingMessage} req - The incoming request object.
|
|
1083
|
-
*
|
|
1084
|
-
* @return {object?} The transaction information if available, otherwise null.
|
|
1035
|
+
* @returns {object?} The transaction information if available, otherwise null.
|
|
1085
1036
|
*/
|
|
1086
1037
|
function _getTransactionInfo(shim, req) {
|
|
1087
1038
|
try {
|
|
@@ -1096,8 +1047,8 @@ function _getTransactionInfo(shim, req) {
|
|
|
1096
1047
|
* Creates a recorder for middleware metrics.
|
|
1097
1048
|
*
|
|
1098
1049
|
* @private
|
|
1099
|
-
*
|
|
1100
|
-
*
|
|
1050
|
+
* @param shim
|
|
1051
|
+
* @param metricName
|
|
1101
1052
|
* @param {string} path - The mounting path of the middleware.
|
|
1102
1053
|
* @param {Segment} segment - The segment generated for this middleware.
|
|
1103
1054
|
* @param {string} scope - The scope of the metric to record.
|
|
@@ -1119,13 +1070,10 @@ function _makeMiddlewareRecorder(shim, metricName) {
|
|
|
1119
1070
|
* Adds the given error to the transaction information if it is actually an error.
|
|
1120
1071
|
*
|
|
1121
1072
|
* @private
|
|
1122
|
-
*
|
|
1123
1073
|
* @param {WebFrameworkShim} shim
|
|
1124
1074
|
* The shim used for this web framework.
|
|
1125
|
-
*
|
|
1126
1075
|
* @param {TransactionInfo} txInfo
|
|
1127
1076
|
* The transaction context information for the request.
|
|
1128
|
-
*
|
|
1129
1077
|
* @param {*} err
|
|
1130
1078
|
* The error to notice.
|
|
1131
1079
|
*/
|
|
@@ -1138,14 +1086,11 @@ function _noticeError(shim, txInfo, err) {
|
|
|
1138
1086
|
* Determines if the given object is an error according to the shim.
|
|
1139
1087
|
*
|
|
1140
1088
|
* @private
|
|
1141
|
-
*
|
|
1142
1089
|
* @param {WebFrameworkShim} shim
|
|
1143
1090
|
* The shim used for this web framework.
|
|
1144
|
-
*
|
|
1145
1091
|
* @param {?*} err
|
|
1146
1092
|
* The object to check for error-ness.
|
|
1147
|
-
*
|
|
1148
|
-
* @return {bool} True if the given object is an error according to the shim.
|
|
1093
|
+
* @returns {bool} True if the given object is an error according to the shim.
|
|
1149
1094
|
*/
|
|
1150
1095
|
function _isError(shim, err) {
|
|
1151
1096
|
return err && shim._errorPredicate(err)
|
|
@@ -1155,11 +1100,9 @@ function _isError(shim, err) {
|
|
|
1155
1100
|
* Copy the keys expected from source to destination.
|
|
1156
1101
|
*
|
|
1157
1102
|
* @private
|
|
1158
|
-
*
|
|
1159
|
-
* @param {Object} destination
|
|
1103
|
+
* @param {object} destination
|
|
1160
1104
|
* The spec object receiving the expected values
|
|
1161
|
-
*
|
|
1162
|
-
* @param {Object} source
|
|
1105
|
+
* @param {object} source
|
|
1163
1106
|
* The spec object the values are coming from
|
|
1164
1107
|
*/
|
|
1165
1108
|
function _copyExpectedSpecParameters(destination, source) {
|
package/lib/util/logger.js
CHANGED
|
@@ -39,7 +39,8 @@ function Logger(options, extra) {
|
|
|
39
39
|
const passedInLevel = this.coerce(options.level)
|
|
40
40
|
this.options = {
|
|
41
41
|
_level: passedInLevel,
|
|
42
|
-
enabled: options.enabled === undefined ? true : options.enabled
|
|
42
|
+
enabled: options.enabled === undefined ? true : options.enabled,
|
|
43
|
+
configured: options.configured === undefined ? true : !!options.configured
|
|
43
44
|
}
|
|
44
45
|
this._nestedLog = false
|
|
45
46
|
this.name = options.name
|
|
@@ -47,12 +48,30 @@ function Logger(options, extra) {
|
|
|
47
48
|
this.extra = extra || Object.create(null)
|
|
48
49
|
this.buffer = ''
|
|
49
50
|
this.reading = false
|
|
51
|
+
this.logQueue = []
|
|
50
52
|
if (options.stream) {
|
|
51
53
|
this.pipe(options.stream)
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
Logger.MAX_LOG_BUFFER = MAX_LOG_BUFFER
|
|
55
57
|
|
|
58
|
+
Logger.prototype.configure = function configure(options) {
|
|
59
|
+
if (options.name !== undefined) {
|
|
60
|
+
this.name = options.name
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (options.enabled !== undefined) {
|
|
64
|
+
this.options.enabled = options.enabled
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (options.level !== undefined) {
|
|
68
|
+
this.options._level = this.coerce(options.level)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.options.configured = true
|
|
72
|
+
this._flushQueuedLogs()
|
|
73
|
+
}
|
|
74
|
+
|
|
56
75
|
Logger.prototype.coerce = function coerce(value) {
|
|
57
76
|
if (!isNaN(parseInt(value, 10)) && isFinite(value)) {
|
|
58
77
|
// value is numeric
|
|
@@ -74,6 +93,11 @@ Object.keys(LEVELS).forEach(function buildLevel(_level) {
|
|
|
74
93
|
const level = Logger.prototype.coerce(LEVELS[_level])
|
|
75
94
|
|
|
76
95
|
function log(extra) {
|
|
96
|
+
if (!this.options.configured) {
|
|
97
|
+
this.logQueue.unshift({ level: _level, args: arguments })
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
77
101
|
if (!this.options.enabled) {
|
|
78
102
|
return false
|
|
79
103
|
}
|
|
@@ -149,6 +173,13 @@ Object.keys(LEVELS).forEach(function buildLevel(_level) {
|
|
|
149
173
|
}
|
|
150
174
|
})
|
|
151
175
|
|
|
176
|
+
Logger.prototype._flushQueuedLogs = function _flushQueuedLogs() {
|
|
177
|
+
while (this.logQueue.length) {
|
|
178
|
+
const { level, args } = this.logQueue.shift()
|
|
179
|
+
this[level].apply(this, args)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
152
183
|
Object.assign(Logger.prototype, loggingFunctions)
|
|
153
184
|
|
|
154
185
|
Logger.prototype.child = function child(extra) {
|
|
@@ -196,6 +227,10 @@ Logger.prototype._read = function _read() {
|
|
|
196
227
|
* already converted the objects to strings.
|
|
197
228
|
* Returns a boolean representing the status of the write
|
|
198
229
|
* (success/failure)
|
|
230
|
+
*
|
|
231
|
+
* @param level
|
|
232
|
+
* @param args
|
|
233
|
+
* @param extra
|
|
199
234
|
*/
|
|
200
235
|
Logger.prototype.write = function write(level, args, extra) {
|
|
201
236
|
if (this._nestedLog) {
|
|
@@ -9,6 +9,7 @@ const logger = require('../logger.js').child({ component: 'aws-info' })
|
|
|
9
9
|
const common = require('./common')
|
|
10
10
|
const NAMES = require('../metrics/names.js')
|
|
11
11
|
let results = null
|
|
12
|
+
const INSTANCE_HOST = '169.254.169.254'
|
|
12
13
|
|
|
13
14
|
module.exports = fetchAWSInfo
|
|
14
15
|
module.exports.clearCache = function clearAWSCache() {
|
|
@@ -24,27 +25,45 @@ function fetchAWSInfo(agent, callback) {
|
|
|
24
25
|
return setImmediate(callback, null, results)
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const authTokenOpts = {
|
|
29
|
+
headers: { 'X-aws-ec2-metadata-token-ttl-seconds': '21600' },
|
|
30
|
+
host: INSTANCE_HOST,
|
|
31
|
+
method: 'PUT',
|
|
32
|
+
path: '/latest/api/token',
|
|
33
|
+
timeout: 500
|
|
34
|
+
}
|
|
35
|
+
common.request(authTokenOpts, agent, function getAuthToken(err, authToken) {
|
|
32
36
|
if (err) {
|
|
37
|
+
logger.debug('Failed to get AWS auth token.')
|
|
33
38
|
return callback(err)
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
const metadataOpts = {
|
|
42
|
+
headers: { 'X-aws-ec2-metadata-token': authToken },
|
|
43
|
+
host: INSTANCE_HOST,
|
|
44
|
+
method: 'GET',
|
|
45
|
+
path: '/latest/dynamic/instance-identity/document',
|
|
46
|
+
timeout: 500
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
common.request(metadataOpts, agent, function getMetadata(metaErr, data) {
|
|
50
|
+
if (metaErr) {
|
|
51
|
+
return callback(metaErr)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
data = JSON.parse(data)
|
|
56
|
+
} catch (e) {
|
|
57
|
+
logger.debug(e, 'Failed to parse AWS metadata.')
|
|
58
|
+
data = null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
results = common.getKeys(data, ['availabilityZone', 'instanceId', 'instanceType'])
|
|
62
|
+
if (results == null) {
|
|
63
|
+
logger.debug('AWS metadata was invalid.')
|
|
64
|
+
agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.AWS_ERROR).incrementCallCount()
|
|
65
|
+
}
|
|
66
|
+
callback(null, results)
|
|
67
|
+
})
|
|
49
68
|
})
|
|
50
69
|
}
|
|
@@ -65,6 +65,12 @@ exports.request = function request(opts, agent, cb) {
|
|
|
65
65
|
|
|
66
66
|
opts.timeout = opts.timeout || 1000
|
|
67
67
|
|
|
68
|
+
// This can make more that GET requests if you pass in an object
|
|
69
|
+
// Node.js just pass this method into ClientRequest which accepts
|
|
70
|
+
// any valid HTTP Method
|
|
71
|
+
// see: https://github.com/nodejs/node/blob/master/lib/http.js#L106
|
|
72
|
+
// Technically this wouldn't work for a PUT/POST with a body
|
|
73
|
+
// but works fine in all cases where this is being used.
|
|
68
74
|
const req = http.get(opts, function awsRequest(res) {
|
|
69
75
|
res.pipe(concat(respond))
|
|
70
76
|
function respond(data) {
|
|
@@ -89,9 +95,7 @@ exports.request = function request(opts, agent, cb) {
|
|
|
89
95
|
}
|
|
90
96
|
})
|
|
91
97
|
|
|
92
|
-
req.
|
|
93
|
-
req.abort()
|
|
94
|
-
})
|
|
98
|
+
req.on('timeout', abortRequest)
|
|
95
99
|
|
|
96
100
|
req.on('error', function requestError(err) {
|
|
97
101
|
if (err.code === 'ECONNRESET') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newrelic",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.9.1",
|
|
4
4
|
"author": "New Relic Node.js agent team <nodejs@newrelic.com>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"contributors": [
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"prepare-test": "npm run ca-gen && npm run ssl && npm run docker-env",
|
|
137
137
|
"lint": "eslint ./*.js lib test bin examples",
|
|
138
138
|
"lint:fix": "eslint --fix, ./*.js lib test bin examples",
|
|
139
|
-
"public-docs": "
|
|
139
|
+
"public-docs": "jsdoc -c ./jsdoc-conf.json --tutorials examples/shim api.js lib/shim/ lib/transaction/handle.js && cp examples/shim/*.png out/",
|
|
140
140
|
"publish-docs": "./bin/publish-docs.sh",
|
|
141
141
|
"services": "./bin/docker-services.sh",
|
|
142
142
|
"smoke": "npm run ssl && time tap test/smoke/**/**/*.tap.js --timeout=180 --no-coverage",
|
|
@@ -159,13 +159,13 @@
|
|
|
159
159
|
"newrelic-naming-rules": "./bin/test-naming-rules.js"
|
|
160
160
|
},
|
|
161
161
|
"dependencies": {
|
|
162
|
-
"@grpc/grpc-js": "^1.
|
|
163
|
-
"@grpc/proto-loader": "^0.
|
|
162
|
+
"@grpc/grpc-js": "^1.5.5",
|
|
163
|
+
"@grpc/proto-loader": "^0.6.9",
|
|
164
164
|
"@newrelic/aws-sdk": "^4.1.1",
|
|
165
|
-
"@newrelic/koa": "^6.
|
|
166
|
-
"@newrelic/superagent": "^5.0
|
|
165
|
+
"@newrelic/koa": "^6.1.1",
|
|
166
|
+
"@newrelic/superagent": "^5.1.0",
|
|
167
167
|
"@tyriar/fibonacci-heap": "^2.0.7",
|
|
168
|
-
"async": "^3.2.
|
|
168
|
+
"async": "^3.2.3",
|
|
169
169
|
"concat-stream": "^2.0.0",
|
|
170
170
|
"https-proxy-agent": "^5.0.0",
|
|
171
171
|
"json-stringify-safe": "^5.0.0",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"semver": "^5.3.0"
|
|
174
174
|
},
|
|
175
175
|
"optionalDependencies": {
|
|
176
|
-
"@newrelic/native-metrics": "^7.
|
|
176
|
+
"@newrelic/native-metrics": "^7.1.1"
|
|
177
177
|
},
|
|
178
178
|
"devDependencies": {
|
|
179
179
|
"@newrelic/eslint-config": "^0.0.3",
|