Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Removed transaction from segment. Introduced a new enterSegment and enterTransaction to make context propagation more clear #2646

Merged
merged 3 commits into from
Oct 31, 2024

Conversation

bizob2828
Copy link
Member

@bizob2828 bizob2828 commented Oct 11, 2024

This PR is a lot so I apologize. This removes transaction from segment, introduces a context class for storing the active transaction and segment as well as helpers to create a new context for entering a new segment and transaction.

Note: You will see two instances where enterSegment passes in the transaction because the 3rd party promise intrumentation has its own context manager. Some follow up work will occur in #2657. This is targeting next as this is quite a radical change and we need to do more manual testing once all the work is done

Copy link

codecov bot commented Oct 11, 2024

Codecov Report

Attention: Patch coverage is 99.69072% with 3 lines in your changes missing coverage. Please review.

Please upload report for BASE (next@5275a3c). Learn more about missing BASE report.

Files with missing lines Patch % Lines
lib/shim/shim.js 98.96% 2 Missing ⚠️
lib/instrumentation/when/index.js 96.77% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             next    #2646   +/-   ##
=======================================
  Coverage        ?   97.25%           
=======================================
  Files           ?      291           
  Lines           ?    46251           
  Branches        ?        0           
=======================================
  Hits            ?    44981           
  Misses          ?     1270           
  Partials        ?        0           
Flag Coverage Δ
integration-tests-cjs-18.x 74.14% <72.30%> (?)
integration-tests-cjs-20.x 74.15% <72.30%> (?)
integration-tests-cjs-22.x 74.19% <72.30%> (?)
integration-tests-esm-18.x 49.59% <28.85%> (?)
integration-tests-esm-20.x 49.60% <28.85%> (?)
integration-tests-esm-22.x 49.62% <28.85%> (?)
unit-tests-18.x 88.83% <80.80%> (?)
unit-tests-20.x 88.83% <80.80%> (?)
unit-tests-22.x 88.83% <80.80%> (?)
versioned-tests-18.x 79.07% <87.91%> (?)
versioned-tests-20.x 79.09% <87.91%> (?)
versioned-tests-22.x 79.09% <87.91%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bizob2828 bizob2828 force-pushed the remove-tx-from-segment branch 3 times, most recently from a876112 to 94f381a Compare October 16, 2024 16:05
@bizob2828 bizob2828 force-pushed the remove-tx-from-segment branch from 94f381a to 3cd3159 Compare October 24, 2024 17:39
@bizob2828 bizob2828 changed the base branch from main to next October 24, 2024 18:13
@bizob2828 bizob2828 changed the title Remove tx from segment feat: Removed transaction from segment. Introduced a new enterSegment and enterTransaction to make context propagation more clear Oct 24, 2024
@bizob2828 bizob2828 marked this pull request as ready for review October 24, 2024 18:50
@bizob2828 bizob2828 force-pushed the remove-tx-from-segment branch from cb93d08 to c2afb3f Compare October 24, 2024 18:51
@bizob2828 bizob2828 force-pushed the remove-tx-from-segment branch from c2afb3f to b7b4ef8 Compare October 24, 2024 18:52
@bizob2828 bizob2828 requested a review from jsumners-nr October 24, 2024 18:53
@bizob2828 bizob2828 force-pushed the remove-tx-from-segment branch from b7b4ef8 to 17ea0db Compare October 24, 2024 19:19
Copy link
Contributor

@jsumners-nr jsumners-nr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As expected, most of the changes are signature related updates. The majority of my comments are around making sure our inline docs are correct. But I do have a couple of clarifying questions.

lib/agent.js Outdated
@@ -843,7 +842,7 @@ Agent.prototype.getLinkingMetadata = function getLinkingMetadata() {
}

if (config.distributed_tracing.enabled && segment) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like the only usage of segment in this function, and it was previously used only to get the transaction. I think we can remove const segment = this.tracer.getSegment().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the line right below it is using segment to get the span id

@@ -21,10 +21,9 @@ function ParsedStatement(type, operation, collection, raw) {
}
}

ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, scope) {
ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, scope, transaction) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we will eventually remove segment from the parameters and then retrieve it from the transaction in the function body?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. Recorders are registered at the start of recording of a segment. In tracer they are added to transaction and binding the appropriate segment:

  if (recorder) {
    transaction.addRecorder(recorder.bind(null, segment))
  }

Then once a transaction end it iterates over all the recorders and calls the function with the scope and the transaction

Transaction.prototype.record = function record() {
  const name = this.name
  for (let i = 0, l = this._recorders.length; i < l; ++i) {
    this._recorders[i](name, this)
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this work make transaction the entry point of the API? As in, wouldn't we attempt to retrieve a segment from the transaction?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect all of the functions that are getting a new transaction parameter can also drop the segment parameter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need the segment because it's getting ended

Copy link
Member Author

@bizob2828 bizob2828 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed all comments and responded to questions in here

@@ -15,7 +15,7 @@ const repos = [
{
name: 'apollo-server',
repository: 'https://github.com/newrelic/newrelic-node-apollo-server-plugin.git',
branch: 'main',
branch: 'remove-transaction-from-segment',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I had to update this repo too. we're going to have to keep track of this when we release

lib/agent.js Outdated
@@ -843,7 +842,7 @@ Agent.prototype.getLinkingMetadata = function getLinkingMetadata() {
}

if (config.distributed_tracing.enabled && segment) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the line right below it is using segment to get the span id

@@ -21,10 +21,9 @@ function ParsedStatement(type, operation, collection, raw) {
}
}

ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, scope) {
ParsedStatement.prototype.recordMetrics = function recordMetrics(segment, scope, transaction) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. Recorders are registered at the start of recording of a segment. In tracer they are added to transaction and binding the appropriate segment:

  if (recorder) {
    transaction.addRecorder(recorder.bind(null, segment))
  }

Then once a transaction end it iterates over all the recorders and calls the function with the scope and the transaction

Transaction.prototype.record = function record() {
  const name = this.name
  for (let i = 0, l = this._recorders.length; i < l; ++i) {
    this._recorders[i](name, this)
  }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need the segment because it's getting ended

@@ -22,6 +22,7 @@ const Logs = require('./logs')
const DT_ACCEPT_PAYLOAD_EXCEPTION_METRIC = 'DistributedTrace/AcceptPayload/Exception'
const DT_ACCEPT_PAYLOAD_PARSE_EXCEPTION_METRIC = 'DistributedTrace/AcceptPayload/ParseException'
const REQUEST_PARAMS_PATH = 'request.parameters.'
const TraceStacks = require('../util/trace-stacks')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm going to remove this trace stacks idea. it's a debug thing that seems useless

wrapped[symbols.original] = getOriginal(handler)
wrapped[symbols.segment] = active
// wrapped[symbols.segment] = segment
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll restore this but not sure if we need it

@bizob2828 bizob2828 requested a review from jsumners-nr October 30, 2024 19:13
@bizob2828 bizob2828 merged commit d726132 into next Oct 31, 2024
48 checks passed
@bizob2828 bizob2828 deleted the remove-tx-from-segment branch October 31, 2024 12:44
bizob2828 added a commit that referenced this pull request Oct 31, 2024
… and enterTransaction to make context propagation more clear (#2646)
@bizob2828
Copy link
Member Author

Closes #2658

bizob2828 added a commit that referenced this pull request Oct 31, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Nov 7, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Nov 8, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Nov 13, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Nov 19, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Dec 4, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Dec 9, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Dec 12, 2024
… and enterTransaction to make context propagation more clear (#2646)
jsumners-nr pushed a commit to jsumners-nr/node-newrelic that referenced this pull request Dec 13, 2024
… and enterTransaction to make context propagation more clear (newrelic#2646)
bizob2828 added a commit that referenced this pull request Dec 13, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Dec 16, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Dec 19, 2024
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Jan 13, 2025
… and enterTransaction to make context propagation more clear (#2646)
bizob2828 added a commit that referenced this pull request Jan 14, 2025
… and enterTransaction to make context propagation more clear (#2646)
@jlowcs
Copy link

jlowcs commented Jan 24, 2025

This change introduced a breaking change that broke @newrelic/apollo-server-plugin

TypeError: Cannot read properties of undefined (reading 'measure')
    at createMetricPairs (/node_modules/@newrelic/apollo-server-plugin/lib/common.js:116:17)
    at recordOperationSegment (/node_modules/@newrelic/apollo-server-plugin/lib/common.js:111:3)
    at Transaction.record (/node_modules/newrelic/lib/transaction/index.js:680:23)
    at Transaction.end (/node_modules/newrelic/lib/transaction/index.js:212:10)
    at ServerResponse.instrumentedFinish (/node_modules/newrelic/lib/instrumentation/core/http.js:207:15)
    at <anonymous> (/node_modules/@opentelemetry/context-async-hooks/src/AbstractAsyncHooksContextManager.ts:75:49)
    at AsyncLocalStorage.run (node:internal/async_local_storage/async_hooks:91:14)
    at SentryContextManager.with (/node_modules/@opentelemetry/context-async-hooks/src/AsyncLocalStorageContextManager.ts:40:36)
    at SentryContextManager.with (/node_modules/@sentry/opentelemetry/src/contextManager.ts:71:24)
    at ServerResponse.contextWrapper (/node_modules/@opentelemetry/context-async-hooks/src/AbstractAsyncHooksContextManager.ts:75:26)
    at Object.onceWrapper (node:events:632:28)
    at ServerResponse.emit (node:events:530:35)
    at AsyncLocalStorage.run (node:internal/async_local_storage/async_hooks:91:14)
    at AsyncLocalContextManager.runInContext (/node_modules/newrelic/lib/context-manager/async-local-context-manager.js:58:38)
    at ServerResponse.wrapped [as emit] (/node_modules/newrelic/lib/transaction/tracer/index.js:250:37)
    at onFinish (node:_http_outgoing:1077:10)
    at callback (node:internal/streams/writable:766:21)
    at afterWrite (node:internal/streams/writable:710:5)
    at afterWriteTick (node:internal/streams/writable:696:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:89:21)

I just filed an issue: #2903

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants