Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

newrelic

Package Overview
Dependencies
Maintainers
1
Versions
383
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

newrelic - npm Package Compare versions

Comparing version 11.7.0 to 11.8.0

lib/shim/webframework-shim/common.js

2

lib/instrumentation/core/http-outbound.js

@@ -141,2 +141,4 @@ /*

opts.headers = opts.headers || {}
synthetics.assignHeadersToOutgoingRequest(agent.config, transaction, outboundHeaders)

@@ -143,0 +145,0 @@ maybeAddDtCatHeaders(agent, transaction, outboundHeaders, opts?.headers)

202

lib/instrumentation/core/http.js

@@ -8,4 +8,2 @@ /*

/* eslint sonarjs/cognitive-complexity: ["error", 42] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
const shimmer = require('../../shimmer')

@@ -39,4 +37,2 @@ const logger = require('../../logger').child({ component: 'http' })

const transport = isHTTPS ? 'HTTPS' : 'HTTP'
let serverPort = null
return tracer.transactionProxy(function wrappedHandler(evnt, request, response) {

@@ -96,11 +92,3 @@ const transaction = tracer.getTransaction()

// store the port on which this transaction runs
if (this.address instanceof Function) {
const address = this.address()
if (address) {
serverPort = address.port
}
}
transaction.port = serverPort
transaction.port = parsePort(this)
// need to set any config-driven names early for RUM

@@ -120,64 +108,98 @@ logger.trace(

if (agent.config.distributed_tracing.enabled) {
// Node http headers are automatically lowercase
transaction.acceptDistributedTraceHeaders(transport, request.headers)
} else if (agent.config.cross_application_tracer.enabled) {
const { id, transactionId } = cat.extractCatHeaders(request.headers)
const { externalId, externalTransaction } = cat.parseCatData(
id,
transactionId,
agent.config.encoding_key
)
cat.assignCatToTransaction(externalId, externalTransaction, transaction)
maybeAddDtCatHeaders({ transaction, request, transport, agent })
response.once('finish', instrumentedFinish.bind(response, segment, transaction))
response.once('close', instrumentedFinish.bind(response, segment, transaction))
return tracer.bindFunction(emit, segment).apply(this, arguments)
})
}
/**
* Gets the port from the Server object
*
* @param {object} server http(s) server
* @returns {number|null} parsed port
*/
function parsePort(server) {
let serverPort = null
// store the port on which this transaction runs
if (server.address instanceof Function) {
const address = server.address()
if (address) {
serverPort = address.port
}
}
return serverPort
}
function instrumentedFinish() {
// Remove listeners so this doesn't get called twice.
response.removeListener('finish', instrumentedFinish)
response.removeListener('close', instrumentedFinish)
function maybeAddDtCatHeaders({ agent, request, transaction, transport }) {
if (agent.config.distributed_tracing.enabled) {
// Node http headers are automatically lowercase
transaction.acceptDistributedTraceHeaders(transport, request.headers)
} else if (agent.config.cross_application_tracer.enabled) {
const { id, transactionId } = cat.extractCatHeaders(request.headers)
const { externalId, externalTransaction } = cat.parseCatData(
id,
transactionId,
agent.config.encoding_key
)
cat.assignCatToTransaction(externalId, externalTransaction, transaction)
}
}
// Naming must happen before the segment and transaction are ended,
// because metrics recording depends on naming's side effects.
transaction.finalizeNameFromUri(transaction.parsedUrl, response.statusCode)
/**
* Adds instrumentation to response on finish/close.
* It will add `http.statusCode`, `http.statusText`
* to the transaction trace and span.
* It will also assign the response headers to the transaction
*
* @param {TraceSegment} segment active segment
* @param {Transaction} transaction active transaction
*/
function instrumentedFinish(segment, transaction) {
// Remove listeners so this doesn't get called twice.
this.removeListener('finish', instrumentedFinish)
this.removeListener('close', instrumentedFinish)
if (response) {
if (response.statusCode != null) {
const responseCode = String(response.statusCode)
// Naming must happen before the segment and transaction are ended,
// because metrics recording depends on naming's side effects.
transaction.finalizeNameFromUri(transaction.parsedUrl, this.statusCode)
if (/^\d+$/.test(responseCode)) {
transaction.trace.attributes.addAttribute(
DESTS.TRANS_COMMON,
'http.statusCode',
responseCode
)
if (this) {
const { statusCode, statusMessage } = this
segment.addSpanAttribute('http.statusCode', responseCode)
}
}
if (statusCode != null) {
const responseCode = String(statusCode)
if (response.statusMessage !== undefined) {
transaction.trace.attributes.addAttribute(
DESTS.TRANS_COMMON,
'http.statusText',
response.statusMessage
)
if (/^\d+$/.test(responseCode)) {
transaction.trace.attributes.addAttribute(
DESTS.TRANS_COMMON,
'http.statusCode',
responseCode
)
segment.addSpanAttribute('http.statusText', response.statusMessage)
}
const headers = response.getHeaders()
if (headers) {
headerAttributes.collectResponseHeaders(headers, transaction)
}
segment.addSpanAttribute('http.statusCode', responseCode)
}
}
// And we are done! End the segment and transaction.
segment.end()
transaction.end()
if (statusMessage !== undefined) {
transaction.trace.attributes.addAttribute(
DESTS.TRANS_COMMON,
'http.statusText',
statusMessage
)
segment.addSpanAttribute('http.statusText', statusMessage)
}
response.once('finish', instrumentedFinish)
response.once('close', instrumentedFinish)
return tracer.bindFunction(emit, segment).apply(this, arguments)
})
const headers = this.getHeaders()
if (headers) {
headerAttributes.collectResponseHeaders(headers, transaction)
}
}
// And we are done! End the segment and transaction.
segment.end()
transaction.end()
}

