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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const DbOperationSubscriber = require('../db-operation')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `connect` event in `cassandra-driver`'s `Client`.
|
|
12
|
+
*/
|
|
13
|
+
class CassandraConnectSubscriber extends DbOperationSubscriber {
|
|
14
|
+
constructor({ agent, logger, channelName = 'nr_connect' }) {
|
|
15
|
+
super({ agent, logger, channelName, packageName: 'cassandra-driver', system: 'Cassandra' })
|
|
16
|
+
this.events = ['asyncEnd']
|
|
17
|
+
this.operation = 'connect'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handler(data, ctx) {
|
|
21
|
+
const { self } = data
|
|
22
|
+
this.setParameters(self)
|
|
23
|
+
return super.handler(data, ctx)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setParameters(self) {
|
|
27
|
+
this.parameters = {}
|
|
28
|
+
this.parameters.product = this.system
|
|
29
|
+
this.parameters.database_name = self?.keyspace
|
|
30
|
+
this.parameters.host = self?.options?.contactPoints?.[0]
|
|
31
|
+
this.parameters.port_path_or_id = self?.options?.protocolOptions?.port
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = CassandraConnectSubscriber
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const DbQuerySubscriber = require('../db-query')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `execute` event in `cassandra-driver`
|
|
12
|
+
* and extracts relevant information from the query.
|
|
13
|
+
*/
|
|
14
|
+
class CassandraEachRowSubscriber extends DbQuerySubscriber {
|
|
15
|
+
constructor({ agent, logger, channelName = 'nr_eachRow' }) {
|
|
16
|
+
super({ agent, logger, channelName, packageName: 'cassandra-driver', system: 'Cassandra' })
|
|
17
|
+
this.events = ['asyncEnd']
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handler(data, ctx) {
|
|
21
|
+
const { self, arguments: args } = data
|
|
22
|
+
this.queryString = args?.[0]
|
|
23
|
+
this.setParameters(self)
|
|
24
|
+
return super.handler(data, ctx)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setParameters(self) {
|
|
28
|
+
this.parameters = {}
|
|
29
|
+
this.parameters.product = this.system
|
|
30
|
+
this.parameters.database_name = self?.keyspace
|
|
31
|
+
this.parameters.host = self?.controlConnection?.connection?.address
|
|
32
|
+
this.parameters.port_path_or_id = self?.controlConnection?.connection?.port
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = CassandraEachRowSubscriber
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const DbQuerySubscriber = require('../db-query')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `execute` event in `cassandra-driver`
|
|
12
|
+
* and extracts relevant information from the query.
|
|
13
|
+
*/
|
|
14
|
+
class CassandraExecuteSubscriber extends DbQuerySubscriber {
|
|
15
|
+
constructor({ agent, logger, channelName = 'nr_execute' }) {
|
|
16
|
+
super({ agent, logger, channelName, packageName: 'cassandra-driver', system: 'Cassandra' })
|
|
17
|
+
this.events = ['asyncEnd']
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handler(data, ctx) {
|
|
21
|
+
const { self, arguments: args } = data
|
|
22
|
+
this.queryString = args?.[0]
|
|
23
|
+
this.setParameters(self)
|
|
24
|
+
return super.handler(data, ctx)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setParameters(self) {
|
|
28
|
+
this.parameters = {}
|
|
29
|
+
this.parameters.product = this.system
|
|
30
|
+
this.parameters.database_name = self?.keyspace
|
|
31
|
+
this.parameters.host = self?.controlConnection?.connection?.address
|
|
32
|
+
this.parameters.port_path_or_id = self?.controlConnection?.connection?.port
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = CassandraExecuteSubscriber
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const DbOperationSubscriber = require('../db-operation')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `shutdown` event in `cassandra-driver`.
|
|
12
|
+
*/
|
|
13
|
+
class CassandraShutdownSubscriber extends DbOperationSubscriber {
|
|
14
|
+
constructor({ agent, logger, channelName = 'nr_shutdown' }) {
|
|
15
|
+
super({ agent, logger, channelName, packageName: 'cassandra-driver', system: 'Cassandra' })
|
|
16
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
17
|
+
this.operation = 'shutdown'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handler(data, ctx) {
|
|
21
|
+
const { self } = data
|
|
22
|
+
this.setParameters(self)
|
|
23
|
+
return super.handler(data, ctx)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setParameters() {
|
|
27
|
+
this.parameters = {}
|
|
28
|
+
this.parameters.product = this.system
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = CassandraShutdownSubscriber
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// there are diff subscribers for handling callback based code. In 4.4.0+ you can specify callbacks but they're all wrapped around promises so you don't have to wrap the callback in that case
|
|
7
|
+
const legacyBatchConfig = {
|
|
8
|
+
path: './cassandra-driver/legacy-client-batch.js',
|
|
9
|
+
instrumentations: [
|
|
10
|
+
{
|
|
11
|
+
channelName: 'nr_legacyBatch',
|
|
12
|
+
module: { name: 'cassandra-driver', versionRange: '>=3.4.0 <4.4.0', filePath: 'lib/client.js' },
|
|
13
|
+
functionQuery: {
|
|
14
|
+
expressionName: 'batch',
|
|
15
|
+
kind: 'Async'
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const legacyConnectConfig = {
|
|
22
|
+
path: './cassandra-driver/legacy-client-connect.js',
|
|
23
|
+
instrumentations: [
|
|
24
|
+
{
|
|
25
|
+
channelName: 'nr_legacyConnect',
|
|
26
|
+
module: { name: 'cassandra-driver', versionRange: '>=3.4.0 <4.4.0', filePath: 'lib/client.js' },
|
|
27
|
+
functionQuery: {
|
|
28
|
+
expressionName: 'connect',
|
|
29
|
+
kind: 'Async'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const legacyExecuteConfig = {
|
|
36
|
+
path: './cassandra-driver/legacy-client-execute.js',
|
|
37
|
+
instrumentations: [
|
|
38
|
+
{
|
|
39
|
+
channelName: 'nr_legacyExecute',
|
|
40
|
+
module: { name: 'cassandra-driver', versionRange: '>=3.4.0 <4.4.0', filePath: 'lib/client.js' },
|
|
41
|
+
functionQuery: {
|
|
42
|
+
expressionName: 'execute',
|
|
43
|
+
kind: 'Async'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const legacyEachRowConfig = {
|
|
50
|
+
path: './cassandra-driver/legacy-client-each-row.js',
|
|
51
|
+
instrumentations: [
|
|
52
|
+
{
|
|
53
|
+
channelName: 'nr_legacyEachRow',
|
|
54
|
+
module: { name: 'cassandra-driver', versionRange: '>=3.4.0 <4.4.0', filePath: 'lib/client.js' },
|
|
55
|
+
functionQuery: {
|
|
56
|
+
expressionName: 'eachRow',
|
|
57
|
+
kind: 'Async'
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const legacyShutdownConfig = {
|
|
64
|
+
path: './cassandra-driver/legacy-client-shutdown.js',
|
|
65
|
+
instrumentations: [
|
|
66
|
+
{
|
|
67
|
+
channelName: 'nr_legacyShutdown',
|
|
68
|
+
module: { name: 'cassandra-driver', versionRange: '>=3.4.0 <4.4.0', filePath: 'lib/client.js' },
|
|
69
|
+
functionQuery: {
|
|
70
|
+
expressionName: 'shutdown',
|
|
71
|
+
kind: 'Async'
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const batchConfig = {
|
|
78
|
+
path: './cassandra-driver/client-batch.js',
|
|
79
|
+
instrumentations: [
|
|
80
|
+
{
|
|
81
|
+
channelName: 'nr_batch',
|
|
82
|
+
module: { name: 'cassandra-driver', versionRange: '>=4.4.0', filePath: 'lib/client.js' },
|
|
83
|
+
functionQuery: {
|
|
84
|
+
expressionName: '_batch',
|
|
85
|
+
kind: 'Async'
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const connectConfig = {
|
|
92
|
+
path: './cassandra-driver/client-connect.js',
|
|
93
|
+
instrumentations: [
|
|
94
|
+
{
|
|
95
|
+
channelName: 'nr_connect',
|
|
96
|
+
module: { name: 'cassandra-driver', versionRange: '>=4.4.0', filePath: 'lib/client.js' },
|
|
97
|
+
functionQuery: {
|
|
98
|
+
expressionName: 'connect',
|
|
99
|
+
kind: 'Async'
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const executeConfig = {
|
|
106
|
+
path: './cassandra-driver/client-execute.js',
|
|
107
|
+
instrumentations: [
|
|
108
|
+
{
|
|
109
|
+
channelName: 'nr_execute',
|
|
110
|
+
module: { name: 'cassandra-driver', versionRange: '>=4.4.0', filePath: 'lib/client.js' },
|
|
111
|
+
functionQuery: {
|
|
112
|
+
expressionName: '_execute',
|
|
113
|
+
kind: 'Async'
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const shutdownConfig = {
|
|
120
|
+
path: './cassandra-driver/client-shutdown.js',
|
|
121
|
+
instrumentations: [
|
|
122
|
+
{
|
|
123
|
+
channelName: 'nr_shutdown',
|
|
124
|
+
module: { name: 'cassandra-driver', versionRange: '>=4.4.0', filePath: 'lib/client.js' },
|
|
125
|
+
functionQuery: {
|
|
126
|
+
expressionName: 'shutdown',
|
|
127
|
+
kind: 'Async'
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = {
|
|
134
|
+
'cassandra-driver': [
|
|
135
|
+
batchConfig,
|
|
136
|
+
connectConfig,
|
|
137
|
+
executeConfig,
|
|
138
|
+
shutdownConfig,
|
|
139
|
+
legacyBatchConfig,
|
|
140
|
+
legacyEachRowConfig,
|
|
141
|
+
legacyConnectConfig,
|
|
142
|
+
legacyExecuteConfig,
|
|
143
|
+
legacyShutdownConfig
|
|
144
|
+
]
|
|
145
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const CassandraBatchSubscriber = require('./client-batch')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `batch` event in `cassandra-driver`
|
|
12
|
+
* and extracts relevant information from the queries.
|
|
13
|
+
*/
|
|
14
|
+
class LegacyCassandraBatchSubscriber extends CassandraBatchSubscriber {
|
|
15
|
+
constructor({ agent, logger }) {
|
|
16
|
+
super({ agent, logger, channelName: 'nr_legacyBatch' })
|
|
17
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
18
|
+
this.callback = -1
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = LegacyCassandraBatchSubscriber
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const CassandraConnectSubscriber = require('./client-connect')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `connect` event in `cassandra-driver`'s `Client`.
|
|
12
|
+
*/
|
|
13
|
+
class LegacyCassandraConnectSubscriber extends CassandraConnectSubscriber {
|
|
14
|
+
constructor({ agent, logger }) {
|
|
15
|
+
super({ agent, logger, channelName: 'nr_legacyConnect' })
|
|
16
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
17
|
+
this.internal = true
|
|
18
|
+
this.callback = -1
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = LegacyCassandraConnectSubscriber
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const CassandraEachRowSubscriber = require('./client-each-row')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `execute` event in `cassandra-driver`
|
|
12
|
+
* and extracts relevant information from the query.
|
|
13
|
+
*/
|
|
14
|
+
class LegacyCassandraEachRowSubscriber extends CassandraEachRowSubscriber {
|
|
15
|
+
constructor({ agent, logger }) {
|
|
16
|
+
super({ agent, logger, channelName: 'nr_legacyEachRow' })
|
|
17
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
18
|
+
this.callback = -1
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = LegacyCassandraEachRowSubscriber
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const CassandraExecuteSubscriber = require('./client-execute')
|
|
9
|
+
/**
|
|
10
|
+
* Subscribes to the `execute` event in `cassandra-driver`
|
|
11
|
+
* and extracts relevant information from the query.
|
|
12
|
+
*/
|
|
13
|
+
class LegacyCassandraExecuteSubscriber extends CassandraExecuteSubscriber {
|
|
14
|
+
constructor({ agent, logger }) {
|
|
15
|
+
super({ agent, logger, channelName: 'nr_legacyExecute' })
|
|
16
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
17
|
+
this.callback = -1
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = LegacyCassandraExecuteSubscriber
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const CassandraShutdownSubscriber = require('./client-shutdown')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to the `shutdown` event in `cassandra-driver`.
|
|
12
|
+
*/
|
|
13
|
+
class LegacyCassandraShutdownSubscriber extends CassandraShutdownSubscriber {
|
|
14
|
+
constructor({ agent, logger }) {
|
|
15
|
+
super({ agent, logger, channelName: 'nr_legacyShutdown' })
|
|
16
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
17
|
+
this.callback = -1
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handler(data, ctx) {
|
|
21
|
+
const { self } = data
|
|
22
|
+
this.setParameters(self)
|
|
23
|
+
return super.handler(data, ctx)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setParameters() {
|
|
27
|
+
this.parameters = {}
|
|
28
|
+
this.parameters.product = this.system
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = LegacyCassandraShutdownSubscriber
|
|
@@ -12,16 +12,14 @@
|
|
|
12
12
|
* @returns {Object} An object containing a Set of unique package names and an array of instrumentations.
|
|
13
13
|
*/
|
|
14
14
|
function createSubscribersConfig (subscribers = []) {
|
|
15
|
-
const packages = new Set()
|
|
16
15
|
const instrumentations = []
|
|
17
|
-
for (const
|
|
18
|
-
packages.add(packageName)
|
|
16
|
+
for (const subscriberList of Object.values(subscribers)) {
|
|
19
17
|
for (const subscriber of subscriberList) {
|
|
20
18
|
instrumentations.push(...subscriber.instrumentations)
|
|
21
19
|
}
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
return {
|
|
22
|
+
return { instrumentations }
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
module.exports = createSubscribersConfig
|
|
@@ -13,7 +13,11 @@ class DbQuerySubscriber extends DbSubscriber {
|
|
|
13
13
|
handler(data, ctx) {
|
|
14
14
|
const queryString = this.queryString
|
|
15
15
|
const parsed = this.parseQueryString(queryString)
|
|
16
|
-
|
|
16
|
+
let name = `${DB.STATEMENT}/${this.system}/${parsed.collection}/${parsed.operation}`
|
|
17
|
+
if (this.isBatch) {
|
|
18
|
+
name += '/batch'
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
return this.createSegment({
|
|
18
22
|
name,
|
|
19
23
|
ctx,
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
const Subscriber = require('./base')
|
|
8
|
+
const Transaction = require('#agentlib/transaction/index.js')
|
|
9
|
+
const messageTransactionRecorder = require('#agentlib/metrics/recorders/message-transaction.js')
|
|
10
|
+
const isString = require('#agentlib/util/is-string.js')
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A message consumer does the following:
|
|
14
|
+
* 1. Calling consume creates a segment if in an active transaction
|
|
15
|
+
* 2. For every consumption, typically registered as a callback, it will create a transaction of type `message`, create a baseSegment, add both segment and trace attributes, and assign the `message-transaction` timeslice metrics
|
|
16
|
+
*
|
|
17
|
+
* @typedef {object} MessageConsumerParams
|
|
18
|
+
* @property {object} agent A New Relic Node.js agent instance.
|
|
19
|
+
* @property {object} logger An agent logger instance.
|
|
20
|
+
* @property {string} packageName The package name being instrumented.
|
|
21
|
+
* This is what a developer would provide to the `require` function.
|
|
22
|
+
* @property {string} channelName A unique name for the diagnostics channel
|
|
23
|
+
* that will be created and monitored.
|
|
24
|
+
* @property {string} system canonical mapping of system(i.e. - Kafka, RabbitMq, SNS, SQS)
|
|
25
|
+
* @property {string} type destinationType: Exchange, Queue, Topic
|
|
26
|
+
* @property {number} callback if consumer is callback based, indicates index of callback
|
|
27
|
+
* @property {string} transport identifier of the transport(see Transaction.TRANSPORT_TYPES)
|
|
28
|
+
*/
|
|
29
|
+
class MessageConsumer extends Subscriber {
|
|
30
|
+
constructor({ agent, logger, packageName, channelName, system, type, callback, transport }) {
|
|
31
|
+
super({ agent, logger, packageName, channelName })
|
|
32
|
+
this.system = system
|
|
33
|
+
this.type = type
|
|
34
|
+
this.callback = callback
|
|
35
|
+
this.transport = transport
|
|
36
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Used to create the consume segment if in an active transaction
|
|
41
|
+
* @param {object} data event passed to handler
|
|
42
|
+
* @param {Context} ctx agent context
|
|
43
|
+
* @returns {Context} new context or existing if not in active transaction
|
|
44
|
+
*/
|
|
45
|
+
handler(data, ctx) {
|
|
46
|
+
return this.createSegment({
|
|
47
|
+
name: this.segmentName,
|
|
48
|
+
ctx
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Used to add parameters to the consume segment
|
|
54
|
+
*
|
|
55
|
+
* @param {TraceSegment} segment to add attributes to
|
|
56
|
+
*/
|
|
57
|
+
addAttributes(segment) {
|
|
58
|
+
for (const [key, value] of Object.entries(this.parameters)) {
|
|
59
|
+
segment.addAttribute(key, value)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
enable() {
|
|
64
|
+
super.enable()
|
|
65
|
+
this.channel.asyncStart.bindStore(this.store, (data) => {
|
|
66
|
+
const ctx = this.agent.tracer.getContext()
|
|
67
|
+
const transaction = new Transaction(this.agent)
|
|
68
|
+
transaction.type = 'message'
|
|
69
|
+
return ctx.enterTransaction(transaction)
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
disable() {
|
|
74
|
+
super.disable()
|
|
75
|
+
this.channel.asyncStart.unbindStore(this.store)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Used to create a transaction for every consumption callback.
|
|
80
|
+
*
|
|
81
|
+
* @param {object} data event passed to asyncStart handler
|
|
82
|
+
*/
|
|
83
|
+
asyncStart(data) {
|
|
84
|
+
const ctx = this.agent.tracer.getContext()
|
|
85
|
+
const tx = ctx?.transaction
|
|
86
|
+
tx.setPartialName(this.name)
|
|
87
|
+
// Note: this is not using `Subscriber.createSegment`
|
|
88
|
+
// this is because it enters the segment and returns a new ctx
|
|
89
|
+
// since this isn't in bindStore entering a new context doesn't
|
|
90
|
+
// bind it to the store
|
|
91
|
+
tx.baseSegment = this.agent.tracer.createSegment({
|
|
92
|
+
name: tx.getFullName(),
|
|
93
|
+
recorder: messageTransactionRecorder,
|
|
94
|
+
parent: tx.trace.root,
|
|
95
|
+
transaction: tx
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
this.addConsumeParameters(tx)
|
|
99
|
+
|
|
100
|
+
if (this.headers) {
|
|
101
|
+
tx.addDtCatHeaders({ headers: this.headers, transport: this.transport })
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Used to add parameters to trace and baseSegment of a consumption callback.
|
|
107
|
+
*
|
|
108
|
+
* @param {Transaction} tx to add attributes to
|
|
109
|
+
*/
|
|
110
|
+
addConsumeParameters(tx) {
|
|
111
|
+
for (const [key, value] of Object.entries(this.consumerParameters)) {
|
|
112
|
+
if (['host', 'port'].includes(key)) {
|
|
113
|
+
tx.baseSegment.addAttribute(key, value)
|
|
114
|
+
} else {
|
|
115
|
+
tx.trace.attributes.addAttribute(Transaction.DESTINATIONS.NONE, `message.parameters.${key}`, value)
|
|
116
|
+
tx.baseSegment.attributes.addAttribute(Transaction.DESTINATIONS.NONE, `message.parameters.${key}`, value)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (key === 'routing_key' && this.config.high_security === false) {
|
|
120
|
+
tx.trace.attributes.addAttribute(Transaction.DESTINATIONS.TRANS_COMMON, 'message.routingKey', value)
|
|
121
|
+
tx.baseSegment.addSpanAttribute('message.routingKey', value)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (isString(this.queue) && this.config.high_security === false) {
|
|
125
|
+
tx.trace.attributes.addAttribute(Transaction.DESTINATIONS.TRANS_COMMON, 'message.queueName', this.queue)
|
|
126
|
+
tx.baseSegment.addSpanAttribute('message.queueName', this.queue)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Used to name the transaction for every consumption callback.
|
|
132
|
+
*
|
|
133
|
+
* @returns {string} partial transaction name
|
|
134
|
+
*/
|
|
135
|
+
get name() {
|
|
136
|
+
let name = `${this.system}/${this.type}`
|
|
137
|
+
if (this.destination) {
|
|
138
|
+
name += `/Named/${this.destination}`
|
|
139
|
+
} else {
|
|
140
|
+
name += '/Temp'
|
|
141
|
+
}
|
|
142
|
+
return name
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = MessageConsumer
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
const Subscriber = require('./base')
|
|
8
|
+
const genericRecorder = require('#agentlib/metrics/recorders/generic.js')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* Creates the segment for a message producer call. Injects appropriate DT/CAT
|
|
13
|
+
* headers if enabled.
|
|
14
|
+
*
|
|
15
|
+
* @typedef {object} MessageProducerParams
|
|
16
|
+
* @property {object} agent A New Relic Node.js agent instance.
|
|
17
|
+
* @property {object} logger An agent logger instance.
|
|
18
|
+
* @property {string} packageName The package name being instrumented.
|
|
19
|
+
* This is what a developer would provide to the `require` function.
|
|
20
|
+
* @property {string} channelName A unique name for the diagnostics channel
|
|
21
|
+
* that will be created and monitored.
|
|
22
|
+
* @property {string} system canonical mapping of system(i.e. - Kafka, RabbitMq, SNS, SQS)
|
|
23
|
+
* @property {string} type destinationType: Exchange, Queue, Topic
|
|
24
|
+
*/
|
|
25
|
+
class MessageProducerSubscriber extends Subscriber {
|
|
26
|
+
constructor({ agent, logger, packageName, channelName, system, type }) {
|
|
27
|
+
super({ agent, logger, packageName, channelName })
|
|
28
|
+
this.system = system
|
|
29
|
+
this.prefix = 'MessageBroker'
|
|
30
|
+
this.type = type
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
handler(data, ctx) {
|
|
34
|
+
const newCtx = this.createSegment({
|
|
35
|
+
name: this.name,
|
|
36
|
+
ctx,
|
|
37
|
+
recorder: genericRecorder
|
|
38
|
+
})
|
|
39
|
+
this.insertDTHeaders({ ctx: newCtx, headers: this.headers, useMqNames: true })
|
|
40
|
+
return newCtx
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get name() {
|
|
44
|
+
let name = `${this.prefix}/${this.system}/${this.type}/Produce`
|
|
45
|
+
if (this.destination) {
|
|
46
|
+
name += `/Named/${this.destination}`
|
|
47
|
+
} else {
|
|
48
|
+
name += '/Temp'
|
|
49
|
+
}
|
|
50
|
+
return name
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
addAttributes(segment) {
|
|
54
|
+
for (const [key, value] of Object.entries(this.parameters)) {
|
|
55
|
+
segment.addAttribute(key, value)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = MessageProducerSubscriber
|