newrelic 13.3.3 → 13.4.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.
Files changed (109) hide show
  1. package/NEWS.md +22 -0
  2. package/THIRD_PARTY_NOTICES.md +11 -11
  3. package/esm-loader.mjs +2 -2
  4. package/lib/attributes.js +4 -4
  5. package/lib/collector/facts.js +1 -1
  6. package/lib/collector/http-agents.js +2 -2
  7. package/lib/collector/parse-response.js +9 -12
  8. package/lib/collector/remote-method.js +4 -5
  9. package/lib/config/formatters.js +2 -3
  10. package/lib/config/index.js +6 -6
  11. package/lib/harvester.js +1 -1
  12. package/lib/header-processing.js +3 -3
  13. package/lib/instrumentation/@node-redis/client.js +1 -1
  14. package/lib/instrumentation/aws-sdk/v2/instrumentation-helper.js +2 -2
  15. package/lib/instrumentation/aws-sdk/v3/common.js +5 -5
  16. package/lib/instrumentation/aws-sdk/v3/dynamodb.js +4 -4
  17. package/lib/instrumentation/aws-sdk/v3/sns.js +9 -9
  18. package/lib/instrumentation/aws-sdk/v3/sqs.js +6 -6
  19. package/lib/instrumentation/core/http-outbound.js +1 -2
  20. package/lib/instrumentation/fastify/spec-builders.js +11 -11
  21. package/lib/instrumentation/fastify.js +4 -4
  22. package/lib/instrumentation/memcached.js +4 -4
  23. package/lib/instrumentation/mongodb.js +2 -2
  24. package/lib/instrumentation/undici.js +3 -3
  25. package/lib/instrumentations.js +0 -2
  26. package/lib/llm-events/aws-bedrock/bedrock-response.js +6 -6
  27. package/lib/llm-events/aws-bedrock/converse-stream-handler.js +1 -1
  28. package/lib/llm-events/aws-bedrock/stream-handler.js +4 -4
  29. package/lib/metrics/index.js +2 -2
  30. package/lib/metrics/normalizer/rule.js +1 -1
  31. package/lib/metrics/normalizer.js +4 -5
  32. package/lib/metrics/recorders/message-transaction.js +3 -3
  33. package/lib/otel/context-manager.js +4 -4
  34. package/lib/otel/trace-propagator.js +1 -1
  35. package/lib/prioritized-attributes.js +2 -2
  36. package/lib/serverless/aws-lambda.js +4 -4
  37. package/lib/shim/datastore-shim.js +1 -1
  38. package/lib/shim/message-shim/consume.js +1 -1
  39. package/lib/shim/message-shim/subscribe-consume.js +1 -2
  40. package/lib/shim/promise-shim.js +1 -3
  41. package/lib/shim/shim.js +3 -4
  42. package/lib/shim/transaction-shim.js +0 -1
  43. package/lib/shim/webframework-shim/common.js +2 -4
  44. package/lib/shim/webframework-shim/middleware.js +8 -8
  45. package/lib/spans/span-context.js +1 -1
  46. package/lib/spans/span-event-aggregator.js +2 -2
  47. package/lib/spans/span-event.js +6 -5
  48. package/lib/spans/streaming-span-attributes.js +1 -1
  49. package/lib/spans/streaming-span-event-aggregator.js +1 -2
  50. package/lib/stats/index.js +1 -1
  51. package/lib/subscriber-configs.js +2 -0
  52. package/lib/subscribers/amqplib/accept-message.js +14 -0
  53. package/lib/subscribers/amqplib/callback-model.js +39 -0
  54. package/lib/subscribers/amqplib/channel-model.js +39 -0
  55. package/lib/subscribers/amqplib/config.js +695 -0
  56. package/lib/subscribers/amqplib/connect.js +74 -0
  57. package/lib/subscribers/amqplib/consume.js +54 -0
  58. package/lib/subscribers/amqplib/get-cb.js +16 -0
  59. package/lib/subscribers/amqplib/get.js +50 -0
  60. package/lib/subscribers/amqplib/purge-queue-cb.js +16 -0
  61. package/lib/subscribers/amqplib/purge-queue.js +37 -0
  62. package/lib/subscribers/amqplib/send-message.js +44 -0
  63. package/lib/subscribers/amqplib/send-or-enqueue.js +20 -0
  64. package/lib/subscribers/amqplib/utils.js +53 -0
  65. package/lib/subscribers/application-logs.js +1 -1
  66. package/lib/subscribers/base.js +67 -1
  67. package/lib/subscribers/cassandra-driver/client-batch.js +49 -0
  68. package/lib/subscribers/cassandra-driver/client-connect.js +35 -0
  69. package/lib/subscribers/cassandra-driver/client-each-row.js +36 -0
  70. package/lib/subscribers/cassandra-driver/client-execute.js +36 -0
  71. package/lib/subscribers/cassandra-driver/client-shutdown.js +32 -0
  72. package/lib/subscribers/cassandra-driver/config.js +145 -0
  73. package/lib/subscribers/cassandra-driver/legacy-client-batch.js +22 -0
  74. package/lib/subscribers/cassandra-driver/legacy-client-connect.js +22 -0
  75. package/lib/subscribers/cassandra-driver/legacy-client-each-row.js +22 -0
  76. package/lib/subscribers/cassandra-driver/legacy-client-execute.js +21 -0
  77. package/lib/subscribers/cassandra-driver/legacy-client-shutdown.js +32 -0
  78. package/lib/subscribers/create-config.js +2 -4
  79. package/lib/subscribers/db-query.js +5 -1
  80. package/lib/subscribers/message-consumer.js +146 -0
  81. package/lib/subscribers/message-producer.js +60 -0
  82. package/lib/subscribers/meta-subscriber.js +69 -0
  83. package/lib/subscribers/openai/base.js +27 -1
  84. package/lib/subscribers/openai/chat.js +0 -27
  85. package/lib/subscribers/openai/config.js +3 -3
  86. package/lib/subscribers/openai/utils.js +9 -11
  87. package/lib/subscribers/propagation.js +43 -0
  88. package/lib/timer.js +1 -1
  89. package/lib/transaction/dt-payload.js +1 -1
  90. package/lib/transaction/handle.js +8 -9
  91. package/lib/transaction/name-state.js +11 -11
  92. package/lib/transaction/trace/segment.js +2 -3
  93. package/lib/util/attribute-types.js +1 -1
  94. package/lib/util/byte-limit.js +1 -1
  95. package/lib/util/cat.js +13 -13
  96. package/lib/util/flatten.js +2 -3
  97. package/lib/util/is-absolute-path.js +1 -1
  98. package/lib/util/is-string.js +15 -0
  99. package/lib/util/logger.js +6 -6
  100. package/lib/util/stream-sink.js +1 -1
  101. package/lib/utilization/docker-info.js +4 -3
  102. package/lib/w3c/traceparent.js +1 -1
  103. package/package.json +2 -2
  104. package/lib/instrumentation/amqplib/amqplib.js +0 -122
  105. package/lib/instrumentation/amqplib/channel-model.js +0 -124
  106. package/lib/instrumentation/amqplib/channel.js +0 -72
  107. package/lib/instrumentation/amqplib/nr-hooks.js +0 -21
  108. package/lib/instrumentation/amqplib/utils.js +0 -143
  109. package/lib/instrumentation/cassandra-driver.js +0 -131
