newrelic 13.3.2 → 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.
- package/NEWS.md +43 -0
- package/THIRD_PARTY_NOTICES.md +11 -11
- package/esm-loader.mjs +2 -2
- package/lib/attributes.js +4 -4
- package/lib/collector/facts.js +1 -1
- package/lib/collector/http-agents.js +2 -2
- package/lib/collector/parse-response.js +9 -12
- package/lib/collector/remote-method.js +4 -5
- package/lib/config/formatters.js +2 -3
- package/lib/config/index.js +6 -6
- package/lib/harvester.js +1 -1
- package/lib/header-processing.js +3 -3
- package/lib/instrumentation/@node-redis/client.js +1 -1
- package/lib/instrumentation/aws-sdk/v2/instrumentation-helper.js +2 -2
- package/lib/instrumentation/aws-sdk/v3/common.js +5 -5
- package/lib/instrumentation/aws-sdk/v3/dynamodb.js +4 -4
- package/lib/instrumentation/aws-sdk/v3/sns.js +9 -9
- package/lib/instrumentation/aws-sdk/v3/sqs.js +6 -6
- package/lib/instrumentation/core/http-outbound.js +1 -2
- package/lib/instrumentation/fastify/spec-builders.js +11 -11
- package/lib/instrumentation/fastify.js +4 -4
- package/lib/instrumentation/memcached.js +4 -4
- package/lib/instrumentation/mongodb.js +2 -2
- package/lib/instrumentation/undici.js +3 -3
- package/lib/instrumentations.js +0 -2
- package/lib/llm-events/aws-bedrock/bedrock-response.js +6 -6
- package/lib/llm-events/aws-bedrock/converse-stream-handler.js +1 -1
- package/lib/llm-events/aws-bedrock/stream-handler.js +4 -4
- package/lib/metrics/index.js +2 -2
- package/lib/metrics/normalizer/rule.js +1 -1
- package/lib/metrics/normalizer.js +4 -5
- package/lib/metrics/recorders/message-transaction.js +3 -3
- package/lib/otel/context-manager.js +4 -4
- package/lib/otel/metrics/index.js +3 -3
- package/lib/otel/setup.js +6 -0
- package/lib/otel/trace-propagator.js +1 -1
- package/lib/otel/traces/index.js +1 -1
- package/lib/prioritized-attributes.js +2 -2
- package/lib/serverless/aws-lambda.js +4 -4
- package/lib/shim/datastore-shim.js +1 -1
- package/lib/shim/message-shim/consume.js +1 -1
- package/lib/shim/message-shim/subscribe-consume.js +1 -2
- package/lib/shim/promise-shim.js +1 -3
- package/lib/shim/shim.js +3 -4
- package/lib/shim/transaction-shim.js +0 -1
- package/lib/shim/webframework-shim/common.js +2 -4
- package/lib/shim/webframework-shim/middleware.js +8 -8
- package/lib/spans/span-context.js +1 -1
- package/lib/spans/span-event-aggregator.js +2 -2
- package/lib/spans/span-event.js +6 -5
- package/lib/spans/streaming-span-attributes.js +1 -1
- package/lib/spans/streaming-span-event-aggregator.js +1 -2
- package/lib/stats/index.js +1 -1
- package/lib/subscriber-configs.js +2 -0
- package/lib/subscribers/amqplib/accept-message.js +14 -0
- package/lib/subscribers/amqplib/callback-model.js +39 -0
- package/lib/subscribers/amqplib/channel-model.js +39 -0
- package/lib/subscribers/amqplib/config.js +695 -0
- package/lib/subscribers/amqplib/connect.js +74 -0
- package/lib/subscribers/amqplib/consume.js +54 -0
- package/lib/subscribers/amqplib/get-cb.js +16 -0
- package/lib/subscribers/amqplib/get.js +50 -0
- package/lib/subscribers/amqplib/purge-queue-cb.js +16 -0
- package/lib/subscribers/amqplib/purge-queue.js +37 -0
- package/lib/subscribers/amqplib/send-message.js +44 -0
- package/lib/subscribers/amqplib/send-or-enqueue.js +20 -0
- package/lib/subscribers/amqplib/utils.js +53 -0
- package/lib/subscribers/application-logs.js +1 -1
- package/lib/subscribers/base.js +167 -9
- package/lib/subscribers/cassandra-driver/client-batch.js +49 -0
- package/lib/subscribers/cassandra-driver/client-connect.js +35 -0
- package/lib/subscribers/cassandra-driver/client-each-row.js +36 -0
- package/lib/subscribers/cassandra-driver/client-execute.js +36 -0
- package/lib/subscribers/cassandra-driver/client-shutdown.js +32 -0
- package/lib/subscribers/cassandra-driver/config.js +145 -0
- package/lib/subscribers/cassandra-driver/legacy-client-batch.js +22 -0
- package/lib/subscribers/cassandra-driver/legacy-client-connect.js +22 -0
- package/lib/subscribers/cassandra-driver/legacy-client-each-row.js +22 -0
- package/lib/subscribers/cassandra-driver/legacy-client-execute.js +21 -0
- package/lib/subscribers/cassandra-driver/legacy-client-shutdown.js +32 -0
- package/lib/subscribers/create-config.js +2 -4
- package/lib/subscribers/db-query.js +5 -1
- package/lib/subscribers/message-consumer.js +146 -0
- package/lib/subscribers/message-producer.js +60 -0
- package/lib/subscribers/meta-subscriber.js +69 -0
- package/lib/subscribers/openai/base.js +27 -1
- package/lib/subscribers/openai/config.js +6 -6
- package/lib/subscribers/openai/utils.js +9 -11
- package/lib/subscribers/propagation.js +43 -0
- package/lib/timer.js +1 -1
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/handle.js +8 -9
- package/lib/transaction/name-state.js +11 -11
- package/lib/transaction/trace/segment.js +2 -3
- package/lib/util/attribute-types.js +1 -1
- package/lib/util/byte-limit.js +1 -1
- package/lib/util/cat.js +13 -13
- package/lib/util/flatten.js +2 -3
- package/lib/util/is-absolute-path.js +1 -1
- package/lib/util/is-string.js +15 -0
- package/lib/util/logger.js +6 -6
- package/lib/util/stream-sink.js +1 -1
- package/lib/utilization/docker-info.js +4 -3
- package/lib/w3c/traceparent.js +1 -1
- package/package.json +2 -2
- package/lib/instrumentation/amqplib/amqplib.js +0 -122
- package/lib/instrumentation/amqplib/channel-model.js +0 -124
- package/lib/instrumentation/amqplib/channel.js +0 -72
- package/lib/instrumentation/amqplib/nr-hooks.js +0 -21
- package/lib/instrumentation/amqplib/utils.js +0 -143
- package/lib/instrumentation/cassandra-driver.js +0 -131
|
@@ -1,122 +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 {
|
|
9
|
-
OperationSpec,
|
|
10
|
-
params: { DatastoreParameters }
|
|
11
|
-
} = require('../../shim/specs')
|
|
12
|
-
const wrapModel = require('./channel-model')
|
|
13
|
-
const { setCallback, parseConnectionArgs } = require('./utils')
|
|
14
|
-
const wrapChannel = require('./channel')
|
|
15
|
-
const { amqpConnection } = require('../../symbols')
|
|
16
|
-
|
|
17
|
-
module.exports.instrumentPromiseAPI = instrumentChannelAPI
|
|
18
|
-
module.exports.instrumentCallbackAPI = instrumentCallbackAPI
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Register all the necessary instrumentation when using
|
|
22
|
-
* promise based methods
|
|
23
|
-
*
|
|
24
|
-
* @param {Shim} shim instance of shim
|
|
25
|
-
* @param {object} amqp amqplib object
|
|
26
|
-
*/
|
|
27
|
-
function instrumentChannelAPI(shim, amqp) {
|
|
28
|
-
instrumentAMQP(shim, amqp, true)
|
|
29
|
-
// 👀 take note the model is channel not callback 👀
|
|
30
|
-
const model = shim.require('./lib/channel_model')
|
|
31
|
-
wrapModel(shim, model, true)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Register all the necessary instrumentation when using
|
|
36
|
-
* callback based methods
|
|
37
|
-
*
|
|
38
|
-
* @param {Shim} shim instance of shim
|
|
39
|
-
* @param {object} amqp amqplib object
|
|
40
|
-
*/
|
|
41
|
-
function instrumentCallbackAPI(shim, amqp) {
|
|
42
|
-
instrumentAMQP(shim, amqp, false)
|
|
43
|
-
// 👀 take note the model is callback not channel 👀
|
|
44
|
-
const model = shim.require('./lib/callback_model')
|
|
45
|
-
wrapModel(shim, model, false)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
-
* Instruments the connect method and channel prototype of amqplib
|
|
51
|
-
*
|
|
52
|
-
* @param {Shim} shim instance of shim
|
|
53
|
-
* @param {object} amqp amqplib object
|
|
54
|
-
* @param {boolean} promiseMode is this promise based?
|
|
55
|
-
* @returns {void}
|
|
56
|
-
*/
|
|
57
|
-
function instrumentAMQP(shim, amqp, promiseMode) {
|
|
58
|
-
if (!amqp || !amqp.connect) {
|
|
59
|
-
shim.logger.debug("This module is not the amqplib we're looking for.")
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (shim.isWrapped(amqp.connect)) {
|
|
64
|
-
shim.logger.trace('This module has already been instrumented, skipping.')
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
shim.setLibrary(shim.RABBITMQ)
|
|
68
|
-
|
|
69
|
-
wrapConnect(shim, amqp, promiseMode)
|
|
70
|
-
wrapChannel(shim)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
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
|
|
79
|
-
*
|
|
80
|
-
* @param {Shim} shim instance of shim
|
|
81
|
-
* @param {object} amqp amqplib object
|
|
82
|
-
* @param {boolean} promiseMode is this promise based?
|
|
83
|
-
*/
|
|
84
|
-
function wrapConnect(shim, amqp, promiseMode) {
|
|
85
|
-
shim.wrap(amqp, 'connect', function wrapConnect(shim, connect) {
|
|
86
|
-
return function wrappedConnect(...args) {
|
|
87
|
-
const [connArgs] = args
|
|
88
|
-
const params = parseConnectionArgs({ shim, connArgs })
|
|
89
|
-
const cb = args[args.length - 1]
|
|
90
|
-
if (!promiseMode) {
|
|
91
|
-
args[args.length - 1] = function wrappedCallback(...cbArgs) {
|
|
92
|
-
const [, c] = cbArgs
|
|
93
|
-
c.connection[amqpConnection] = params
|
|
94
|
-
return cb.apply(this, cbArgs)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const result = connect.apply(this, args)
|
|
99
|
-
if (promiseMode) {
|
|
100
|
-
return result.then((c) => {
|
|
101
|
-
c.connection[amqpConnection] = params
|
|
102
|
-
return c
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
return result
|
|
106
|
-
}
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
shim.record(amqp, 'connect', function recordConnect(shim, connect, name, args) {
|
|
110
|
-
const [connArgs] = args
|
|
111
|
-
const params = parseConnectionArgs({ shim, connArgs })
|
|
112
|
-
return new OperationSpec({
|
|
113
|
-
name: 'amqplib.connect',
|
|
114
|
-
callback: setCallback(shim, promiseMode),
|
|
115
|
-
promise: promiseMode,
|
|
116
|
-
parameters: new DatastoreParameters({
|
|
117
|
-
host: params.host,
|
|
118
|
-
port_path_or_id: params.port
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
})
|
|
122
|
-
}
|
|
@@ -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
|
-
}
|