Skip to content

Commit

Permalink
chore: fixed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bizob2828 committed Oct 11, 2024
1 parent 6168419 commit 7158cf8
Show file tree
Hide file tree
Showing 30 changed files with 235 additions and 147 deletions.
10 changes: 8 additions & 2 deletions lib/db/parsed-statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function ParsedStatement(type, operation, collection, raw) {
}
}

ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, transaction, scope) {
ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, scope, transaction) {
const duration = segment.getDurationInMillis()
const exclusive = segment.getExclusiveDurationInMillis()
const type = transaction.isWeb() ? DB.WEB : DB.OTHER
Expand Down Expand Up @@ -67,7 +67,13 @@ ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, transa
}

if (this.raw) {
transaction.agent.queries.add({ segment, transaction, type: this.type.toLowerCase(), query: this.raw, trace: this.trace })
transaction.agent.queries.add({
segment,
transaction,
type: this.type.toLowerCase(),
query: this.raw,
trace: this.trace
})
}
}

Expand Down
32 changes: 26 additions & 6 deletions lib/instrumentation/core/http-outbound.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,14 @@ module.exports = function instrumentOutbound(agent, opts, makeRequest) {
* @param {string} params.hostname domain of outbound request
* @param {string} params.port port of outbound request
* @param {TraceSegment} segment outbound http segment
* @param {Transaction} transaction active tx
* @param {Transaction} transaction active tx
* @returns {http.IncomingMessage} request actual http outbound request
*/
function instrumentRequest({ agent, opts, makeRequest, host, port, hostname }, segment, transaction) {
function instrumentRequest(
{ agent, opts, makeRequest, host, port, hostname },
segment,
transaction
) {
const outboundHeaders = Object.create(null)

opts.headers = opts.headers || {}
Expand All @@ -157,7 +161,15 @@ function instrumentRequest({ agent, opts, makeRequest, host, port, hostname }, s
maybeAddDtCatHeaders(agent, transaction, outboundHeaders, opts?.headers)
opts.headers = assignOutgoingHeaders(opts.headers, outboundHeaders)

const request = applySegment({ opts, makeRequest, hostname, host, port, segment, config: agent.config })
const request = applySegment({
opts,
makeRequest,
hostname,
host,
port,
segment,
config: agent.config
})

instrumentRequestEmit(agent, host, segment, request)

Expand Down Expand Up @@ -268,7 +280,7 @@ function instrumentRequestEmit(agent, host, segment, request) {
segment.end()
handleError({ transaction, req: request, error: arg })
} else if (evnt === 'response') {
handleResponse({ agent, segment, host, res: arg })
handleResponse({ agent, segment, transaction, host, res: arg })
}

return boundEmit.apply(this, arguments)
Expand All @@ -283,8 +295,11 @@ function instrumentRequestEmit(agent, host, segment, request) {
* request object.
*
* @param {object} segment TraceSegment instance
* @param segment.transaction
* @param {object} req http.ClientRequest
* @param {Error} error If provided, unhandled error that occurred during request
* @param segment.req
* @param segment.error
* @returns {boolean} True if the error will be collected by New Relic.
*/
function handleError({ transaction, req, error }) {
Expand All @@ -301,12 +316,17 @@ function handleError({ transaction, req, error }) {
/**
* Ties the response object to the request segment.
*
* @param segment.agent
* @param {object} segment TraceSegment instance
* @param {string} hostname host of the HTTP request
* @param host
* @param {object} res http.ServerResponse
* @param segment.segment
* @param segment.transaction
* @param segment.host
* @param segment.res
*/
function handleResponse({ agent, segment, host, res }) {
function handleResponse({ agent, segment, transaction, host, res }) {
// Add response attributes for spans
segment.addSpanAttribute('http.statusCode', res.statusCode)
segment.addSpanAttribute('http.statusText', res.statusMessage)
Expand All @@ -315,7 +335,7 @@ function handleResponse({ agent, segment, host, res }) {
if (agent.config.cross_application_tracer.enabled && !agent.config.distributed_tracing.enabled) {
const { appData } = cat.extractCatHeaders(res.headers)
const decodedAppData = cat.parseAppData(agent.config, appData)
cat.assignCatToSegment(decodedAppData, segment, host)
cat.assignCatToSegment({ appData: decodedAppData, segment, host, transaction })
}

// Again a custom emit wrapper because we want to watch for the `end` event.
Expand Down
17 changes: 12 additions & 5 deletions lib/instrumentation/undici.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ function addDTHeaders({ transaction, config, request }) {
* @param {Shim} params.shim instance of shim
* @param {object} params.request undici request object
* @param {object} params.parentSegment current active, about to be parent of external segment
* @param params.segment
*/
function createExternalSegment({ shim, request, segment }) {
const url = new URL(request.origin + request.path)
Expand Down Expand Up @@ -160,9 +161,9 @@ function createExternalSegment({ shim, request, segment }) {
function requestCreateHook(shim, { request }) {
const { config } = shim.agent
const { transaction, segment } = getParentContext(shim)
request[symbols.parentSegment] = segment
request[symbols.transaction] = transaction
if (!(segment || transaction) || (segment?.opaque)) {
request[symbols.parentSegment] = segment
request[symbols.transaction] = transaction
if (!(segment || transaction) || segment?.opaque) {
logger.trace(
'Not capturing data for outbound request (%s) because parent segment opaque (%s)',
request.path,
Expand Down Expand Up @@ -193,6 +194,7 @@ function requestCreateHook(shim, { request }) {
function requestHeadersHook(shim, { request, response }) {
const { config } = shim.agent
const activeSegment = request[symbols.segment]
const transaction = request[symbols.transaction]
if (!activeSegment) {
return
}
Expand All @@ -206,7 +208,12 @@ function requestHeadersHook(shim, { request, response }) {
const decodedAppData = cat.parseAppData(config, appData)
const attrs = activeSegment.getAttributes()
const url = new URL(attrs.url)
cat.assignCatToSegment(decodedAppData, activeSegment, url.host)
cat.assignCatToSegment({
appData: decodedAppData,
segment: activeSegment,
host: url.host,
transaction
})
} catch (err) {
logger.warn(err, 'Cannot add CAT data to segment')
}
Expand Down Expand Up @@ -244,7 +251,7 @@ function endAndRestoreSegment(shim, { request, error }) {
* Adds the error to the active transaction
*
* @param {Shim} shim instance of shim
* @param {Transaction} tx active transaction
* @param {Transaction} tx active transaction
* @param {Error} error error from undici request
*/
function handleError(shim, tx, error) {
Expand Down
2 changes: 1 addition & 1 deletion lib/shim/datastore-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ function _getSpec({ spec, shim, fn, fnName, args }) {
*/
function _recordQueryMetrics(parsed, segment, scope, transaction) {
if (segment && transaction) {
parsed.recordMetrics(segment, transaction, scope)
parsed.recordMetrics(segment, scope, transaction)
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/shim/message-shim/subscribe-consume.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ function createConsumerWrapper({ shim, spec, consumer }) {
}
}
if (msgDesc.headers) {
shim.handleMqTracingHeaders(msgDesc.headers, tx.baseSegment, shim._transportType)
shim.handleMqTracingHeaders(msgDesc.headers, tx.baseSegment, tx, shim._transportType)
}

shim.logger.trace('Started message transaction %s named %s', tx.id, txName)
Expand Down
22 changes: 13 additions & 9 deletions lib/shim/transaction-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,11 @@ function setTransactionName(name) {
* @param {TraceSegment} [segment]
* The trace segment to associate the header data with. If no segment is
* provided then the currently active segment is used.
* @param transaction
* @param {string} [transportType]
* The transport type that brought the headers. Usually `HTTP` or `HTTPS`.
*/
function handleMqTracingHeaders(headers, segment, transportType) {
function handleMqTracingHeaders(headers, segment, transaction, transportType) {
// TODO: replace functionality when CAT fully removed.

if (!headers) {
Expand All @@ -215,13 +216,11 @@ function handleMqTracingHeaders(headers, segment, transportType) {

// Check that we're in an active transaction.
const currentSegment = segment || this.getSegment()
if (!currentSegment || !currentSegment.transaction.isActive()) {
if (!currentSegment || !transaction.isActive()) {
this.logger.trace('Not processing headers for CAT or DT, not in an active transaction.')
return
}

const transaction = currentSegment.transaction

if (config.distributed_tracing.enabled) {
transaction.acceptDistributedTraceHeaders(transportType, headers)
return
Expand All @@ -237,7 +236,7 @@ function handleMqTracingHeaders(headers, segment, transportType) {
)
cat.assignCatToTransaction(externalId, externalTransaction, transaction)
const decodedAppData = cat.parseAppData(config, appData)
cat.assignCatToSegment(decodedAppData, currentSegment)
cat.assignCatToSegment({ appData: decodedAppData, segment: currentSegment, transaction })
// TODO: Handle adding ExternalTransaction metrics for this segment.
}

Expand Down Expand Up @@ -316,11 +315,11 @@ function insertCATReplyHeader(headers, useAlternateHeaderNames) {

// Are we in a transaction?
const segment = this.getSegment()
if (!segment || !segment.transaction.isActive()) {
const transaction = this.tracer.getTransaction()
if (!segment || !transaction?.isActive()) {
this.logger.trace('Not adding CAT reply header, not in an active transaction.')
return
}
const tx = segment.transaction

// Hunt down the content length.
// NOTE: In AMQP, content-type and content-encoding are guaranteed fields, but
Expand All @@ -334,11 +333,16 @@ function insertCATReplyHeader(headers, useAlternateHeaderNames) {
}
}

const { key, data } = cat.encodeAppData(config, tx, contentLength, useAlternateHeaderNames)
const { key, data } = cat.encodeAppData(
config,
transaction,
contentLength,
useAlternateHeaderNames
)
// Add the header.
if (key && data) {
headers[key] = data
this.logger.trace('Added outbound response CAT headers for transaction %s', tx.id)
this.logger.trace('Added outbound response CAT headers for transaction %s', transaction.id)
}
}

Expand Down
7 changes: 3 additions & 4 deletions lib/shim/webframework-shim/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,9 @@ module.exports._recordMiddleware = function _recordMiddleware(shim, middleware,
* @returns {Function} recorder for middleware
*/
function _makeMiddlewareRecorder(_shim, metricName) {
return function middlewareMetricRecorder(segment, scope) {
return function middlewareMetricRecorder(segment, scope, transaction) {
const duration = segment.getDurationInMillis()
const exclusive = segment.getExclusiveDurationInMillis()
const transaction = segment.transaction

if (scope) {
transaction.measure(metricName, scope, duration, exclusive)
Expand Down Expand Up @@ -454,7 +453,7 @@ function wrapNextFn({ shim, txInfo, nextDetails, segment }, nodule, property, is
if (isError(shim, err)) {
assignError(txInfo, err)
} else if (!isFinal && !nextDetails.isErrorWare && nextDetails.appendPath) {
segment.transaction.nameState.popPath(nextDetails.route)
txInfo.transaction.nameState.popPath(nextDetails.route)
}

// The next call does not signify the end of the segment
Expand All @@ -472,7 +471,7 @@ function wrapNextFn({ shim, txInfo, nextDetails, segment }, nodule, property, is
// more work to do in that scope.
return ret.then(function onNextFinish(v) {
if (nextDetails.appendPath) {
segment.transaction.nameState.appendPath(nextDetails.route)
txInfo.transaction.nameState.appendPath(nextDetails.route)
}

txInfo.segmentStack.push(segment)
Expand Down
11 changes: 5 additions & 6 deletions lib/spans/span-event-aggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,21 @@ class SpanEventAggregator extends EventAggregator {
* Attempts to add the given segment to the collection.
*
* @param {TraceSegment} segment - The segment to add.
* @param {string} [parentId=null] - The GUID of the parent span.
* @param {string} [parentId] - The GUID of the parent span.
* @param isRoot
* @returns {boolean} True if the segment was added, or false if it was discarded.
*/
addSegment(segment, parentId, isRoot) {
addSegment({ segment, transaction, parentId, isRoot }) {
// Check if the priority would be accepted before creating the event object.
const tx = segment.transaction

if (tx.priority < this._items.getMinimumPriority()) {
if (transaction.priority < this._items.getMinimumPriority()) {
++this.events.seen
this._metrics.getOrCreateMetric(this._metricNames.SEEN).incrementCallCount()

return false
}
const span = SpanEvent.fromSegment(segment, parentId || null, isRoot)
return this.add(span, tx.priority)
const span = SpanEvent.fromSegment(segment, transaction, parentId || null, isRoot)
return this.add(span, transaction.priority)
}

/**
Expand Down
23 changes: 11 additions & 12 deletions lib/spans/span-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,17 @@ class SpanEvent {
* category of the segment.
*
* @param {TraceSegment} segment - The segment to turn into a span event.
* @param transaction
* @param {?string} [parentId] - The ID of the segment's parent.
* @param isRoot
* @returns {SpanEvent} The constructed event.
*/
static fromSegment(segment, parentId = null, isRoot = false) {
static fromSegment(segment, transaction, parentId = null, isRoot = false) {
const spanContext = segment.getSpanContext()

// Since segments already hold span agent attributes and we want to leverage
// filtering, we add to the segment attributes prior to processing.
if (spanContext.hasError && !segment.transaction.hasIgnoredErrorStatusCode()) {
if (spanContext.hasError && !transaction.hasIgnoredErrorStatusCode()) {
const details = spanContext.errorDetails
segment.addSpanAttribute('error.message', details.message)
segment.addSpanAttribute('error.class', details.type)
Expand All @@ -128,25 +129,23 @@ class SpanEvent {
span.intrinsics[key] = value
}

const tx = segment.transaction

span.intrinsics.traceId = tx.traceId
span.intrinsics.traceId = transaction.traceId
span.intrinsics.guid = segment.id
span.intrinsics.parentId = parentId
span.intrinsics.transactionId = tx.id
span.intrinsics.sampled = tx.sampled
span.intrinsics.priority = tx.priority
span.intrinsics.transactionId = transaction.id
span.intrinsics.sampled = transaction.sampled
span.intrinsics.priority = transaction.priority
span.intrinsics.name = segment.name

if (isRoot) {
span.intrinsics.trustedParentId = tx.traceContext.trustedParentId
if (tx.traceContext.tracingVendors) {
span.intrinsics.tracingVendors = tx.traceContext.tracingVendors
span.intrinsics.trustedParentId = transaction.traceContext.trustedParentId
if (transaction.traceContext.tracingVendors) {
span.intrinsics.tracingVendors = transaction.traceContext.tracingVendors
}
}

// Only set this if it will be `true`. Must be `null` otherwise.
if (tx.baseSegment === segment) {
if (transaction.baseSegment === segment) {
span.intrinsics['nr.entryPoint'] = true
}

Expand Down
4 changes: 2 additions & 2 deletions lib/spans/streaming-span-event-aggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ class StreamingSpanEventAggregator extends Aggregator {
* @param isRoot
* @returns {boolean} True if the segment was added, or false if it was discarded.
*/
addSegment(segment, parentId, isRoot) {
addSegment({ segment, transaction, parentId, isRoot }) {
if (!this.started) {
logger.trace('Aggregator has not yet started, dropping span (%s).', segment.name)
return
}

const span = StreamingSpanEvent.fromSegment(segment, parentId, isRoot)
const span = StreamingSpanEvent.fromSegment(segment, transaction, parentId, isRoot)
this.stream.write(span)
}

Expand Down
5 changes: 2 additions & 3 deletions lib/spans/streaming-span-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ class StreamingSpanEvent {
}
}

static fromSegment(segment, parentId = null, isRoot = false) {
static fromSegment(segment, transaction, parentId = null, isRoot = false) {
const spanContext = segment.getSpanContext()

// Since segments already hold span agent attributes and we want to leverage
// filtering, we add to the segment attributes prior to processing.
if (spanContext.hasError && !segment.transaction.hasIgnoredErrorStatusCode()) {
if (spanContext.hasError && !transaction.hasIgnoredErrorStatusCode()) {
const details = spanContext.errorDetails
segment.addSpanAttribute('error.message', details.message)
segment.addSpanAttribute('error.class', details.type)
Expand All @@ -132,7 +132,6 @@ class StreamingSpanEvent {

const customAttributes = spanContext.customAttributes.get(DESTINATIONS.SPAN_EVENT)

const transaction = segment.transaction
const traceId = transaction.traceId

let span = null
Expand Down
Loading

0 comments on commit 7158cf8

Please sign in to comment.