newrelic 8.15.0 → 8.16.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 CHANGED
@@ -1,3 +1,11 @@
1
+ ### v8.16.0 (2022-07-21)
2
+
3
+ * Automatic application log forwarding is now enabled by default. This version of the agent will automatically send enriched application logs to New Relic. To learn more about about this feature, see the [APM logs in context documentation](https://docs.newrelic.com/docs/apm/new-relic-apm/getting-started/get-started-logs-context/). For additional configuration options, see the [Node.js logs in context documentation](https://docs.newrelic.com/docs/logs/logs-context/configure-logs-context-nodejs). To learn about how to toggle log ingestion on or off by account, see our documentation to [disable automatic logging](https://docs.newrelic.com/docs/logs/logs-context/disable-automatic-logging) via the UI or API.
4
+
5
+ * Added a support statement to our release notes
6
+
7
+ * Added node 18 to CI workflows.
8
+
1
9
  ### v8.15.0 (2022-07-07)
2
10
 
3
11
  * Added instrumentation for grpc-js unary, streaming, and bidirectional client calls.
@@ -66,7 +66,6 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
66
66
  * [q](#q)
67
67
  * [redis](#redis)
68
68
  * [request](#request)
69
- * [restify](#restify)
70
69
  * [rimraf](#rimraf)
71
70
  * [should](#should)
72
71
  * [sinon](#sinon)
@@ -2516,7 +2515,7 @@ https://creativecommons.org/licenses/by-sa/4.0/
2516
2515
 
2517
2516
  ### got
2518
2517
 
2519
- This product includes source derived from [got](https://github.com/sindresorhus/got) ([v8.3.2](https://github.com/sindresorhus/got/tree/v8.3.2)), distributed under the [MIT License](https://github.com/sindresorhus/got/blob/v8.3.2/license):
2518
+ This product includes source derived from [got](https://github.com/sindresorhus/got) ([v11.8.5](https://github.com/sindresorhus/got/tree/v11.8.5)), distributed under the [MIT License](https://github.com/sindresorhus/got/blob/v11.8.5/license):
2520
2519
 
2521
2520
  ```
2522
2521
  MIT License
@@ -3208,33 +3207,6 @@ If the Work includes a "NOTICE" text file as part of its distribution, then any
3208
3207
  END OF TERMS AND CONDITIONS
3209
3208
  ```
3210
3209
 
3211
- ### restify
3212
-
3213
- This product includes source derived from [restify](https://github.com/restify/node-restify) ([v8.5.1](https://github.com/restify/node-restify/tree/v8.5.1)), distributed under the [MIT License](https://github.com/restify/node-restify/blob/v8.5.1/LICENSE):
3214
-
3215
- ```
3216
- Copyright (c) 2011 Mark Cavage, All rights reserved.
3217
-
3218
- Permission is hereby granted, free of charge, to any person obtaining a copy
3219
- of this software and associated documentation files (the "Software"), to deal
3220
- in the Software without restriction, including without limitation the rights
3221
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3222
- copies of the Software, and to permit persons to whom the Software is
3223
- furnished to do so, subject to the following conditions:
3224
-
3225
- The above copyright notice and this permission notice shall be included in
3226
- all copies or substantial portions of the Software.
3227
-
3228
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3229
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3230
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3231
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3232
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3233
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3234
- THE SOFTWARE
3235
-
3236
- ```
3237
-
3238
3210
  ### rimraf
3239
3211
 
3240
3212
  This product includes source derived from [rimraf](https://github.com/isaacs/rimraf) ([v2.7.1](https://github.com/isaacs/rimraf/tree/v2.7.1)), distributed under the [ISC License](https://github.com/isaacs/rimraf/blob/v2.7.1/LICENSE):
@@ -950,7 +950,7 @@ exports.config = () => ({
950
950
  *
951
951
  * @env NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED
952
952
  */
953
- enabled: false,
953
+ enabled: true,
954
954
  /**
955
955
  * Number of log records to send per minute to New Relic.
956
956
  *
@@ -127,13 +127,22 @@ common.makeBulkDescFunc = function makeBulkDescFunc(shim) {
127
127
  *
128
128
  * @param {Shim} shim
129
129
  * @param {Instrumentation} instrumenter instance of mongo APM class
130
+ * @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
130
131
  */
131
- common.captureAttributesOnStarted = function captureAttributesOnStarted(shim, instrumenter) {
132
+ common.captureAttributesOnStarted = function captureAttributesOnStarted(
133
+ shim,
134
+ instrumenter,
135
+ options = { skipCommands: [] }
136
+ ) {
132
137
  instrumenter.on('started', function onMongoEventStarted(evnt) {
138
+ if (options.skipCommands.includes(evnt.commandName)) {
139
+ return
140
+ }
133
141
  // This assumes that this `started` event is fired _after_ our wrapper
134
142
  // starts and creates the segment. We perform a check of the segment name
135
143
  // out of an excess of caution.
136
144
  const connId = evnt.connectionId
145
+
137
146
  if (connId) {
138
147
  // used in v3 when connection is a cluster pool
139
148
  if (typeof connId === 'number') {
@@ -165,7 +174,7 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(shim, in
165
174
  * @param {object} client mongo client instance
166
175
  */
167
176
  function setHostPort(shim, connStr, db, client) {
168
- const parts = connStr.split(':')
177
+ const parts = common.parseAddress(connStr)
169
178
  // in v3 when running with a cluster of socket connections
170
179
  // the address is `undefined:undefined`. we will instead attempt
171
180
  // to get connection details from the client symbol NR_ATTRS
@@ -189,7 +198,7 @@ function setHostPort(shim, connStr, db, client) {
189
198
 
190
199
  /**
191
200
  * Get the database_name, host, port_path_or_id
192
- * for the query segment. v4 refactored where the toplogy is stored.
201
+ * for the query segment. v4 refactored where the topology is stored.
193
202
  * You can now get the details via the client obj that's deeply nested
194
203
  * See: https://github.com/mongodb/node-mongodb-native/pull/2594/files#diff-1d214e57ddda9095d296e5700ebce701333bfefcf417e234c584d14091b2f50dR168
195
204
  *
@@ -202,8 +211,8 @@ function getInstanceAttributeParameters(shim, obj) {
202
211
  const databaseName =
203
212
  (obj.s.db && obj.s.db.databaseName) || (obj.s.namespace && obj.s.namespace.db) || null
204
213
  const topology = obj.s.topology
205
- if (topology.s && topology.s.options) {
206
- return doCapture(topology.s.options, databaseName)
214
+ if (topology) {
215
+ return doCapture(topology, databaseName)
207
216
  }
208
217
  } else if (
209
218
  obj.s &&
@@ -241,13 +250,13 @@ function getInstanceAttributeParameters(shim, obj) {
241
250
 
242
251
  function doCapture(conf, database) {
243
252
  // in older versions of 3.x the host/port
244
- // lived directly on the topology.s.options
253
+ // lived directly on the topology
245
254
  let host = conf.host
246
255
  let port = conf.port
247
256
 
248
257
  // servers is an array but we will always pull the first for consistency
249
- if (conf.servers && conf.servers.length) {
250
- ;[{ host, port }] = conf.servers
258
+ if (conf.s && conf.s.options && conf.s.options.servers && conf.s.options.servers.length) {
259
+ ;[{ host, port }] = conf.s.options.servers
251
260
  }
252
261
 
253
262
  // host is a domain socket. set host as localhost and use the domain
@@ -264,3 +273,16 @@ function getInstanceAttributeParameters(shim, obj) {
264
273
  }
265
274
  }
266
275
  }
276
+
277
+ /**
278
+ * Parses mongo address that accounts for IPv6
279
+ *
280
+ * @param {string} address mongo address string
281
+ * @returns {Array} host/port of address string
282
+ */
283
+ common.parseAddress = function parseAddress(address) {
284
+ const lastColon = address.lastIndexOf(':')
285
+ const host = address.slice(0, lastColon)
286
+ const port = address.slice(lastColon + 1)
287
+ return [host, port]
288
+ }
@@ -18,7 +18,7 @@ const {
18
18
  * parser used to grab the collection and operation
19
19
  * on every mongo operation
20
20
  *
21
- * @param {Object} operation
21
+ * @param {object} operation
22
22
  */
23
23
  function queryParser(operation) {
24
24
  let collection = this.collectionName || 'unknown'
@@ -40,7 +40,7 @@ function queryParser(operation) {
40
40
  * is a cluster of domain sockets
41
41
  *
42
42
  * @param {Shim} shim
43
- * @param {Object} mongodb resolved package
43
+ * @param {object} mongodb resolved package
44
44
  */
45
45
  function instrumentClient(shim, mongodb) {
46
46
  shim.recordOperation(mongodb.MongoClient, 'connect', function wrappedConnect(shim, _, __, args) {
@@ -61,13 +61,16 @@ function instrumentClient(shim, mongodb) {
61
61
  * add necessary attributes to segments
62
62
  *
63
63
  * @param {Shim} shim
64
- * @param {Object} mongodb resolved package
64
+ * @param {object} mongodb resolved package
65
65
  */
66
66
  module.exports = function instrument(shim, mongodb) {
67
67
  shim.setParser(queryParser)
68
68
  instrumentClient(shim, mongodb)
69
69
  const instrumenter = mongodb.instrument(Object.create(null), () => {})
70
- captureAttributesOnStarted(shim, instrumenter)
70
+ // in v3 of mongo endSessions fires after every command and it updates the active segment
71
+ // attributes with the admin database name which stomps on the database name where the original
72
+ // command runs on
73
+ captureAttributesOnStarted(shim, instrumenter, { skipCommands: ['endSessions'] })
71
74
  instrumentCursor(shim, mongodb.Cursor)
72
75
  instrumentCursor(shim, shim.require('./lib/aggregation_cursor'))
73
76
  instrumentCursor(shim, shim.require('./lib/command_cursor'))
@@ -5,13 +5,13 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- const { instrumentCollection, instrumentCursor, instrumentDb } = require('./common')
8
+ const { instrumentCollection, instrumentCursor, instrumentDb, parseAddress } = require('./common')
9
9
 
10
10
  /**
11
11
  * parser used to grab the collection and operation
12
12
  * from a running query
13
13
  *
14
- * @param {Object} operation
14
+ * @param {object} operation
15
15
  */
16
16
  function queryParser(operation) {
17
17
  let collection = this.collectionName || 'unknown'
@@ -34,7 +34,7 @@ function queryParser(operation) {
34
34
  */
35
35
  function cmdStartedHandler(shim, evnt) {
36
36
  if (evnt.connectionId) {
37
- let [host, port] = evnt.address.split(':')
37
+ let [host, port] = parseAddress(evnt.address)
38
38
 
39
39
  // connection via socket get port from 1st host
40
40
  // socketPath property
@@ -45,7 +45,7 @@ function cmdStartedHandler(shim, evnt) {
45
45
  if (hosts && hosts.length && hosts[0].socketPath) {
46
46
  port = hosts[0].socketPath
47
47
  }
48
- } else if (host === '127.0.0.1') {
48
+ } else if (['127.0.0.1', '::1'].includes(host)) {
49
49
  host = 'localhost'
50
50
  }
51
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "8.15.0",
3
+ "version": "8.16.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [
@@ -213,7 +213,6 @@
213
213
  "q": "*",
214
214
  "redis": "^1.0.0",
215
215
  "request": "^2.88.0",
216
- "restify": "^8.4.0",
217
216
  "rimraf": "^2.6.3",
218
217
  "should": "*",
219
218
  "sinon": "^4.5.0",