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,69 @@
|
|
|
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
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Used to subscribe to many different events that have the same behavior around
|
|
11
|
+
* segment creation.
|
|
12
|
+
*
|
|
13
|
+
* @typedef {object} MetaSubscriberParams
|
|
14
|
+
* @property {object} agent A New Relic Node.js agent instance.
|
|
15
|
+
* @property {object} logger An agent logger instance.
|
|
16
|
+
* @property {string} packageName The package name being instrumented.
|
|
17
|
+
* This is what a developer would provide to the `require` function.
|
|
18
|
+
* @property {string} channelName A unique name for the diagnostics channel
|
|
19
|
+
* that will be created and monitored.
|
|
20
|
+
* @property {Array} channels list of channels to construct new subscribers
|
|
21
|
+
* @property {Array} events list of events to subscribe to new subscribers
|
|
22
|
+
* @property {number} callback if consumer is callback based, indicates index of callback
|
|
23
|
+
*/
|
|
24
|
+
class MetaSubscriber {
|
|
25
|
+
constructor({ agent, logger, packageName, channelName, channels, events, callback }) {
|
|
26
|
+
this.config = agent.config
|
|
27
|
+
this.packageName = packageName
|
|
28
|
+
this.id = `orchestrion:${packageName}:${channelName}`
|
|
29
|
+
this.subscribers = channels.map((name) => {
|
|
30
|
+
const subscriber = new Subscriber({ agent, logger, packageName, channelName: name })
|
|
31
|
+
subscriber.events = events
|
|
32
|
+
subscriber.handler = this.handler.bind(subscriber)
|
|
33
|
+
if (callback !== null) {
|
|
34
|
+
subscriber.callback = callback
|
|
35
|
+
}
|
|
36
|
+
return subscriber
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get enabled() {
|
|
41
|
+
return this.config.instrumentation[this.packageName].enabled === true
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
enable() {
|
|
45
|
+
for (const subscriber of this.subscribers) {
|
|
46
|
+
subscriber.enable()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
disable() {
|
|
51
|
+
for (const subscriber of this.subscribers) {
|
|
52
|
+
subscriber.disable()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
subscribe() {
|
|
57
|
+
for (const subscriber of this.subscribers) {
|
|
58
|
+
subscriber.subscribe()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
unsubscribe() {
|
|
63
|
+
for (const subscriber of this.subscribers) {
|
|
64
|
+
subscriber.unsubscribe()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = MetaSubscriber
|
|
@@ -10,12 +10,38 @@ const Subscriber = require('../base')
|
|
|
10
10
|
class OpenAISubscriber extends Subscriber {
|
|
11
11
|
constructor({ agent, logger, channelName }) {
|
|
12
12
|
super({ agent, logger, packageName: 'openai', channelName })
|
|
13
|
-
this.events = ['asyncEnd']
|
|
13
|
+
this.events = ['asyncEnd', 'end']
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
get enabled() {
|
|
17
17
|
return super.enabled && this.config.ai_monitoring?.enabled
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Temporary fix as `tracePromise` wraps the promise in a native one.
|
|
22
|
+
* We are now wrapping all openai functions in a `traceSync` call.
|
|
23
|
+
* Then we wrap the promise here so it returns the custom promise.
|
|
24
|
+
* OpenAI has a [custom promise](https://github.com/openai/openai-node/blob/master/src/core/api-promise.ts).
|
|
25
|
+
* see: https://github.com/newrelic/node-newrelic/issues/3379
|
|
26
|
+
* see: https://github.com/nodejs/node/issues/59936
|
|
27
|
+
* @param {object} data the data associated with the `end` event
|
|
28
|
+
*/
|
|
29
|
+
end(data) {
|
|
30
|
+
const promise = data?.result
|
|
31
|
+
if (!promise.then) {
|
|
32
|
+
return promise
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return promise.then((result) => {
|
|
36
|
+
data.result = result
|
|
37
|
+
this.channel.asyncEnd.publish(data)
|
|
38
|
+
return result
|
|
39
|
+
}).catch((err) => {
|
|
40
|
+
data.error = err
|
|
41
|
+
this.channel.asyncEnd.publish(data)
|
|
42
|
+
return err
|
|
43
|
+
})
|
|
44
|
+
}
|
|
19
45
|
}
|
|
20
46
|
|
|
21
47
|
module.exports = OpenAISubscriber
|
|
@@ -16,7 +16,7 @@ module.exports = {
|
|
|
16
16
|
functionQuery: {
|
|
17
17
|
className: 'Completions',
|
|
18
18
|
methodName: 'create',
|
|
19
|
-
kind: '
|
|
19
|
+
kind: 'Sync'
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
{
|
|
@@ -25,7 +25,7 @@ module.exports = {
|
|
|
25
25
|
functionQuery: {
|
|
26
26
|
className: 'Completions',
|
|
27
27
|
methodName: 'create',
|
|
28
|
-
kind: '
|
|
28
|
+
kind: 'Sync'
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
]
|
|
@@ -39,7 +39,7 @@ module.exports = {
|
|
|
39
39
|
functionQuery: {
|
|
40
40
|
className: 'Responses',
|
|
41
41
|
methodName: 'create',
|
|
42
|
-
kind: '
|
|
42
|
+
kind: 'Sync'
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
]
|
|
@@ -53,7 +53,7 @@ module.exports = {
|
|
|
53
53
|
functionQuery: {
|
|
54
54
|
className: 'APIClient',
|
|
55
55
|
methodName: 'makeRequest',
|
|
56
|
-
kind: '
|
|
56
|
+
kind: 'Sync'
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
{
|
|
@@ -62,7 +62,7 @@ module.exports = {
|
|
|
62
62
|
functionQuery: {
|
|
63
63
|
className: 'OpenAI',
|
|
64
64
|
methodName: 'makeRequest',
|
|
65
|
-
kind: '
|
|
65
|
+
kind: 'Sync'
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
]
|
|
@@ -76,7 +76,7 @@ module.exports = {
|
|
|
76
76
|
functionQuery: {
|
|
77
77
|
className: 'Embeddings',
|
|
78
78
|
methodName: 'create',
|
|
79
|
-
kind: '
|
|
79
|
+
kind: 'Sync'
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
]
|
|
@@ -41,7 +41,7 @@ function getMessageFromResponse(response) {
|
|
|
41
41
|
* Parses all messages from the OpenAI request object.
|
|
42
42
|
*
|
|
43
43
|
* @param {object} request The OpenAI SDK request object
|
|
44
|
-
* @param logger
|
|
44
|
+
* @param {Logger} logger instance
|
|
45
45
|
* @returns {Array<object>} an array of message objects with fields `content` and `role`
|
|
46
46
|
*/
|
|
47
47
|
function getMessagesFromRequest(request, logger) {
|
|
@@ -95,7 +95,7 @@ function recordEvent({ agent, type, msg }) {
|
|
|
95
95
|
* @param {object} params input params
|
|
96
96
|
* @param {Agent} params.agent NR agent instance
|
|
97
97
|
* @param {Transaction} params.transaction active transaction
|
|
98
|
-
* @param params.version
|
|
98
|
+
* @param {string} params.version package version
|
|
99
99
|
*/
|
|
100
100
|
function addLlmMeta({ agent, transaction, version }) {
|
|
101
101
|
TRACKING_METRIC = `${TRACKING_METRIC}/${version}`
|
|
@@ -112,13 +112,13 @@ function addLlmMeta({ agent, transaction, version }) {
|
|
|
112
112
|
*
|
|
113
113
|
* @param {object} params input params
|
|
114
114
|
* @param {Agent} params.agent NR agent instance
|
|
115
|
+
* @param {object} params.headers request headers
|
|
116
|
+
* @param {Logger} params.logger logger instance
|
|
115
117
|
* @param {TraceSegment} params.segment active segment from chat completion
|
|
116
118
|
* @param {object} params.request chat completion params
|
|
117
119
|
* @param {object} params.response chat completion response
|
|
118
120
|
* @param {boolean} [params.err] err if it exists
|
|
119
121
|
* @param {Transaction} params.transaction active transaction
|
|
120
|
-
* @param params.headers
|
|
121
|
-
* @param params.logger
|
|
122
122
|
*/
|
|
123
123
|
function recordChatCompletionMessages({
|
|
124
124
|
agent,
|
|
@@ -189,11 +189,10 @@ function recordChatCompletionMessages({
|
|
|
189
189
|
|
|
190
190
|
/**
|
|
191
191
|
* Checks if we should skip instrumentation.
|
|
192
|
-
* Currently,
|
|
193
|
-
* and the package version >= 4.0.0
|
|
192
|
+
* Currently, just checks if `ai_monitoring.enabled` is true.
|
|
194
193
|
*
|
|
195
194
|
* @param {object} config agent config
|
|
196
|
-
* @param logger
|
|
195
|
+
* @param {Logger} logger instance
|
|
197
196
|
* @returns {boolean} flag if instrumentation should be skipped
|
|
198
197
|
*/
|
|
199
198
|
function shouldSkipInstrumentation(config, logger) {
|
|
@@ -212,14 +211,13 @@ function shouldSkipInstrumentation(config, logger) {
|
|
|
212
211
|
* messages.
|
|
213
212
|
* @param {object} params input params
|
|
214
213
|
* @param {Agent} params.agent NR agent instance
|
|
215
|
-
* @param {
|
|
214
|
+
* @param {object} params.headers request headers
|
|
215
|
+
* @param {object} params.logger logger instance
|
|
216
216
|
* @param {object} params.request chat completion params
|
|
217
217
|
* @param {object} params.response chat completion response
|
|
218
218
|
* @param {TraceSegment} params.segment active segment from chat completion
|
|
219
219
|
* @param {Transaction} params.transaction active transaction
|
|
220
|
-
* @param {Error} params.err error if it exists
|
|
221
|
-
* @param params.headers
|
|
222
|
-
* @param params.logger
|
|
220
|
+
* @param {Error} [params.err] error if it exists
|
|
223
221
|
*/
|
|
224
222
|
function instrumentStream({ agent, headers, logger, request, response, segment, transaction, err = null }) {
|
|
225
223
|
if (!agent.config.ai_monitoring.streaming.enabled) {
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
|
|
9
|
+
/**
|
|
10
|
+
* This subscriber is purely for propagation of async context within the `asyncStart` event.
|
|
11
|
+
* This will be typically used in a callback based scenario where there is async code getting scheduled
|
|
12
|
+
* but not bound to the context.
|
|
13
|
+
*/
|
|
14
|
+
class PropagationSubscriber extends Subscriber {
|
|
15
|
+
constructor({ agent, logger, packageName, channelName, callback }) {
|
|
16
|
+
super({ agent, logger, packageName, channelName })
|
|
17
|
+
this.callback = callback
|
|
18
|
+
this.propagateTx = true
|
|
19
|
+
this.events = ['asyncStart', 'asyncEnd']
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
enable() {
|
|
23
|
+
super.enable()
|
|
24
|
+
this.channel.asyncStart.bindStore(this.store, (data) => {
|
|
25
|
+
const { transaction, segment } = data
|
|
26
|
+
const ctx = this.agent.tracer.getContext()
|
|
27
|
+
|
|
28
|
+
if (!(transaction && segment)) {
|
|
29
|
+
this.logger.trace('No active transaction/segment, returning existing context')
|
|
30
|
+
return ctx
|
|
31
|
+
}
|
|
32
|
+
const newCtx = ctx.enterSegment({ transaction, segment })
|
|
33
|
+
return newCtx
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
disable() {
|
|
38
|
+
super.disable()
|
|
39
|
+
this.channel.asyncStart.unbindStore(this.store)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = PropagationSubscriber
|
package/lib/timer.js
CHANGED
|
@@ -220,7 +220,7 @@ Timer.prototype.startedRelativeTo = function startedRelativeTo(other) {
|
|
|
220
220
|
/**
|
|
221
221
|
* Returns true if this timer ends after the other.
|
|
222
222
|
*
|
|
223
|
-
* @param other
|
|
223
|
+
* @param {Timer} other other timer
|
|
224
224
|
*/
|
|
225
225
|
Timer.prototype.endsAfter = function compare(other) {
|
|
226
226
|
return this.getDurationInMillis() + this.start > other.getDurationInMillis() + other.start
|
|
@@ -15,7 +15,7 @@ module.exports = class DistributedTracePayload {
|
|
|
15
15
|
* The class responsible for producing distributed trace payloads.
|
|
16
16
|
* Created by calling {@link TransactionHandle#_createDistributedTracePayload}.
|
|
17
17
|
*
|
|
18
|
-
* @param payload
|
|
18
|
+
* @param {Object} payload DT payload
|
|
19
19
|
* @class
|
|
20
20
|
*/
|
|
21
21
|
constructor(payload) {
|
|
@@ -14,8 +14,8 @@ class TransactionHandle {
|
|
|
14
14
|
* A light representation of a transaction instance, returned by calling
|
|
15
15
|
* {@link API#getTransaction}.
|
|
16
16
|
*
|
|
17
|
-
* @param transaction
|
|
18
|
-
* @param metrics
|
|
17
|
+
* @param {Transaction} transaction the associated transaction
|
|
18
|
+
* @param {Metrics} metrics class instance
|
|
19
19
|
* @class
|
|
20
20
|
*/
|
|
21
21
|
constructor(transaction, metrics) {
|
|
@@ -26,7 +26,7 @@ class TransactionHandle {
|
|
|
26
26
|
/**
|
|
27
27
|
* End the transaction.
|
|
28
28
|
*
|
|
29
|
-
* @param
|
|
29
|
+
* @param {Function} callback The function to call after ending the transaction.
|
|
30
30
|
*/
|
|
31
31
|
end(callback) {
|
|
32
32
|
const tx = this._transaction.end()
|
|
@@ -57,11 +57,10 @@ class TransactionHandle {
|
|
|
57
57
|
* W3C TraceContext format is preferred over the NewRelic DT format.
|
|
58
58
|
* NewRelic DT format will be used if no `traceparent` header is found.
|
|
59
59
|
*
|
|
60
|
-
* @param
|
|
61
|
-
* @param transportType
|
|
60
|
+
* @param {string} [transportType] - The transport type that delivered the trace; defaults to 'Unknown'.
|
|
62
61
|
* @param {object} headers - Headers to search for supported formats. Keys must be lowercase.
|
|
63
62
|
*/
|
|
64
|
-
acceptDistributedTraceHeaders(transportType, headers) {
|
|
63
|
+
acceptDistributedTraceHeaders(transportType = 'Unknown', headers) {
|
|
65
64
|
incrementApiSupportMetric(this._metrics, 'acceptDistributedTraceHeaders')
|
|
66
65
|
return this._transaction.acceptDistributedTraceHeaders(transportType, headers)
|
|
67
66
|
}
|
|
@@ -69,7 +68,7 @@ class TransactionHandle {
|
|
|
69
68
|
/**
|
|
70
69
|
* Inserts distributed trace headers into the provided headers map.
|
|
71
70
|
*
|
|
72
|
-
* @param {object} headers
|
|
71
|
+
* @param {object} headers DT headers
|
|
73
72
|
*/
|
|
74
73
|
insertDistributedTraceHeaders(headers) {
|
|
75
74
|
incrementApiSupportMetric(this._metrics, 'insertDistributedTraceHeaders')
|
|
@@ -82,8 +81,8 @@ module.exports = TransactionHandle
|
|
|
82
81
|
/**
|
|
83
82
|
*
|
|
84
83
|
* @private
|
|
85
|
-
* @param metrics
|
|
86
|
-
* @param functionName
|
|
84
|
+
* @param {Metrics} metrics class instance
|
|
85
|
+
* @param {string} functionName name of function to increment the metric of
|
|
87
86
|
*/
|
|
88
87
|
function incrementApiSupportMetric(metrics, functionName) {
|
|
89
88
|
if (!metrics) {
|
|
@@ -29,10 +29,10 @@ const STATUS_CODE_NAMES = {
|
|
|
29
29
|
/**
|
|
30
30
|
* Manages transaction names using a stack of paths.
|
|
31
31
|
*
|
|
32
|
-
* @param prefix
|
|
33
|
-
* @param verb
|
|
34
|
-
* @param delimiter
|
|
35
|
-
* @param path
|
|
32
|
+
* @param {string} prefix metric prefix
|
|
33
|
+
* @param {string} verb HTTP verb
|
|
34
|
+
* @param {string} delimiter delimiter character
|
|
35
|
+
* @param {string} path path element
|
|
36
36
|
* @class
|
|
37
37
|
*/
|
|
38
38
|
function NameState(prefix, verb, delimiter, path) {
|
|
@@ -72,7 +72,7 @@ NameState.prototype.markPath = function markPath() {
|
|
|
72
72
|
/**
|
|
73
73
|
* Sets the metric prefix (i.e. Expressjs).
|
|
74
74
|
*
|
|
75
|
-
* @param prefix
|
|
75
|
+
* @param {string} prefix metric prefix
|
|
76
76
|
*/
|
|
77
77
|
NameState.prototype.setPrefix = function setPrefix(prefix) {
|
|
78
78
|
if (this._frozen) {
|
|
@@ -89,7 +89,7 @@ NameState.prototype.setPrefix = function setPrefix(prefix) {
|
|
|
89
89
|
/**
|
|
90
90
|
* Sets the HTTP verb (i.e. GET/POST/PUT)
|
|
91
91
|
*
|
|
92
|
-
* @param verb
|
|
92
|
+
* @param {string} verb HTTP verb
|
|
93
93
|
*/
|
|
94
94
|
NameState.prototype.setVerb = function setVerb(verb) {
|
|
95
95
|
if (!this._frozen) {
|
|
@@ -100,7 +100,7 @@ NameState.prototype.setVerb = function setVerb(verb) {
|
|
|
100
100
|
/**
|
|
101
101
|
* Sets the delimiter character used to separate the http verb from the path.
|
|
102
102
|
*
|
|
103
|
-
* @param delimiter
|
|
103
|
+
* @param {string} delimiter delimiter character
|
|
104
104
|
*/
|
|
105
105
|
NameState.prototype.setDelimiter = function setDelimiter(delimiter) {
|
|
106
106
|
if (!this._frozen) {
|
|
@@ -115,8 +115,8 @@ NameState.prototype.isEmpty = function isEmpty() {
|
|
|
115
115
|
/**
|
|
116
116
|
* Pushes a new path element onto the naming stack.
|
|
117
117
|
*
|
|
118
|
-
* @param path
|
|
119
|
-
* @param params
|
|
118
|
+
* @param {string} path path element
|
|
119
|
+
* @param {Object} params to add to pathStack
|
|
120
120
|
*/
|
|
121
121
|
NameState.prototype.appendPath = function appendPath(path, params) {
|
|
122
122
|
if (!this._frozen && path != null) {
|
|
@@ -134,8 +134,8 @@ NameState.prototype.appendPath = function appendPath(path, params) {
|
|
|
134
134
|
* Pushes a new path element onto the naming stack if the stack is
|
|
135
135
|
* empty.
|
|
136
136
|
*
|
|
137
|
-
* @param path
|
|
138
|
-
* @param params
|
|
137
|
+
* @param {string} path path element
|
|
138
|
+
* @param {Object} params to add with appendPath
|
|
139
139
|
*/
|
|
140
140
|
NameState.prototype.appendPathIfEmpty = function appendPathIfEmpty(path, params) {
|
|
141
141
|
if (!this._frozen && this.isEmpty()) {
|
|
@@ -138,7 +138,7 @@ TraceSegment.prototype.setNameFromTransaction = function setNameFromTransaction(
|
|
|
138
138
|
* finally, marking the trace segment as being a web segment copies the
|
|
139
139
|
* segment's parameters onto the transaction.
|
|
140
140
|
* @param {Transaction} transaction The transaction to which this segment will be bound.
|
|
141
|
-
* @param obfuscatedUrl
|
|
141
|
+
* @param {object} obfuscatedUrl The obfuscated URL for the request.
|
|
142
142
|
*/
|
|
143
143
|
TraceSegment.prototype.markAsWeb = function markAsWeb(transaction, obfuscatedUrl) {
|
|
144
144
|
this.setNameFromTransaction(transaction)
|
|
@@ -270,11 +270,10 @@ function getExclusiveDurationInMillis(trace) {
|
|
|
270
270
|
* @param {string} params.protocol protocol of request(i.e. `http:`, `grpc:`)
|
|
271
271
|
* @param {string} params.hostname hostname of request(no port)
|
|
272
272
|
* @param {string} params.host host of request(hostname + port)
|
|
273
|
-
* @param
|
|
273
|
+
* @param {string} params.port port of request if applicable
|
|
274
274
|
* @param {string} params.path uri of request
|
|
275
275
|
* @param {string} [params.method] method of request
|
|
276
276
|
* @param {object} [params.queryParams] query parameters of request
|
|
277
|
-
* @param params.port
|
|
278
277
|
*/
|
|
279
278
|
TraceSegment.prototype.captureExternalAttributes = function captureExternalAttributes({
|
|
280
279
|
protocol,
|
|
@@ -11,7 +11,7 @@ const VALID_ATTR_TYPES = new Set(['string', 'number', 'boolean'])
|
|
|
11
11
|
* Checks incoming attribute value against valid types:
|
|
12
12
|
* string, number, & boolean.
|
|
13
13
|
*
|
|
14
|
-
* @param {*} val
|
|
14
|
+
* @param {*} val value to check type of
|
|
15
15
|
* @returns {boolean}
|
|
16
16
|
*/
|
|
17
17
|
function isValidType(val) {
|
package/lib/util/byte-limit.js
CHANGED
|
@@ -21,7 +21,7 @@ function isValidLength(str, limit) {
|
|
|
21
21
|
* 0 if the string is at the limit
|
|
22
22
|
* <1 if the string is shorter than the limit
|
|
23
23
|
*
|
|
24
|
-
* @param {string} str
|
|
24
|
+
* @param {string} str - Object key name or value
|
|
25
25
|
* @param {number} limit - String byte limit
|
|
26
26
|
*/
|
|
27
27
|
function compareLength(str, limit) {
|
package/lib/util/cat.js
CHANGED
|
@@ -32,11 +32,11 @@ const MATCH_CAT_APP_DATA_HEADER = new RegExp(
|
|
|
32
32
|
/**
|
|
33
33
|
* Decodes the CAT id and transaction headers from incoming request
|
|
34
34
|
*
|
|
35
|
-
* @param {object}
|
|
36
|
-
* @param id
|
|
37
|
-
* @param transactionId
|
|
35
|
+
* @param {object} id CAT id
|
|
36
|
+
* @param {object} transactionId transaction header id
|
|
38
37
|
* @param {string} encKey config.encoding_key used to decode CAT headers
|
|
39
|
-
*
|
|
38
|
+
*
|
|
39
|
+
* @returns {object} { externalId, externalTransaction }
|
|
40
40
|
*/
|
|
41
41
|
cat.parseCatData = function parseCatData(id, transactionId, encKey) {
|
|
42
42
|
if (!encKey) {
|
|
@@ -109,10 +109,10 @@ cat.assignCatToTransaction = function assignCatToTransaction(
|
|
|
109
109
|
* for incoming requests
|
|
110
110
|
*
|
|
111
111
|
* @param {object} config agent config
|
|
112
|
-
* @param {Transaction} transaction
|
|
113
|
-
* @param {string} contentLength
|
|
112
|
+
* @param {Transaction} transaction current transaction
|
|
113
|
+
* @param {string} contentLength length of content
|
|
114
114
|
* @param {boolean} useMqHeaders flag to return proper headers for MQ compliance
|
|
115
|
-
* @returns {object} { key, data} to add as header
|
|
115
|
+
* @returns {object} { key, data } to add as header
|
|
116
116
|
*/
|
|
117
117
|
cat.encodeAppData = function encodeAppData(config, transaction, contentLength, useMqHeaders) {
|
|
118
118
|
let appData = null
|
|
@@ -147,7 +147,7 @@ cat.encodeAppData = function encodeAppData(config, transaction, contentLength, u
|
|
|
147
147
|
* Adds CAT headers to outbound request.
|
|
148
148
|
*
|
|
149
149
|
* @param {object} config agent config
|
|
150
|
-
* @param {Transaction} transaction
|
|
150
|
+
* @param {Transaction} transaction current transaction
|
|
151
151
|
* @param {object} headers object that contains headers the agent is adding to client request
|
|
152
152
|
* @param {boolean} useMqHeaders flag to return proper headers for MQ compliance
|
|
153
153
|
*/
|
|
@@ -189,9 +189,9 @@ cat.addCatHeaders = function addCatHeaders(config, transaction, headers, useMqHe
|
|
|
189
189
|
|
|
190
190
|
/**
|
|
191
191
|
* Find the CAT id, transaction, app data headers
|
|
192
|
-
* from the headers of either HTTP or MQ request
|
|
192
|
+
* from the headers of either HTTP or MQ request.
|
|
193
193
|
*
|
|
194
|
-
* @param {object} headers
|
|
194
|
+
* @param {object} headers HTTP/MQ headers
|
|
195
195
|
* @returns {object} { id, transactionId, appData }
|
|
196
196
|
*/
|
|
197
197
|
cat.extractCatHeaders = function extractCatHeaders(headers) {
|
|
@@ -220,8 +220,7 @@ cat.extractCatHeaders = function extractCatHeaders(headers) {
|
|
|
220
220
|
* Extracts the account Id from CAT data and verifies if it is
|
|
221
221
|
* a trusted account id
|
|
222
222
|
*
|
|
223
|
-
* @param {object} CAT data
|
|
224
|
-
* @param data
|
|
223
|
+
* @param {object} data CAT data
|
|
225
224
|
* @param {Array} trustedAccounts from config
|
|
226
225
|
* @returns {boolean}
|
|
227
226
|
*/
|
|
@@ -240,7 +239,8 @@ cat.isTrustedAccountId = function isTrustedAccountId(data, trustedAccounts) {
|
|
|
240
239
|
*
|
|
241
240
|
* @param {object} config agent config
|
|
242
241
|
* @param {string} obfAppData encoded app data to parse and use
|
|
243
|
-
*
|
|
242
|
+
*
|
|
243
|
+
* @returns {Array} decoded app data header
|
|
244
244
|
*/
|
|
245
245
|
cat.parseAppData = function parseAppData(config, obfAppData) {
|
|
246
246
|
if (!config.encoding_key) {
|
package/lib/util/flatten.js
CHANGED
|
@@ -16,8 +16,8 @@ exports.keys = flatKeys
|
|
|
16
16
|
* @private
|
|
17
17
|
* @param {object} result Object to place key-value pairs into, normally called with `{}`.
|
|
18
18
|
* @param {string} prefix Prefix for keys, normally called with `''`.
|
|
19
|
-
* @param seen
|
|
20
19
|
* @param {object} obj Object to be flattened.
|
|
20
|
+
* @param {Array} seen Array of seen objects to prevent circular references.
|
|
21
21
|
* @returns {object} Object with flattened key-value pairs
|
|
22
22
|
*/
|
|
23
23
|
function flatten(result, prefix, obj, seen) {
|
|
@@ -45,8 +45,7 @@ function flatten(result, prefix, obj, seen) {
|
|
|
45
45
|
* @private
|
|
46
46
|
* @param {object} obj - The object to get the flat keys of.
|
|
47
47
|
* @param {string} prefix - A prefix for the keys, usually `''`.
|
|
48
|
-
* @param arrayIdxs
|
|
49
|
-
* @param {boolean} arrayIdx - Flag indicating if array indexes should be iterated.
|
|
48
|
+
* @param {boolean} arrayIdxs - Flag indicating if array indexes should be iterated.
|
|
50
49
|
* @returns {Array.<string>} An array of keys names.
|
|
51
50
|
*/
|
|
52
51
|
function flatKeys(obj, prefix, arrayIdxs) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Tests if argument passed in is a string or String object
|
|
10
|
+
* @param {*} data to check if it is a string
|
|
11
|
+
* @returns {boolean} if string or string object
|
|
12
|
+
*/
|
|
13
|
+
module.exports = function isString(data) {
|
|
14
|
+
return typeof data === 'string' || data instanceof String
|
|
15
|
+
}
|
package/lib/util/logger.js
CHANGED
|
@@ -253,14 +253,14 @@ Logger.prototype._read = function _read() {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
/**
|
|
256
|
-
* For performance reasons we do not support %j because we will have
|
|
256
|
+
* For performance reasons, we do not support %j because we will have
|
|
257
257
|
* already converted the objects to strings.
|
|
258
|
-
* Returns a boolean representing the status of the write
|
|
259
|
-
* (success/failure)
|
|
260
258
|
*
|
|
261
|
-
* @param level
|
|
262
|
-
* @param args
|
|
263
|
-
* @param extra
|
|
259
|
+
* @param {string} level log entry level
|
|
260
|
+
* @param {Array} args arguments to stringify
|
|
261
|
+
* @param {Object} extra data to log
|
|
262
|
+
*
|
|
263
|
+
* @returns {boolean} True if the log was written successfully, false otherwise.
|
|
264
264
|
*/
|
|
265
265
|
Logger.prototype.write = function write(level, args, extra) {
|
|
266
266
|
if (this._nestedLog) {
|
package/lib/util/stream-sink.js
CHANGED
|
@@ -26,7 +26,7 @@ const util = require('util')
|
|
|
26
26
|
* contract and the callback will be fired when the stream has been completely
|
|
27
27
|
* read.
|
|
28
28
|
*
|
|
29
|
-
* @param callback
|
|
29
|
+
* @param {function} callback Function to call when stream has been read.
|
|
30
30
|
*/
|
|
31
31
|
function StreamSink(callback) {
|
|
32
32
|
EventEmitter.call(this)
|
|
@@ -58,9 +58,10 @@ function recordBootIdError(agent) {
|
|
|
58
58
|
/**
|
|
59
59
|
* Utility function to parse a Docker boot id from a cgroup proc file.
|
|
60
60
|
*
|
|
61
|
-
* @param {
|
|
62
|
-
* @param {
|
|
63
|
-
* @param {
|
|
61
|
+
* @param {Object} params params object
|
|
62
|
+
* @param {Buffer} params.data The information from the proc file.
|
|
63
|
+
* @param {Agent} params.agent Newrelic agent instance.
|
|
64
|
+
* @param {Function} params.callback Typical error first callback. Second parameter
|
|
64
65
|
* is the boot id as a string.
|
|
65
66
|
*
|
|
66
67
|
* @returns {*}
|
package/lib/w3c/traceparent.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newrelic",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.4.0",
|
|
4
4
|
"author": "New Relic Node.js agent team <nodejs@newrelic.com>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"contributors": [
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
"#test/assert": "./test/lib/custom-assertions/index.js"
|
|
202
202
|
},
|
|
203
203
|
"dependencies": {
|
|
204
|
-
"@apm-js-collab/tracing-hooks": "^0.1
|
|
204
|
+
"@apm-js-collab/tracing-hooks": "^0.3.1",
|
|
205
205
|
"@grpc/grpc-js": "^1.13.2",
|
|
206
206
|
"@grpc/proto-loader": "^0.7.5",
|
|
207
207
|
"@newrelic/security-agent": "^2.4.2",
|