Skip to content

add http request + test utilities#2

Merged
rochdev merged 4 commits into
masterfrom
request
Jan 26, 2018
Merged

add http request + test utilities#2
rochdev merged 4 commits into
masterfrom
request

Conversation

@rochdev

@rochdev rochdev commented Jan 24, 2018

Copy link
Copy Markdown
Member

This PR adds a platform module to abstract away Node specific code. This is so that other platforms can eventually be supported, such as browsers and vert.x. This first implementation includes a request method to make HTTP requests to the agent. It is very minimal in nature on purpose since it has a limited scope.

Also included are improvements to the test setup and the inclusion of additional test utilities.

@rochdev
rochdev requested a review from palazzem January 24, 2018 22:28
@palazzem palazzem added the core label Jan 25, 2018
@palazzem palazzem added this to the 0.1.0 milestone Jan 25, 2018
Comment thread index.js
module.exports = {
Tracer: DatadogTracer
}
platform.use(node)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

Comment thread src/platform/node/index.js Outdated
request: function (options, callback) {
options = assign({
headers: {},
timeout: 5000

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we can tweak this value, but in general the timeout should be lower

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Totally agree. I started with a very high value to be safe. Would you rather change it to something like 1 or 2 seconds?

@rochdev
rochdev merged commit 40c8a23 into master Jan 26, 2018
@rochdev
rochdev deleted the request branch January 26, 2018 22:10
paullegranddc added a commit that referenced this pull request May 3, 2021
alrosot pushed a commit to alrosot/dd-trace-js that referenced this pull request May 20, 2021
BridgeAR added a commit that referenced this pull request Jan 5, 2026
BridgeAR added a commit that referenced this pull request Jan 5, 2026
@dd-octo-sts dd-octo-sts Bot mentioned this pull request Jan 12, 2026
dd-octo-sts Bot pushed a commit that referenced this pull request Jan 12, 2026
nina9753 pushed a commit that referenced this pull request Jan 15, 2026
crysmags added a commit that referenced this pull request May 14, 2026
After merging master, #8309's perf wins target functions that either no
longer exist (wrapExecute / wrapFields / pathToArray / finishResolvers
moved out of instrumentations/graphql.js) or live in a deleted file
(resolve.js was folded into execute.js). Port the still-applicable
changes onto the migrated execute plugin:

  #1 _startResolveSpan uses info.fieldNodes[0] instead of .find(fn =>
     fn.kind === 'Field'). The executor only hands FieldNode siblings.
  #2 pathToArray switches to count-then-fill (drops the trailing
     .reverse() and the push-grow).
  #3 getResolverInfo lazy-allocates resolverVars: skips both the
     up-front {} and the directive-loop assignment when args is empty
     and no directives have arguments.
  #4 shouldInstrument early-returns on config.depth < 0 (no-limit, the
     default-enabled case) before walking the path.
  #5 buildCollapsedPathString builds the collapsed key in one walk;
     drops the intermediate collapsedPath array. iastResolveCh.publish
     now passes raw path / pathString, matching the contract the old
     resolve.js had with the IAST subscriber.
  drive-by  wrapFields iterates Object.values(type._fields) directly.

  #7 (addVariableTags early-return) already auto-merged during the
     master merge.
  #6 (single documentSources.get in wrapExecute) is already the shape
     of bindStart in the migrated plugin.

The reverted depth=0 bindStart short-circuit (156a557 / ca2d041)
sat at a different position — inside bindStart, gated on _depthDisabled
(config.depth === 0). It was rolled back because piling it on top of
the resolveAsync depth-flag fix didn't move plugin-graphql-long-with-
depth-off any further. This port stays inside shouldInstrument, fires
on config.depth < 0 (the *enabled* default), and targets the hot path
on plugin-graphql-long.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
crysmags added a commit that referenced this pull request May 19, 2026
After merging master, #8309's perf wins target functions that either no
longer exist (wrapExecute / wrapFields / pathToArray / finishResolvers
moved out of instrumentations/graphql.js) or live in a deleted file
(resolve.js was folded into execute.js). Port the still-applicable
changes onto the migrated execute plugin:

  #1 _startResolveSpan uses info.fieldNodes[0] instead of .find(fn =>
     fn.kind === 'Field'). The executor only hands FieldNode siblings.
  #2 pathToArray switches to count-then-fill (drops the trailing
     .reverse() and the push-grow).
  #3 getResolverInfo lazy-allocates resolverVars: skips both the
     up-front {} and the directive-loop assignment when args is empty
     and no directives have arguments.
  #4 shouldInstrument early-returns on config.depth < 0 (no-limit, the
     default-enabled case) before walking the path.
  #5 buildCollapsedPathString builds the collapsed key in one walk;
     drops the intermediate collapsedPath array. iastResolveCh.publish
     now passes raw path / pathString, matching the contract the old
     resolve.js had with the IAST subscriber.
  drive-by  wrapFields iterates Object.values(type._fields) directly.

  #7 (addVariableTags early-return) already auto-merged during the
     master merge.
  #6 (single documentSources.get in wrapExecute) is already the shape
     of bindStart in the migrated plugin.

The reverted depth=0 bindStart short-circuit (156a557 / ca2d041)
sat at a different position — inside bindStart, gated on _depthDisabled
(config.depth === 0). It was rolled back because piling it on top of
the resolveAsync depth-flag fix didn't move plugin-graphql-long-with-
depth-off any further. This port stays inside shouldInstrument, fires
on config.depth < 0 (the *enabled* default), and targets the hot path
on plugin-graphql-long.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
christophe-papazian added a commit that referenced this pull request Jun 16, 2026
- #3 (regression from round 5): constraintMatchesSlash no longer treats a '/' that
  appears only inside a character class as slash-spanning. `[^/]+` denies slashes, so
  /:id([^/]+)/users (Express 4) normalizes to /{id}/users again instead of null.
- #2: a non-terminal catch-all (a wildcard with a non-empty segment after it, incl. an
  optional {/*rest}/tail) is rejected at compile (→ null) rather than silently dropped.
- #1: a segment containing two independent optional groups (e.g. :a{.:b}{-:c}) is
  rejected (→ null); our single per-segment regex can't replicate path-to-regexp's
  ordered-alternative assignment, so the combined name could be wrong. Single
  intra-segment optionals (:id{.:format}) are unaffected.
- #4: structural-only optional groups — a {...} wrapping only nested group(s) with no
  segment/token of its own (e.g. the outer braces in /a{{/b}}) — are collapsed by
  reparenting represented groups to their nearest represented ancestor, so /a{{/b}}
  resolves to /a/b | /a instead of always /a.

Adds a regression test per finding (verified against live Express 5).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
szegedi added a commit that referenced this pull request Jul 8, 2026
…n unsupported runtimes

Addresses two P2 review points on the OTEP-4947 branch.

Endpoint refresh (#2). HTTP server plugins set 'span.type=web' and
'http.method' when a request arrives and only add 'http.route' /
'resource.name' later, once framework routing has resolved the URL. The
writer used to treat any non-undefined webTags result as a fully formed
answer at build time — 'needsEndpoint' would flip to false immediately —
so the OTEP-4947 record's endpoint attribute got frozen as e.g. 'GET'
with no route, and later route arrival was silently ignored.

Defer writing the endpoint until 'isEndpointFinal(tags)' is true (either
'resource.name' is set, or both 'http.method' and 'http.route' are), and
subscribe onTagsUpdated to the raw 'dd-trace:span:tags:update' channel
(not webTagsCache.resolvedCh) so we also see content changes on
already-cached web-server spans. The shared cache still runs first
(module-load subscribe), so its cached webTags is up to date by the time
our handler queries it. Once the endpoint has been appended, further
tags-update fires are no-ops (we can't overwrite a written entry — OTEP
readers honor the first occurrence).

Process-context metadata gate (#4). On non-Linux or non-ACF runtimes,
otel-thread-ctx.start() returns false but tracer_metadata.js was still
publishing the threadlocal_metadata block in the OTel process context —
advertising a decodable OTEP-4947 stream that no writer was producing
records for. Add the same 'process.platform === linux' and 'isACFActive'
gates to getThreadLocalMetadata that start() applies, so the block is
only advertised when the writer can actually run.

Tests: three new cases for the defer-and-append endpoint path and two
new cases for the platform/ACF gates on getThreadLocalMetadata. 24/24
passing.
szegedi added a commit that referenced this pull request Jul 8, 2026
Addresses Codex review point #2 on #9210: an OTEP-4947 record can only
carry the first-written value for each attribute key, and HTTP plugins
routinely set 'http.method' up front and add 'http.route' (plus
'resource.name') later once routing has resolved. The writer previously
committed the endpoint on first activation, so a request to '/users/:id'
was recorded as 'GET' forever.

Introduce an isEndpointFinal(tags) heuristic and only write the endpoint
when the tag bag looks stable — either 'resource.name' is set, or both
'http.method' and 'http.route' are. Otherwise mark the context as
needsEndpoint and re-check on every 'dd-trace:span:tags:update' fire
(switched from webTagsCache.resolvedCh, which only fires on presence
transitions and would miss content-only updates).
szegedi added a commit that referenced this pull request Jul 10, 2026
Addresses Codex review point #2 on #9210: HTTP plugins routinely set
'http.method' up front and add 'http.route' (plus 'resource.name')
later once routing has resolved. The writer previously committed the
endpoint on first activation, so an out-of-process reader sampling
mid-request saw a bare 'GET' as the endpoint for a call to
'/users/:id'.

OTEP-4947 duplicates are last-wins, so a later appendAttributes would
overwrite the interim value for readers that decode the record in
full — but a sampling reader can still observe the incomplete value.
Introduce an isEndpointFinal(tags) heuristic and only write the
endpoint when the tag bag looks stable — either 'resource.name' is
set, or both 'http.method' and 'http.route' are. Otherwise mark the
context as needsEndpoint and re-check on every
'dd-trace:span:tags:update' fire (switched from
webTagsCache.resolvedCh, which only fires on presence transitions and
would miss content-only updates).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants