Skip to content

Update Node custom labels support to use hashmap-based labels.#91

Merged
umanwizard merged 17 commits into
mainfrom
node-cl-wip-pr
Aug 15, 2025
Merged

Update Node custom labels support to use hashmap-based labels.#91
umanwizard merged 17 commits into
mainfrom
node-cl-wip-pr

Conversation

@umanwizard

Copy link
Copy Markdown
Collaborator

The previous approach, which involved resetting the current labelset every time a piece of javascript code ran, was too slow. So we switched to a new approach, where we only run our own code when a new async context is created or destroyed, or when label sets change.

Since we are no longer setting the current labelset, we instead store labelsets in a hash map from async ID -> labelset (this is implemented in the custom_labels library). Thus, at profiling time, we need to get the current async ID from the node.js environment, then look it up in the hashmap. This PR accomplishes the profiling side of that change.

The previous approach, which involved resetting the current labelset
every time a piece of javascript code ran, was too slow. So we
switched to a new approach, where we _only_ run our own code when a
new async context is created or destroyed, or when label sets change.

Since we are no longer setting the current labelset, we instead store
labelsets in a hash map from async ID -> labelset (this is implemented
in the custom_labels library). Thus, at profiling time, we need to get
the current async ID from the node.js environment, then look it up in
the hashmap. This PR accomplishes the profiling side of that change.
@umanwizard umanwizard requested review from brancz and gnurizen August 13, 2025 20:50
@gnurizen

Copy link
Copy Markdown
Collaborator

We should get the CI green and add a Makefile target to run the new container tests (which are awesome)! And then have unit-test-on-pull-request hit that Makefile target. Maybe the test job could be extended to hit the container tests?

@umanwizard

Copy link
Copy Markdown
Collaborator Author

@gnurizen my test already runs during the "Interpreter integration" test job

@gnurizen

Copy link
Copy Markdown
Collaborator

@gnurizen my test already runs during the "Interpreter integration" test job

Oh sweet I was looking at upstream otel fork and didn't see it! Forgot I added a generic integration test invocation to run the luajit tests.

Comment thread cmd/csv2go/main.go
Comment thread complete_offsets.csv

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Upstream will want to see this in interpreter/customlabels/integrationtests/, upstream the golabels tests now live in interpreter/golabels/integrationtests/.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I moved the node test to there. I'm gonna leave this one here and address it in a follow-up PR because it already existed before this PR (and needs more changes in order to start working again)

Comment thread reporter/iface.go
maxRetries int, waitRetry time.Duration) error
}

type MetricsReporter interface {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we know what happened to the metrics reporter? Might be worth kicking off a discussion on slack if it wasn't obvious what the plan was when this was removed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

sure, I'll check with them what happened

Comment thread interpreter/nodev8/v8.go

major := binary.LittleEndian.Uint32(versBuf[0:4])
minor := binary.LittleEndian.Uint32(versBuf[4:8])
patch := binary.LittleEndian.Uint32(versBuf[8:12])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's wrong with the version info Loader already looked up?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

That is the v8 version; this is the Node version.

The Environment class as well as the execution async ID are not v8 concepts, they are higher level Node.js concepts. So two versions of Node could have a different set of offsets even if they use the same underlying version of v8, and so we need the actual Node version here.

Comment thread support/ebpf/interpreter_dispatcher.ebpf.c Outdated
Comment thread support/ebpf/interpreter_dispatcher.ebpf.c
Comment thread support/ebpf/interpreter_dispatcher.ebpf.c Outdated
abiVersionElfVA libpf.Address
currentSetTlsAddr libpf.Address

hasCurrentHm bool

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why not just have hasCurrentHm == currentHmTlsAddr != 0?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

0 is a valid TLS symbol, it would just mean the variable happens to be the first thing in the TLS segment.

Comment thread interpreter/customlabels/node_test.go
Comment thread support/ebpf/interpreter_dispatcher.ebpf.c
@umanwizard umanwizard merged commit b593d65 into main Aug 15, 2025
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants