newrelic 12.1.0 → 12.1.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 +20 -0
- package/lib/instrumentation/@node-redis/client.js +3 -2
- package/lib/instrumentation/amqplib/amqplib.js +34 -13
- package/lib/instrumentation/amqplib/channel-model.js +4 -9
- package/lib/instrumentation/amqplib/channel.js +22 -19
- package/lib/instrumentation/amqplib/utils.js +23 -21
- package/lib/instrumentation/kafkajs/record-linking-metrics.js +1 -1
- package/lib/instrumentation/pino/pino.js +21 -11
- package/package.json +1 -1
package/NEWS.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
### v12.1.1 (2024-08-15)
|
|
2
|
+
|
|
3
|
+
#### Bug fixes
|
|
4
|
+
|
|
5
|
+
* Updated `amqplib` instrumentation to properly parse host/port from connect ([#2461](https://github.com/newrelic/node-newrelic/pull/2461)) ([91636a8](https://github.com/newrelic/node-newrelic/commit/91636a8e9702ba4ad1bf9b3941432ea65a3920fe))
|
|
6
|
+
* Updated `redis` instrumentation to parse host/port when a url is not provided ([#2463](https://github.com/newrelic/node-newrelic/pull/2463)) ([2b67623](https://github.com/newrelic/node-newrelic/commit/2b67623afef5fb132105c7f5b1d72e23b6d56dc1))
|
|
7
|
+
* Updated the `kafkajs` node metrics to remove `/Named` from the name ([#2458](https://github.com/newrelic/node-newrelic/pull/2458)) ([37ce113](https://github.com/newrelic/node-newrelic/commit/37ce1137a91c2efa85541cf6ec252a759e5f48ea))
|
|
8
|
+
|
|
9
|
+
#### Code refactoring
|
|
10
|
+
|
|
11
|
+
* Updated pino instrumentation to separate the wrapping of asJson into its own function ([#2464](https://github.com/newrelic/node-newrelic/pull/2464)) ([81fdde1](https://github.com/newrelic/node-newrelic/commit/81fdde1e35b5643ff141db1309ca58d7f6176cd5))
|
|
12
|
+
|
|
13
|
+
#### Documentation
|
|
14
|
+
|
|
15
|
+
* Updated compatibility report ([#2460](https://github.com/newrelic/node-newrelic/pull/2460)) ([a4570e9](https://github.com/newrelic/node-newrelic/commit/a4570e93298d10f4464570b75867634b95a61e89))
|
|
16
|
+
|
|
17
|
+
#### Miscellaneous chores
|
|
18
|
+
|
|
19
|
+
* Removed limit on superagent versioned testing ([#2456](https://github.com/newrelic/node-newrelic/pull/2456)) ([b4b6a6b](https://github.com/newrelic/node-newrelic/commit/b4b6a6b2eca8bd47d17f8b265344b4596c8226b3))
|
|
20
|
+
|
|
1
21
|
### v12.1.0 (2024-08-12)
|
|
2
22
|
|
|
3
23
|
#### Bug fixes
|
|
@@ -104,8 +104,9 @@ function getRedisParams(clientOpts) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
return new DatastoreParameters({
|
|
107
|
-
host: clientOpts?.socket?.host || 'localhost',
|
|
108
|
-
port_path_or_id:
|
|
107
|
+
host: clientOpts?.host || clientOpts?.socket?.host || 'localhost',
|
|
108
|
+
port_path_or_id:
|
|
109
|
+
clientOpts?.port || clientOpts?.socket?.path || clientOpts?.socket?.port || '6379',
|
|
109
110
|
database_name: clientOpts?.database || 0
|
|
110
111
|
})
|
|
111
112
|
}
|
|
@@ -9,10 +9,10 @@ const {
|
|
|
9
9
|
OperationSpec,
|
|
10
10
|
params: { DatastoreParameters }
|
|
11
11
|
} = require('../../shim/specs')
|
|
12
|
-
const url = require('url')
|
|
13
12
|
const wrapModel = require('./channel-model')
|
|
14
|
-
const { setCallback } = require('./utils')
|
|
13
|
+
const { setCallback, parseConnectionArgs } = require('./utils')
|
|
15
14
|
const wrapChannel = require('./channel')
|
|
15
|
+
const { amqpConnection } = require('../../symbols')
|
|
16
16
|
|
|
17
17
|
module.exports.instrumentPromiseAPI = instrumentChannelAPI
|
|
18
18
|
module.exports.instrumentCallbackAPI = instrumentCallbackAPI
|
|
@@ -73,31 +73,52 @@ function instrumentAMQP(shim, amqp, promiseMode) {
|
|
|
73
73
|
/**
|
|
74
74
|
*
|
|
75
75
|
* Instruments the connect method
|
|
76
|
+
* We have to both wrap and record because
|
|
77
|
+
* we need the host/port for all subsequent calls on the model/channel
|
|
78
|
+
* but record only completes in an active transaction
|
|
76
79
|
*
|
|
77
80
|
* @param {Shim} shim instance of shim
|
|
78
81
|
* @param {object} amqp amqplib object
|
|
79
82
|
* @param {boolean} promiseMode is this promise based?
|
|
80
83
|
*/
|
|
81
84
|
function wrapConnect(shim, amqp, promiseMode) {
|
|
82
|
-
shim.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
shim.wrap(amqp, 'connect', function wrapConnect(shim, connect) {
|
|
86
|
+
return function wrappedConnect() {
|
|
87
|
+
const args = shim.argsToArray.apply(shim, arguments)
|
|
88
|
+
const [connArgs] = args
|
|
89
|
+
const params = parseConnectionArgs({ shim, connArgs })
|
|
90
|
+
const cb = args[args.length - 1]
|
|
91
|
+
if (!promiseMode) {
|
|
92
|
+
args[args.length - 1] = function wrappedCallback() {
|
|
93
|
+
const cbArgs = shim.argsToArray.apply(shim, arguments)
|
|
94
|
+
const [, c] = cbArgs
|
|
95
|
+
c.connection[amqpConnection] = params
|
|
96
|
+
return cb.apply(this, cbArgs)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
85
99
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
100
|
+
const result = connect.apply(this, args)
|
|
101
|
+
if (promiseMode) {
|
|
102
|
+
return result.then((c) => {
|
|
103
|
+
c.connection[amqpConnection] = params
|
|
104
|
+
return c
|
|
105
|
+
})
|
|
91
106
|
}
|
|
107
|
+
return result
|
|
92
108
|
}
|
|
109
|
+
})
|
|
93
110
|
|
|
111
|
+
shim.record(amqp, 'connect', function recordConnect(shim, connect, name, args) {
|
|
112
|
+
const [connArgs] = args
|
|
113
|
+
const params = parseConnectionArgs({ shim, connArgs })
|
|
94
114
|
return new OperationSpec({
|
|
95
115
|
name: 'amqplib.connect',
|
|
96
116
|
callback: setCallback(shim, promiseMode),
|
|
97
117
|
promise: promiseMode,
|
|
98
|
-
parameters:
|
|
99
|
-
|
|
100
|
-
|
|
118
|
+
parameters: new DatastoreParameters({
|
|
119
|
+
host: params.host,
|
|
120
|
+
port_path_or_id: params.port
|
|
121
|
+
})
|
|
101
122
|
})
|
|
102
123
|
})
|
|
103
124
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
const { MessageSpec, MessageSubscribeSpec, RecorderSpec } = require('../../shim/specs')
|
|
8
|
+
const { amqpConnection } = require('../../symbols')
|
|
8
9
|
const CHANNEL_METHODS = [
|
|
9
10
|
'close',
|
|
10
11
|
'open',
|
|
@@ -22,13 +23,7 @@ const CHANNEL_METHODS = [
|
|
|
22
23
|
'prefetch',
|
|
23
24
|
'recover'
|
|
24
25
|
]
|
|
25
|
-
const {
|
|
26
|
-
describeMessage,
|
|
27
|
-
setCallback,
|
|
28
|
-
parseConnect,
|
|
29
|
-
getParametersFromMessage,
|
|
30
|
-
TEMP_RE
|
|
31
|
-
} = require('./utils')
|
|
26
|
+
const { describeMessage, setCallback, getParametersFromMessage, TEMP_RE } = require('./utils')
|
|
32
27
|
|
|
33
28
|
/**
|
|
34
29
|
*
|
|
@@ -89,7 +84,7 @@ function recordPurge({ shim, proto, promiseMode }) {
|
|
|
89
84
|
|
|
90
85
|
function recordGet({ shim, proto, promiseMode }) {
|
|
91
86
|
shim.recordConsume(proto, 'get', function wrapGet() {
|
|
92
|
-
const { host, port } =
|
|
87
|
+
const { host, port } = this?.connection?.[amqpConnection] || {}
|
|
93
88
|
return new MessageSpec({
|
|
94
89
|
destinationName: shim.FIRST,
|
|
95
90
|
callback: setCallback(shim, promiseMode),
|
|
@@ -115,7 +110,7 @@ function recordGet({ shim, proto, promiseMode }) {
|
|
|
115
110
|
|
|
116
111
|
function recordConsume({ shim, proto, promiseMode }) {
|
|
117
112
|
shim.recordSubscribedConsume(proto, 'consume', function consume() {
|
|
118
|
-
const { host, port } =
|
|
113
|
+
const { host, port } = this?.connection?.[amqpConnection] || {}
|
|
119
114
|
return new MessageSubscribeSpec({
|
|
120
115
|
name: 'amqplib.Channel#consume',
|
|
121
116
|
queue: shim.FIRST,
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
const { MessageSpec } = require('../../shim/specs')
|
|
8
|
-
const {
|
|
8
|
+
const { amqpConnection } = require('../../symbols')
|
|
9
|
+
const { getParameters, TEMP_RE } = require('./utils')
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
@@ -47,24 +48,26 @@ module.exports = function wrapChannel(shim) {
|
|
|
47
48
|
}
|
|
48
49
|
})
|
|
49
50
|
|
|
50
|
-
shim.recordProduce(proto, 'sendMessage',
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
shim.recordProduce(proto, 'sendMessage', recordSendMessage)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function recordSendMessage(shim, fn, n, args) {
|
|
55
|
+
const fields = args[0]
|
|
56
|
+
if (!fields) {
|
|
57
|
+
return null
|
|
58
|
+
}
|
|
59
|
+
const isDefault = fields.exchange === ''
|
|
60
|
+
let exchange = 'Default'
|
|
61
|
+
if (!isDefault) {
|
|
62
|
+
exchange = TEMP_RE.test(fields.exchange) ? null : fields.exchange
|
|
63
|
+
}
|
|
64
|
+
const { host, port } = this?.connection?.[amqpConnection] || {}
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
})
|
|
66
|
+
return new MessageSpec({
|
|
67
|
+
destinationName: exchange,
|
|
68
|
+
destinationType: shim.EXCHANGE,
|
|
69
|
+
routingKey: fields.routingKey,
|
|
70
|
+
headers: fields.headers,
|
|
71
|
+
parameters: getParameters({ parameters: Object.create(null), fields, host, port })
|
|
69
72
|
})
|
|
70
73
|
}
|
|
@@ -8,7 +8,6 @@ const {
|
|
|
8
8
|
MessageSpec,
|
|
9
9
|
params: { QueueMessageParameters }
|
|
10
10
|
} = require('../../shim/specs')
|
|
11
|
-
const { amqpConnection } = require('../../symbols')
|
|
12
11
|
const TEMP_RE = /^amq\./
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -100,25 +99,6 @@ function getParametersFromMessage({ message, host, port }) {
|
|
|
100
99
|
return parameters
|
|
101
100
|
}
|
|
102
101
|
|
|
103
|
-
/**
|
|
104
|
-
* Extracts the host/port from the amqp socket connection.
|
|
105
|
-
* Stores on connection as symbol to only parse once.
|
|
106
|
-
*
|
|
107
|
-
* @param {Socket} socket amqp connection
|
|
108
|
-
* @returns {object} {host, port } of connection
|
|
109
|
-
*/
|
|
110
|
-
function parseConnect(socket) {
|
|
111
|
-
if (socket[amqpConnection]) {
|
|
112
|
-
return socket[amqpConnection]
|
|
113
|
-
}
|
|
114
|
-
const host = ['127.0.0.1', '::1', '[::1]'].includes(socket?.remoteAddress)
|
|
115
|
-
? 'localhost'
|
|
116
|
-
: socket?.remoteAddress
|
|
117
|
-
const port = socket?.remotePort
|
|
118
|
-
socket[amqpConnection] = { host, port }
|
|
119
|
-
return { host, port }
|
|
120
|
-
}
|
|
121
|
-
|
|
122
102
|
/**
|
|
123
103
|
* Helper to set the appropriate value of the callback property
|
|
124
104
|
* in the spec. If it's a promise set to null otherwise set it to `shim.LAST`
|
|
@@ -131,11 +111,33 @@ function setCallback(shim, promiseMode) {
|
|
|
131
111
|
return promiseMode ? null : shim.LAST
|
|
132
112
|
}
|
|
133
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Parses the connection args to return host/port
|
|
116
|
+
*
|
|
117
|
+
* @param {string|object} connArgs connection arguments
|
|
118
|
+
* @returns {object} {host, port }
|
|
119
|
+
*/
|
|
120
|
+
function parseConnectionArgs({ shim, connArgs }) {
|
|
121
|
+
const params = {}
|
|
122
|
+
if (shim.isString(connArgs)) {
|
|
123
|
+
connArgs = new URL(connArgs)
|
|
124
|
+
params.host = connArgs.hostname
|
|
125
|
+
if (connArgs.port) {
|
|
126
|
+
params.port = parseInt(connArgs.port, 10)
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
params.port = connArgs.port || (connArgs.protocol === 'amqp' ? 5672 : 5671)
|
|
130
|
+
params.host = connArgs.hostname
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return params
|
|
134
|
+
}
|
|
135
|
+
|
|
134
136
|
module.exports = {
|
|
135
137
|
describeMessage,
|
|
136
138
|
getParameters,
|
|
137
139
|
getParametersFromMessage,
|
|
138
|
-
|
|
140
|
+
parseConnectionArgs,
|
|
139
141
|
setCallback,
|
|
140
142
|
TEMP_RE
|
|
141
143
|
}
|
|
@@ -11,7 +11,7 @@ function recordLinkingMetrics({ agent, brokers, topic, producer = true }) {
|
|
|
11
11
|
const kind = producer === true ? 'Produce' : 'Consume'
|
|
12
12
|
for (const broker of brokers) {
|
|
13
13
|
agent.metrics
|
|
14
|
-
.getOrCreateMetric(`MessageBroker/Kafka/Nodes/${broker}/${kind}
|
|
14
|
+
.getOrCreateMetric(`MessageBroker/Kafka/Nodes/${broker}/${kind}/${topic}`)
|
|
15
15
|
.incrementCallCount()
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -15,7 +15,6 @@ const {
|
|
|
15
15
|
} = require('../../util/application-logging')
|
|
16
16
|
const semver = require('semver')
|
|
17
17
|
|
|
18
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
19
18
|
module.exports = function instrument(shim, tools) {
|
|
20
19
|
const pinoVersion = shim.pkgVersion
|
|
21
20
|
|
|
@@ -35,7 +34,20 @@ module.exports = function instrument(shim, tools) {
|
|
|
35
34
|
const metrics = agent.metrics
|
|
36
35
|
createModuleUsageMetric('pino', metrics)
|
|
37
36
|
|
|
37
|
+
wrapAsJson({ shim, tools })
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Wraps `asJson` to properly decorate and forward logs
|
|
42
|
+
*
|
|
43
|
+
* @param {object} params to function
|
|
44
|
+
* @param {Shim} params.shim instance of shim
|
|
45
|
+
* @param {object} params.tools exported `pino/lib/tools`
|
|
46
|
+
*/
|
|
47
|
+
function wrapAsJson({ shim, tools }) {
|
|
38
48
|
const symbols = shim.require('./lib/symbols')
|
|
49
|
+
const { agent } = shim
|
|
50
|
+
const { config, metrics } = agent
|
|
39
51
|
|
|
40
52
|
shim.wrap(tools, 'asJson', function wrapJson(shim, asJson) {
|
|
41
53
|
/**
|
|
@@ -98,16 +110,14 @@ module.exports = function instrument(shim, tools) {
|
|
|
98
110
|
* reformats error and assigns NR context data
|
|
99
111
|
* to log line
|
|
100
112
|
*
|
|
101
|
-
* @param
|
|
102
|
-
* @param {object} logLine log line
|
|
103
|
-
* @param {
|
|
104
|
-
* @param {
|
|
105
|
-
* @param
|
|
106
|
-
* @param
|
|
107
|
-
* @param
|
|
108
|
-
* @
|
|
109
|
-
* @param logLine.level
|
|
110
|
-
* @param logLine.logger
|
|
113
|
+
* @param {object} params to function
|
|
114
|
+
* @param {object} params.logLine log line
|
|
115
|
+
* @param {string} params.msg message of log line
|
|
116
|
+
* @param {object} params.agent instance of agent
|
|
117
|
+
* @param {string} params.chindings serialized string of all common log line data
|
|
118
|
+
* @param {string} params.level log level
|
|
119
|
+
* @param {object} params.logger instance of agent logger
|
|
120
|
+
* @returns {function} wrapped log formatter function
|
|
111
121
|
*/
|
|
112
122
|
function reformatLogLine({ logLine, msg, agent, chindings = '', level, logger }) {
|
|
113
123
|
const metadata = agent.getLinkingMetadata()
|