@@ -1,124 +0,0 @@
1
- /*
2
- * Copyright 2024 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- 'use strict'
7
- const { MessageSpec, MessageSubscribeSpec, RecorderSpec } = require('../../shim/specs')
8
- const { amqpConnection } = require('../../symbols')
9
- const CHANNEL_METHODS = [
10
- 'close',
11
- 'open',
12
- 'assertQueue',
13
- 'checkQueue',
14
- 'deleteQueue',
15
- 'bindQueue',
16
- 'unbindQueue',
17
- 'assertExchange',
18
- 'checkExchange',
19
- 'deleteExchange',
20
- 'bindExchange',
21
- 'unbindExchange',
22
- 'cancel',
23
- 'prefetch',
24
- 'recover'
25
- ]
26
- const { describeMessage, setCallback, getParametersFromMessage, TEMP_RE } = require('./utils')
27
-
28
- /**
29
- *
30
- * Instruments the relevant channel callback_model or channel_model.
31
- *
32
- * @param {Shim} shim instance of shim
33
- * @param {object} Model either channel or callback model
34
- * @param {boolean} promiseMode is this promise based?
35
- */
36
- module.exports = function wrapModel(shim, Model, promiseMode) {
37
- if (!Model.Channel?.prototype) {
38
- shim.logger.debug(
39
- `Could not get ${promiseMode ? 'promise' : 'callback'} model Channel to instrument.`
40
- )
41
- return
42
- }
43
-
44
- const proto = Model.Channel.prototype
45
- if (shim.isWrapped(proto.consume)) {
46
- shim.logger.trace(`${promiseMode ? 'promise' : 'callback'} model already instrumented.`)
47
- return
48
- }
49
-
50
- recordChannelMethods({ shim, proto, promiseMode })
51
- recordPurge({ shim, proto, promiseMode })
52
- recordGet({ shim, proto, promiseMode })
53
- recordConsume({ shim, proto, promiseMode })
54
- }
55
-
56
- /**
57
- * Record spans for common methods on channel
58
- *
59
- * @param {Channel} proto prototype of Model.Channel
60
- */
61
- function recordChannelMethods({ shim, proto, promiseMode }) {
62
- shim.record(proto, CHANNEL_METHODS, function recordChannelMethod(shim, fn, name) {
63
- return new RecorderSpec({
64
- name: 'Channel#' + name,
65
- callback: setCallback(shim, promiseMode),
66
- promise: promiseMode
67
- })
68
- })
69
- }
70
-
71
- function recordPurge({ shim, proto, promiseMode }) {
72
- shim.recordPurgeQueue(proto, 'purgeQueue', function purge(shim, fn, name, args) {
73
- let queue = args[0]
74
- if (TEMP_RE.test(queue)) {
75
- queue = null
76
- }
77
- return new MessageSpec({
78
- queue,
79
- promise: promiseMode,
80
- callback: setCallback(shim, promiseMode)
81
- })
82
- })
83
- }
84
-
85
- function recordGet({ shim, proto, promiseMode }) {
86
- shim.recordConsume(proto, 'get', function wrapGet() {
87
- const { host, port } = this?.connection?.[amqpConnection] || {}
88
- return new MessageSpec({
89
- destinationName: shim.FIRST,
90
- callback: setCallback(shim, promiseMode),
91
- promise: promiseMode,
92
- after: function handleConsumedMessage({ shim, result, args, segment }) {
93
- if (!shim.agent.config.message_tracer.segment_parameters.enabled) {
94
- shim.logger.trace('Not capturing segment parameters')
95
- return
96
- }
97
-
98
- // the message is the param when using the promised based model
99
- const message = promiseMode ? result : args?.[1]
100
- if (!message) {
101
- shim.logger.trace('No results from consume.')
102
- return null
103
- }
104
- const parameters = getParametersFromMessage({ message, host, port })
105
- shim.copySegmentParameters(segment, parameters)
106
- }
107
- })
108
- })
109
- }
110
-
111
- function recordConsume({ shim, proto, promiseMode }) {
112
- shim.recordSubscribedConsume(proto, 'consume', function consume() {
113
- const { host, port } = this?.connection?.[amqpConnection] || {}
114
- return new MessageSubscribeSpec({
115
- name: 'amqplib.Channel#consume',
116
- queue: shim.FIRST,
117
- consumer: shim.SECOND,
118
- promise: promiseMode,
119
- parameters: { host, port },
120
- callback: promiseMode ? null : shim.FOURTH,
121
- messageHandler: describeMessage({ host, port })
122
- })
123
- })
124
- }
@@ -1,72 +0,0 @@
1
- /*
2
- * Copyright 2024 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- 'use strict'
7
- const { MessageSpec } = require('../../shim/specs')
8
- const { amqpConnection } = require('../../symbols')
9
- const { getParameters, TEMP_RE } = require('./utils')
10
-
11
- /**
12
- *
13
- * Instruments the sendOrEnqueue and sendMessage methods of the ampqlib channel.
14
- *
15
- * @param {Shim} shim instance of shim
16
- */
17
- module.exports = function wrapChannel(shim) {
18
- const libChannel = shim.require('./lib/channel')
19
- if (!libChannel?.Channel?.prototype) {
20
- shim.logger.debug('Could not get Channel class to instrument.')
21
- return
22
- }
23
-
24
- const proto = libChannel.Channel.prototype
25
- if (shim.isWrapped(proto.sendMessage)) {
26
- shim.logger.trace('Channel already instrumented.')
27
- return
28
- }
29
- shim.logger.trace('Instrumenting basic Channel class.')
30
-
31
- shim.wrap(proto, 'sendOrEnqueue', function wrapSendOrEnqueue(shim, fn) {
32
- if (!shim.isFunction(fn)) {
33
- return fn
34
- }
35
-
36
- return function wrappedSendOrEnqueue(...args) {
37
- const segment = shim.getSegment()
38
- const cb = args[args.length - 1]
39
- if (!shim.isFunction(cb) || !segment) {
40
- shim.logger.debug({ cb: !!cb, segment: !!segment }, 'Not binding sendOrEnqueue callback')
41
- return fn.apply(this, args)
42
- }
43
-
44
- shim.logger.trace('Binding sendOrEnqueue callback to %s', segment.name)
45
- args[args.length - 1] = shim.bindSegment(cb, segment)
46
- return fn.apply(this, args)
47
- }
48
- })
49
-
50
- shim.recordProduce(proto, 'sendMessage', recordSendMessage)
51
- }
52
-
53
- function recordSendMessage(shim, fn, n, args) {
54
- const fields = args[0]
55
- if (!fields) {
56
- return null
57
- }
58
- const isDefault = fields.exchange === ''
59
- let exchange = 'Default'
60
- if (!isDefault) {
61
- exchange = TEMP_RE.test(fields.exchange) ? null : fields.exchange
62
- }
63
- const { host, port } = this?.connection?.[amqpConnection] || {}
64
-
65
- return new MessageSpec({
66
- destinationName: exchange,
67
- destinationType: shim.EXCHANGE,
68
- routingKey: fields.routingKey,
69
- headers: fields.headers,
70
- parameters: getParameters({ parameters: Object.create(null), fields, host, port })
71
- })
72
- }
@@ -1,21 +0,0 @@
1
- /*
2
- * Copyright 2023 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- 'use strict'
7
- const amqplib = require('./amqplib')
8
- const InstrumentationDescriptor = require('../../instrumentation-descriptor')
9
-
10
- module.exports = [
11
- {
12
- moduleName: 'amqplib/callback_api',
13
- type: InstrumentationDescriptor.TYPE_MESSAGE,
14
- onRequire: amqplib.instrumentCallbackAPI
15
- },
16
- {
17
- moduleName: 'amqplib',
18
- type: InstrumentationDescriptor.TYPE_MESSAGE,
19
- onRequire: amqplib.instrumentPromiseAPI
20
- }
21
- ]
@@ -1,143 +0,0 @@
1
- /*
2
- * Copyright 2024 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- 'use strict'
7
- const {
8
- MessageSpec,
9
- params: { QueueMessageParameters }
10
- } = require('../../shim/specs')
11
- const TEMP_RE = /^amq\./
12
-
13
- /**
14
- * Wrapper around message handler to pass host/port
15
- *
16
- * @param {object} params to function
17
- * @param {string} params.host hostname
18
- * @param {number} params.port port
19
- * @returns {function} message handler
20
- */
21
- function describeMessage({ host, port }) {
22
- /**
23
- * Extracts the appropriate messageHandler parameters for the consume method.
24
- *
25
- * @param {Shim} shim instance of shim
26
- * @param {Array} args arguments passed to the consume method
27
- * @returns {object} message params
28
- */
29
- return function messageHandler(shim, args) {
30
- const [message] = args
31
-
32
- if (!message?.properties) {
33
- shim.logger.debug({ message }, 'Failed to find message in consume arguments.')
34
- return null
35
- }
36
-
37
- const parameters = getParametersFromMessage({ message, host, port })
38
- let exchangeName = message?.fields?.exchange || 'Default'
39
-
40
- if (TEMP_RE.test(exchangeName)) {
41
- exchangeName = null
42
- }
43
-
44
- return new MessageSpec({
45
- destinationName: exchangeName,
46
- destinationType: shim.EXCHANGE,
47
- routingKey: message?.fields?.routingKey,
48
- headers: message.properties.headers,
49
- parameters
50
- })
51
- }
52
- }
53
-
54
- /**
55
- * Sets the relevant message parameters
56
- *
57
- * @param {object} params to function
58
- * @param {object} params.parameters object used to store the message parameters
59
- * @param {object} params.fields fields from the sendMessage method
60
- * @param {string} params.host hostname
61
- * @param {number} params.port port
62
- * @returns {QueueMessageParameters} parameters updated parameters
63
- */
64
- function getParameters({ parameters, fields, host, port }) {
65
- if (fields.routingKey) {
66
- parameters.routing_key = fields.routingKey
67
- }
68
- if (fields.correlationId) {
69
- parameters.correlation_id = fields.correlationId
70
- }
71
- if (fields.replyTo) {
72
- parameters.reply_to = fields.replyTo
73
- }
74
-
75
- if (host) {
76
- parameters.host = host
77
- }
78
-
79
- if (port) {
80
- parameters.port = port
81
- }
82
-
83
- return new QueueMessageParameters(parameters)
84
- }
85
-
86
- /**
87
- * Sets the QueueMessageParameters from the amqp message
88
- *
89
- * @param {object} params to function
90
- * @param {object} params.message queue message
91
- * @param {string} params.host host
92
- * @param {number} params.port port
93
- * @returns {QueueMessageParameters} parameters from message
94
- */
95
- function getParametersFromMessage({ message, host, port }) {
96
- const parameters = Object.create(null)
97
- getParameters({ parameters, fields: message.fields, host, port })
98
- getParameters({ parameters, fields: message.properties })
99
- return parameters
100
- }
101
-
102
- /**
103
- * Helper to set the appropriate value of the callback property
104
- * in the spec. If it's a promise set to null otherwise set it to `shim.LAST`
105
- *
106
- * @param {Shim} shim instance of shim
107
- * @param {boolean} promiseMode is this promise based?
108
- * @returns {string|null} appropriate value
109
- */
110
- function setCallback(shim, promiseMode) {
111
- return promiseMode ? null : shim.LAST
112
- }
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
-
136
- module.exports = {
137
- describeMessage,
138
- getParameters,
139
- getParametersFromMessage,
140
- parseConnectionArgs,
141
- setCallback,
142
- TEMP_RE
143
- }
@@ -1,131 +0,0 @@
1
- /*
2
- * Copyright 2020 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- 'use strict'
7
-
8
- const semver = require('semver')
9
- const { OperationSpec, QuerySpec } = require('../shim/specs')
10
-
11
- /**
12
- * Instruments the `cassandra-driver` module, function that is
13
- * passed to `onRequire` when instantiating instrumentation.
14
- *
15
- * @param {object} _agent - NewRelic agent
16
- * @param {object} cassandra - The cassandra-driver library definition
17
- * @param {string} _moduleName - String representation of require/import path
18
- * @param {object} shim - shim for instrumentation
19
- */
20
- module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
21
- const cassandraVersion = shim.pkgVersion
22
-
23
- shim.setDatastore(shim.CASSANDRA)
24
-
25
- const ClientProto = cassandra.Client.prototype
26
- const RequestExecutionProto = shim.require('./lib/request-execution.js').prototype
27
-
28
- shim.recordOperation(
29
- ClientProto,
30
- ['connect', 'shutdown'],
31
- function operationSpec(shim, _fn, name) {
32
- return new OperationSpec({ callback: shim.LAST, name, promise: true })
33
- }
34
- )
35
-
36
- if (semver.satisfies(cassandraVersion, '>=4.4.0')) {
37
- shim.recordQuery(
38
- ClientProto,
39
- '_execute',
40
- new QuerySpec({
41
- query: shim.FIRST,
42
- callback: shim.LAST,
43
- promise: true
44
- })
45
- )
46
-
47
- shim.wrap(
48
- RequestExecutionProto,
49
- '_sendOnConnection',
50
- function wrapSendOnConnection(shim, _sendOnConnection) {
51
- return function wrappedSendOnConnection() {
52
- shim.captureInstanceAttributes(
53
- this._connection.address,
54
- this._connection.port,
55
- this._connection.keyspace
56
- )
57
-
58
- return _sendOnConnection.apply(this, arguments)
59
- }
60
- }
61
- )
62
- } else {
63
- shim.recordQuery(
64
- ClientProto,
65
- '_innerExecute',
66
- new QuerySpec({
67
- query: shim.FIRST,
68
- callback: shim.LAST,
69
- promise: true
70
- })
71
- )
72
-
73
- shim.wrap(RequestExecutionProto, 'start', function wrapStart(shim, start) {
74
- return function wrappedStart(...args) {
75
- const parent = shim.getSegment()
76
- const self = this
77
-
78
- /**
79
- * In older versions of cassandra-driver, we can't rely on RequestExecution._sendOnConnection,
80
- * so instead we use the callback passed to RequestExecution.start as a sort of hook point,
81
- * because we know for sure that the connection was set and in scope right before the callback
82
- * is executed.
83
- *
84
- * We also have to set the active segment to the RequestExecution.start's segment to ensure that
85
- * we're adding the connection attributes to the correct segment.
86
- *
87
- * See: https://github.com/datastax/nodejs-driver/blob/v3.4.0/lib/request-execution.js#L51
88
- */
89
- args[0] = shim.wrap(args[0], function wrapGetHostCallback(shim, getHostCallback) {
90
- return function wrappedGetHostCallback() {
91
- shim.setActiveSegment(parent)
92
-
93
- shim.captureInstanceAttributes(
94
- self._connection.address,
95
- self._connection.port,
96
- self._connection.keyspace
97
- )
98
- return getHostCallback.apply(this, arguments)
99
- }
100
- })
101
-
102
- return start.apply(this, args)
103
- }
104
- })
105
- }
106
-
107
- shim.recordBatchQuery(
108
- ClientProto,
109
- 'batch',
110
- new QuerySpec({
111
- query: findBatchQueryArg,
112
- callback: shim.LAST,
113
- promise: true
114
- })
115
- )
116
- }
117
-
118
- /**
119
- * Given the arguments for Cassandra's `batch` method, this finds the first
120
- * query in the batch.
121
- *
122
- * @param {object} _shim - shim for instrumentation
123
- * @param {Function} _batch - original batch function
124
- * @param {string} _fnName - the function name (batch)
125
- * @param {Array} args - original arguments passed to the batch function
126
- * @returns {string} The query for this batch request.
127
- */
128
- function findBatchQueryArg(_shim, _batch, _fnName, args) {
129
- const sql = (args[0] && args[0][0]) || ''
130
- return sql.query || sql
131
- }