Conversation
Now that `initOtel()` creates the logger, there's exactly one tracer provider per logger, so the logger can own it (and the root span's debug trace ID) rather than keeping it in a global. The logger creates the provider itself; `initOtel()` is left with resolving the configuration and creating the exporter from it. That also makes the fork callback unnecessary: it discarded the global state in forked children, but `startProcess()` already gives them a fresh global logger (leaking the parent's), so nothing in a child references the inherited provider; a child that wants tracing calls `initOtel()` and gets its own. Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
The parent sends the settings of every registered `Config`, but the hook applied them via `settings.set()`, which only knows `Settings` and silently returns false for anything else. So settings living in other `Config`s never reached the hook: the OpenTelemetry ones (so `nix build --otlp ...` didn't trace the hook), but also e.g. `experimental-features` and the file transfer settings. Apply them via `globalConfig.set()` instead. Only apply those that differ from our own values, though, since we've read the same configuration files: setting a deprecated setting warns even when it's set to its default, which showed up in the output of every build. (Having the parent send only its overridden settings instead doesn't work: things like `--store` set the setting without marking it as overridden, so the hook would end up using the wrong store.) Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
A collector's probabilistic sampler may drop a trace regardless of the W3C "sampled" flag, which makes the trace ID printed under NIX_DEBUG_OTEL useless if the trace never arrives. A non-zero `sampling.priority` attribute is the documented override, so set it on all spans when debugging. Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
The build hook exports its own telemetry (parented to ours via TRACEPARENT), so replaying its activities into our logger produced duplicate spans. Mark them as coming from a remote log source, like we do for messages forwarded by the daemon. Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
Commands that exec() another program (nix run/shell/develop/fmt, nix-shell, and `--help` running man) stopped the logger but never flushed it, so their traces were lost along with the exporter thread. Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
The exporter uploads periodically as well as on exit, so a slow build (e.g. on a loaded CI machine) spreads its spans over several uploads, which shifted the upload numbers the test relied on. Instead, delete the uploads before each step and select spans by name across all the uploads received since. Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
To get rid of: hint: Using 'master' as the name for the initial branch. This default branch name hint: will change to "main" in Git 3.0. Changing that from master breaks the tests. Also dedups test to use createGitRepo (cherry picked from commit 242d09e)
A rev-pinned fetch left the rev un-refed, so a later fetch of the same URL had nothing to negotiate from and re-downloaded shared history. Fetch into refs/nix/tip-<2 hex chars of rev> instead. Bucketing (256 slots) means unrelated revs don't keep evicting each other's tip the way a single shared ref would. Verified against a real ~7.7M-object repo: a third fetch that would've re-downloaded 67,656 objects with a single shared ref dropped to 7 with bucketing. (cherry picked from commit 74d9f99)
Without a network (as in the Nix sandbox on CI), `nix` turns off substitution unless it's requested explicitly, so the build never started a substitution goal and the test couldn't find its span. Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
Fetches an exact rev, checks its bucket ref was created, fetches a second rev, and asserts via GIT_TRACE_PACKET that the second fetch negotiated against the first rev's ref instead of re-downloading. (cherry picked from commit 99b5af9)
(cherry picked from commit e20887e)
fetchers/git: negotiate rev-pinned fetches from bucketed refs
Fix the Nix < 2.20 NAR hash fallback for inputs with submodules
Flake lock file updates:
• Updated input 'nix':
'path:../..'
→ 'path:../..'
• Updated input 'nix/nixpkgs':
'https://api.flakehub.com/f/pinned/DeterminateSystems/secure-packages-26.05/0.1.1013551%2Brev-07b3c48788b0deb9ee48c40ed5ff1dff7f4643e7/01a08dbc-1a6d-7e60-8dd0-bc2bf8ecb4fb/source.tar.gz' (2026-09-10)
→ 'https://api.flakehub.com/f/pinned/DeterminateSystems/secure-packages-26.05/0.1.1013583%2Brev-f041631d1ed8316e18423533f65925c81c3abce7/01a0a705-a838-70e1-90f7-6126cdd43de6/source.tar.gz' (2026-09-15)
…760-f596-4774-8107-f2a2522c87ad Release v3.22.4
…eSourceAccessor -> FdSink On modern filesystems like ZFS/BTRFS copy_file_range can do use block cloning for copying file contents. In the future we could use something similar via sendfile for sending data to a socket from a file descriptor (or even send the descriptor via SCM_RIGHTS). This is only beneficial for copying files wholesale (like we do with NAR unpacking). This cuts down the overhead of copying FOD outputs (for breaking file handles) significantly. These are numbers from building with store on ZFS of a simple FOD with a large output: (After) 79.03 1.752192 9 183511 pread64 8.42 0.186688 186688 1 copy_file_range 8.40 0.186341 46585 4 wait4 1.06 0.023536 7 3092 getdents64 User time (seconds): 4.69 System time (seconds): 3.80 Percent of CPU this job got: 63% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:13.32 (Before) 74.80 3.831072 15 244547 pread64 20.07 1.027953 16 61730 write 3.16 0.161804 40451 4 wait4 0.59 0.030202 9 3092 getdents64 User time (seconds): 4.71 System time (seconds): 7.27 Percent of CPU this job got: 82% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:14.47 Also adds tests for copyFdRange and fixes some windows specific bugs.
Backport libutil/serialise: Use zero-copy copy_file_range for copying PosixFileSourceAccessor -> FdSink
Flake lock file updates:
• Updated input 'nix':
'path:../..'
→ 'path:../..'
• Updated input 'nix/nixpkgs':
'https://api.flakehub.com/f/pinned/DeterminateSystems/secure-packages-26.05/0.1.1013583%2Brev-f041631d1ed8316e18423533f65925c81c3abce7/01a0a705-a838-70e1-90f7-6126cdd43de6/source.tar.gz' (2026-09-15)
→ 'https://api.flakehub.com/f/pinned/DeterminateSystems/secure-packages-26.05/0.1.1013924%2Brev-9f03b01a2c5e850ba180f9ca750979300e118389/01a0b003-ce4b-7973-91ca-5f497160ec59/source.tar.gz' (2026-09-17)
…ecf-65d2-4c6a-b86a-a3ad09955c87 Release v3.22.5
Add OpenTelemetry support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Not intended to be merged directly. This PR is a convenience to show the diff between upstream Nix and Determinate Nix (the
mainbranch).Continuation of #4.