@@ -348,24 +370,38 @@

/**
* http.request and http.get signatures vary. This function
* will parse the options and callback
*
* @param {*} input first arg of http.request and http.get
* @param {*} options request opts of callback
* @param {Function} cb if present it is the callback
* @returns {Array} [options, cb]
*/
function parseRequest(input, options, cb) {
// If the first argument is a URL, merge it into the options object.
// This code is copied from Node internals.
if (typeof input === 'string') {
const urlStr = input
input = urlToOptions(new URL(urlStr))
} else if (input.constructor && input.constructor.name === 'URL') {
input = urlToOptions(input)
} else {
cb = options
options = input
input = null
}
if (typeof options === 'function') {
cb = options
options = input || {}
} else {
options = Object.assign(input || {}, options)
}
return [options, cb]
}
function wrapRequest(agent, request) {
return function wrappedRequest(input, options, cb) {
// If the first argument is a URL, merge it into the options object.
// This code is copied from Node internals.
if (typeof input === 'string') {
const urlStr = input
input = urlToOptions(new URL(urlStr))
} else if (input.constructor && input.constructor.name === 'URL') {
input = urlToOptions(input)
} else {
cb = options
options = input
input = null
}
if (typeof options === 'function') {
cb = options
options = input || {}
} else {
options = Object.assign(input || {}, options)
}
;[options, cb] = parseRequest(input, options, cb)
const reqArgs = [options, cb]

@@ -372,0 +408,0 @@

@@ -54,4 +54,4 @@ /*

const attrs = transaction?.trace?.custom.get(DESTINATIONS.TRANS_SCOPE)
return attrs?.conversation_id
return attrs?.['llm.conversation_id']
}
}

@@ -8,4 +8,2 @@ /*

/* eslint sonarjs/cognitive-complexity: ["error", 30] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
const logger = require('../logger').child({ component: 'PromiseShim' })

@@ -16,2 +14,14 @@ const Shim = require('./shim')

/**
* Checks if function is actually not a function
* or it is wrapped
*
* @param {Shim} shim instance of shim
* @param {Function} fn function to wrap
* @returns {boolean} is already wrapped or not
*/
function isWrapped(shim, fn) {
return shim.isFunction(fn) === false || shim.isWrapped(fn)
}
/**
* A helper class for wrapping promise modules.

@@ -32,3 +42,2 @@ *

* @param {string} pkgVersion version of module
* @param shimName
* @see Shim

@@ -47,2 +56,3 @@ */

* @private
* @returns {Contextualizer} contextualizer class
*/

@@ -148,3 +158,3 @@ static get Contextualizer() {

return this.wrap(nodule, properties, function executorWrapper(shim, caller) {
if (!shim.isFunction(caller) || shim.isWrapped(caller)) {
if (isWrapped(shim, caller)) {
return

@@ -206,3 +216,3 @@ }

return this.wrap(nodule, properties, function castWrapper(shim, cast) {
if (!shim.isFunction(cast) || shim.isWrapped(cast)) {
if (isWrapped(shim, cast)) {
return

@@ -291,3 +301,3 @@ }

return this.wrap(nodule, properties, function promisifyWrapper(shim, promisify) {
if (!shim.isFunction(promisify) || shim.isWrapped(promisify)) {
if (isWrapped(shim, promisify)) {
return

@@ -308,3 +318,5 @@ }

/**
* Returns wrapped promise that binds the active segment accordingly
*
* @returns {Promise} promise bound to active segment
*/

@@ -330,4 +342,4 @@ function __NR_wrappedPromisified() {

/**
* @param shim
* @param args
* @param {object} shim instance of shim
* @param {Array} args arguments passed to executor function
* @private

@@ -347,4 +359,4 @@ */

*
* @param resolve
* @param reject
* @param {Function} resolve function of promise
* @param {Function} reject function of promise
*/

@@ -360,4 +372,5 @@ function contextExporter(resolve, reject) {

/**
* @param context
* @param fn
* @param {object} context context object
* @param {Function} fn function that is wrapped
* @returns {Function} wrapped function
* @private

@@ -376,11 +389,56 @@ */

/**
* @param shim
* @param fn
* @param name
* @param useAllParams
*
* @param {object} params object passed to wrapHandler
* @param {Function} params.handler to wrap
* @param {number} params.index index of argument
* @param {number} params.argsLength length of args
* @param {boolean} params.useAllParams flag to use all params
* @param {object} params.ctx context passed in to store the next handler and isWrapped
* @param {object} params.shim shim instance
* @returns {Function} wrapped function
*/
function wrapHandler({ handler, index, argsLength, useAllParams, ctx, shim }) {
if (
isWrapped(shim, handler) ||
(!useAllParams && index !== argsLength - 1) // Don't want all and not last
) {
ctx.isWrapped = shim.isWrapped(handler)
return handler
}
return function __NR_wrappedThenHandler() {
if (!ctx.handler || !ctx.handler[symbols.context]) {
return handler.apply(this, arguments)
}
let promSegment = ctx.handler[symbols.context].getSegment()
const segment = promSegment || shim.getSegment()
if (segment && segment !== promSegment) {
ctx.handler[symbols.context].setSegment(segment)
promSegment = segment
}
let ret = null
try {
ret = shim.applySegment(handler, promSegment, true, this, arguments)
} finally {
if (ret && typeof ret.then === 'function') {
ret = ctx.handler[symbols.context].continueContext(ret)
}
}
return ret
}
}
/**
* @param {object} shim instance of shim
* @param {Function} fn function that is wrapped
* @param {string} _name function name(unused)
* @param {boolean} useAllParams flag to indicate if all params of function are used
* @returns {Function|undefined} wrapped function
* @private
*/
function _wrapThen(shim, fn, name, useAllParams) {
function _wrapThen(shim, fn, _name, useAllParams) {
// Don't wrap non-functions.
if (shim.isWrapped(fn) || !shim.isFunction(fn)) {
if (isWrapped(shim, fn)) {
return

@@ -397,55 +455,23 @@ }

// Wrap up the arguments and execute the real then.
let isWrapped = false
// store isWrapped and current handler on context object to be passed into wrapHandler
const ctx = { isWrapped: false, handler: null }
const args = new Array(arguments.length)
for (let i = 0; i < arguments.length; ++i) {
args[i] = wrapHandler(arguments[i], i, arguments.length)
args[i] = wrapHandler({
shim,
handler: arguments[i],
index: i,
argsLength: arguments.length,
useAllParams,
ctx
})
}
const next = fn.apply(this, args)
ctx.handler = fn.apply(this, args)
// If we got a promise (which we should have), link the parent's context.
if (!isWrapped && next instanceof shim._class && next !== promise) {
Contextualizer.link(promise, next, thenSegment)
if (!ctx.isWrapped && ctx.handler instanceof shim._class && ctx.handler !== promise) {
Contextualizer.link(promise, ctx.handler, thenSegment)
}
return next
/**
*
* @param handler
* @param i
* @param length
*/
function wrapHandler(handler, i, length) {
if (
!shim.isFunction(handler) || // Not a function
shim.isWrapped(handler) || // Already wrapped
(!useAllParams && i !== length - 1) // Don't want all and not last
) {
isWrapped = shim.isWrapped(handler)
return handler
}
return function __NR_wrappedThenHandler() {
if (!next || !next[symbols.context]) {
return handler.apply(this, arguments)
}
let promSegment = next[symbols.context].getSegment()
const segment = promSegment || shim.getSegment()
if (segment && segment !== promSegment) {
next[symbols.context].setSegment(segment)
promSegment = segment
}
let ret = null
try {
ret = shim.applySegment(handler, promSegment, true, this, arguments)
} finally {
if (ret && typeof ret.then === 'function') {
ret = next[symbols.context].continueContext(ret)
}
}
return ret
}
}
return ctx.handler
}

@@ -478,2 +504,41 @@ }

/**
* Iterate over the children and assign parent/child relationship
* via parentIdx and idx of contextualizer.
*
* The first child needs to be updated to have its own branch as well. And
* each of that child's children must be updated with the new parent index.
* This is the only non-constant-time action for linking, but it only
* happens with branching promise chains specifically when the 2nd branch
* is added.
*
* Note: This does not account for branches of branches. That may result
* in improperly parented segments.
*
* @param {Contextualizer} ctxlzr instance of contextualizer
*/
static buildContextTree(ctxlzr) {
// When the branch-point is the 2nd through nth link in the chain, it is
// necessary to track its segment separately so the branches can parent
// their segments on the branch-point.
if (ctxlzr.parentIdx !== -1) {
ctxlzr.idx = ctxlzr.context.branch()
}
let parent = ctxlzr
let child = ctxlzr.child
const branchIdx = ctxlzr.context.branch()
do {
child.parentIdx = parent.idx
child.idx = branchIdx
parent = child
child = child.child
} while (child)
// We set the child to something falsey that isn't `null` so we can
// distinguish between having no child, having one child, and having
// multiple children.
ctxlzr.child = false
}
static link(prev, next, segment) {

@@ -488,31 +553,3 @@ let ctxlzr = prev && prev[symbols.context]

if (ctxlzr.child) {
// When the branch-point is the 2nd through nth link in the chain, it is
// necessary to track its segment separately so the branches can parent
// their segments on the branch-point.
if (ctxlzr.parentIdx !== -1) {
ctxlzr.idx = ctxlzr.context.branch()
}
// The first child needs to be updated to have its own branch as well. And
// each of that child's children must be updated with the new parent index.
// This is the only non-constant-time action for linking, but it only
// happens with branching promise chains specifically when the 2nd branch
// is added.
//
// Note: This does not account for branches of branches. That may result
// in improperly parented segments.
let parent = ctxlzr
let child = ctxlzr.child
const branchIdx = ctxlzr.context.branch()
do {
child.parentIdx = parent.idx
child.idx = branchIdx
parent = child
child = child.child
} while (child)
// We set the child to something falsey that isn't `null` so we can
// distinguish between having no child, having one child, and having
// multiple children.
ctxlzr.child = false
Contextualizer.buildContextTree(ctxlzr)
}

@@ -519,0 +556,0 @@

@@ -15,7 +15,7 @@ /*

const comment = /(?:#|--).*?(?=\r|\n|$)/
const multilineComment = /\/\*(?:[^/]|\/[^*])*?(?:\*\/|\/\*.*)/
const multilineComment = /\/\*(?:[^\/]|\/[^*])*?(?:\*\/|\/\*.*)/
const uuid = /\{?(?:[0-9a-f]\-*){32}\}?/
const hex = /0x[0-9a-f]+/
const boolean = /true|false|null/
const number = /\b-?(?:[0-9]+\.)?[0-9]+([eE][+-]?[0-9]+)?/
const boolean = /\b(?:true|false|null)\b/
const number = /-?\b(?:[0-9]+\.)?[0-9]+(e[+-]?[0-9]+)?/

@@ -33,3 +33,3 @@ const dialects = (obfuscate.dialects = Object.create(null))

),
unmatchedPairs(/'|\/\*|\*\/|(?:\$(?!\?))/)
unmatchedPairs(/'|\/\*|\*\/|\$(?!\?)/)
]

@@ -47,2 +47,7 @@

dialects.sqlite = [
replacer(join([singleQuote, comment, multilineComment, hex, boolean, number], 'gi')),
unmatchedPairs(/'|\/\*|\*\//)
]
dialects.default = dialects.mysql

@@ -49,0 +54,0 @@

{
"name": "newrelic",
"version": "11.7.0",
"version": "11.8.0",
"author": "New Relic Node.js agent team <nodejs@newrelic.com>",

@@ -188,3 +188,3 @@ "license": "Apache-2.0",

"@newrelic/koa": "^8.0.1",
"@newrelic/security-agent": "0.5.0",
"@newrelic/security-agent": "^0.6.0",
"@newrelic/superagent": "^7.0.1",

@@ -217,3 +217,2 @@ "@tyriar/fibonacci-heap": "^2.0.7",

"c8": "^8.0.1",
"chai": "^4.1.2",
"clean-jsdoc-theme": "^4.2.4",

@@ -220,0 +219,0 @@ "commander": "^7.0.0",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc