Add POSIX telemetry#27379
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces cross-platform build support for telemetry by extending the existing Windows ETW telemetry to non-Windows platforms via the 1DS (cpp_client_telemetry) SDK, wiring it through the build scripts and CMake.
Changes:
- Adds a new POSIX telemetry provider implementation using the 1DS SDK and swaps it into the POSIX Env when enabled.
- Extends build and CMake plumbing to fetch/link cpp_client_telemetry on non-Windows and to expose a cross-platform
--use_telemetrybuild flag. - Updates top-level build wrappers and third-party notices for the new dependency.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/ci_build/build_args.py | Moves --use_telemetry to cross-platform args. |
| tools/ci_build/build.py | Always sets -Donnxruntime_USE_TELEMETRY=ON/OFF based on --use_telemetry. |
| onnxruntime/core/platform/windows/telemetry.cc | Include ordering tweak only. |
| onnxruntime/core/platform/posix/telemetry.h | Introduces POSIX telemetry provider interface (1DS). |
| onnxruntime/core/platform/posix/telemetry.cc | Implements POSIX telemetry provider using cpp_client_telemetry. |
| onnxruntime/core/platform/posix/env.cc | Uses PosixTelemetry provider when USE_1DS_TELEMETRY is defined. |
| cmake/onnxruntime_common.cmake | Adds POSIX telemetry sources/defines and links 1DS + system libs when enabled. |
| cmake/onnxruntime_1ds_telemetry.cmake | New helper module for enabling 1DS telemetry on non-Windows. |
| cmake/external/onnxruntime_external_deps.cmake | Fetches cpp_client_telemetry only when telemetry is enabled on non-Windows. |
| cmake/deps.txt | Adds cpp_client_telemetry dependency entry. |
| cmake/CMakeLists.txt | Includes the new 1DS telemetry CMake module. |
| build.sh | Now passes --use_telemetry by default. |
| build.bat | Now passes --use_telemetry by default. |
| ThirdPartyNotices.txt | Adds cpp_client_telemetry license text (and an additional KleidiAi block). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fded7ba to
2f18217
Compare
178e702 to
b0eaeb7
Compare
generate_android_triplets did not receive use_telemetry, so Android vcpkg builds with telemetry skipped the sqlite3 feature-omit defines that Linux/macOS apply, bloating the offline-store sqlite3 and diverging from the other non-Windows platforms. Thread use_telemetry through build.py and generate_android_triplets into generate_triplet_for_android, and emit the same per-PORT sqlite3 minimal-defines block (guarded by use_telemetry so non-telemetry triplets stay byte-identical and keep the vcpkg binary cache valid). Addresses two Copilot review comments on PR #27379. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tianleiwu
left a comment
There was a problem hiding this comment.
Review: Add POSIX telemetry
Thanks for the thorough cross-platform telemetry work. The redaction and CI-suppression helpers are well-factored and well-tested, and the SDK lifetime handling (a shared_mutex around logger init/shutdown, register-count singleton, non-blocking teardown) is careful. A few items are worth addressing before merge, one of which is a consent/opt-out concern.
High priority
ORT_TELEMETRY_DISABLED / DisableTelemetryEvents() still transmit the ProcessInfo event. Initialize() sets enabled_ = false for the env-var opt-out but still creates the uploader and logger, and LogProcessInfo() gates only on logger_ != nullptr (not IsEnabled()). So a user who sets ORT_TELEMETRY_DISABLED=1 still uploads one ProcessInfo event carrying osDescription, processName, cpuModel, totalMemoryMB, and (on desktop) the hashed device id. README.md / docs/Privacy.md present this variable as a way to turn data collection off, which most users will read as "nothing is sent." Recommend either (a) fully suppressing ProcessInfo on the explicit opt-out (treat it like CI suppression and skip creating the uploader), or (b) documenting explicitly that a single non-PII ProcessInfo event is still emitted after opt-out. Inline note on the code path.
Suggestions
- UTF-8 truncation in
ScrubStringForTelemetry: the finalout.resize(kMaxTelemetryStringLength)can cut in the middle of a multi-byte UTF-8 sequence, leaving an invalid partial codepoint at the tail of the transmitted string. Consider backing up to a UTF-8 boundary. - Schema drift vs. the Windows provider: on failure the POSIX helpers return
""/-1while the new Windows helpers return"unknown"/0for the same fields (cpuModel,totalMemoryMB,processorCount); andProcessInforeportscpuCountviastd::thread::hardware_concurrency()while the logger-contextprocessorCountusessysconf(_SC_NPROCESSORS_ONLN). Aligning sentinel values and sources keeps the backend schema consistent. - Device-id write race across processes:
open(..., O_WRONLY|O_CREAT|O_TRUNC)inDeviceId::InitializeInternal()lets two concurrent first-run processes each generate and truncate/write a different GUID. Both are valid, but the persisted id can flap on first run; anO_EXCLcreate-then-read-back (or write-temp +rename) would make first-run persistence deterministic. cmake/vcpkg.jsondrops the explicitutf8-rangedependency. This looks unrelated to telemetry. Is it intentional (now pulled transitively by the new baseline's protobuf) or an accidental removal? Worth confirming it does not regress non-telemetry builds.
Nitpick
friend class EventBuilder;inposix/telemetry.happears unnecessary:EventBuilderdoes not referenceprojection_(or any private member);projection_is read directly inLogSessionCreation. It can likely be removed.
|
@tianleiwu Thank you for the detailed review. I have addressed everything you mentioned. Regarding |
tianleiwu
left a comment
There was a problem hiding this comment.
Consolidated review — head 86d16ad
Re-reviewed the latest head. This PR has already been through several review rounds, so this round mostly re-confirms prior threads and adds only the genuinely new findings (inline below). Overall implementation quality is high: careful reader/writer locking around SDK teardown, defensive ORT_TRY/ORT_CATCH on every path, secure device-id file creation (open+fchmod before write, 0700 tree, hashed id only), and well-tested path redaction / CI-suppression helpers.
My earlier-round threads — status at this head
- ✅ UTF-8 truncation splitting codepoints (redaction) — fixed via
TruncateUtf8AtBoundary+ dedicated test. - ✅
cpuCountvsprocessorCountmismatch — both now useGetProcessorCount()(sysconf). - ✅ Unnecessary
friend EventBuilder— removed. ⚠️ Opt-out asymmetry (ORT_TELEMETRY_DISABLEDstill writes a device-id file + uploadsProcessInfo) — replied and re-opened the existing thread: the code behavior is unchanged; only the docs were updated. Please confirm privacy sign-off or gate the on-disk write + init event behind the opt-out.
Already tracked by existing (resolved) threads — not re-posting to avoid duplicates, but flagging so they aren't lost before merge:
- Telemetry on-by-default via
build.sh --use_telemetryfor from-source builds (posture change vs. the old "no data collection for private builds"). - Hardcoded collector URL + obfuscated (base64+XOR) default tenant token embedded in every binary — worth a one-line comment stating it's a public, write-only ingestion key, not a secret.
- Repo-wide vcpkg baseline bump + new global
overrides(mimalloc2.1.1,benchmark1.9.4,directx-headers1.616.0) andutf8-rangeremoval, which affect all builds (incl. Windows/DML). Avcpkg install --dry-rundiff on a non-telemetry config would confirm no silent downgrade.
Nit (not worth an inline): ThirdPartyNotices.txt ends without a trailing newline, and a few YAML files carry whitespace-only churn unrelated to telemetry.
Verdict: COMMENT — no blocking correctness bugs; please close out the privacy-posture sign-off and the vcpkg blast-radius check before merge.
Build non-Windows telemetry on the 1DS SDK with POSIX event emission, library identity, stable product-salted device identity, redaction, CI/test suppression, and official package integration. Use 1DS-owned host app/OS/device context, publish generated desktop IDs atomically across processes, retain platform identity on Android/iOS, and document telemetry defaults and opt-out behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Centralize local test telemetry suppression across shared and custom test entry points, serialize RuntimePerf batch durations into the Windows-compatible bounded schema, warn on device-ID persistence fallback, and widen Windows memory telemetry to 64 bits.
Files changed:
- onnxruntime/core/platform/posix/telemetry.cc
- onnxruntime/core/platform/windows/telemetry.cc
- onnxruntime/test/util/include/telemetry_test_environment.h
- onnxruntime/test/{unittest_main,global_thread_pools,onnx,perftest,ep_weight_sharing_ctx_gen,webgpu/external_dawn,fuzzing}/...
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
tianleiwu
left a comment
There was a problem hiding this comment.
Re-review — head 89f882a
Re-reviewed the Address telemetry review follow-ups commit against all my earlier threads. Every concern from my prior rounds is now resolved, and I verified each fix on the current head:
- RuntimePerf batch durations —
AddBatchSizeDurationsnow serializes into a single boundedtotalRunDurationPerBatchSizestring, matching the WindowsLogRuntimePerfformat exactly (same<batch>: <duration>, ...layout and the sameunordered_mapsource). Payload width is no longer unbounded. - Device-ID persistence failure —
LogProcessInfo()now emits a singleORT_TELEMETRY_WARNwhenDeviceIdStatus::Failed, correctly guarded to the desktop path (excluded on Android/iOS). Good for field diagnosability without adding noise. - Windows memory width —
GetTotalMemoryMB()and its local now useuint64_t, and the event usesTraceLoggingUInt64, matching the POSIX side. - Local test suppression — centralized into
onnxruntime::test::SuppressTelemetryForTests()and invoked at the top of every affected test entry point (unittest_main,global_thread_pools,onnx,perftest,ep_weight_sharing_ctx_gen,webgpu/external_dawn,fuzzing) before anyOrt::Envis created, so local non-CI dev runs won't spin up the uploader. - Opt-out asymmetry / on-by-default posture — accepting the author's rationale that the
ProcessInfoheartbeat underORT_TELEMETRY_DISABLEDis intentional and has explicit privacy sign-off, as documented inPrivacy.md.
The earlier UTF-8 truncation, cpuCount vs processorCount mismatch, and the stray friend declaration were also confirmed fixed in prior commits. No remaining code-level findings from my side; the concurrency/teardown design and privacy scrubbing remain solid.
Wait for the documented 1DS Java HttpClient before creating the native log manager so Android hosts without context fail closed instead of crashing. Let 1DS use the Java-provided app-private cache directory. Files changed: - onnxruntime/core/platform/posix/telemetry.cc: gate Android initialization and defer cache selection to 1DS. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b269873-a7bf-490e-a412-70a920868135
Clarify source-build defaults, align CLI help and ProcessInfo schema, enforce telemetry directory permissions, scrub provider and EP-library path fields, and use the shared scoped environment helper on Windows and POSIX. Files changed: - docs/Privacy.md - tools/ci_build/build_args.py - onnxruntime/core/platform/posix/device_id.cc - onnxruntime/core/platform/posix/telemetry.cc - onnxruntime/core/platform/telemetry_environment.h - onnxruntime/test/platform/telemetry_environment_test.cc Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
State explicitly that every official non-Windows packaging pipeline passes --use_telemetry, while retaining the separate direct-source-build behavior. Files changed: - docs/Privacy.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Anchor multi-segment relative Windows and POSIX paths at the beginning of the containing token so a username in the first path segment cannot survive. Preserve support for spaced Windows profile paths and extend the privacy regression suite. Files changed: - onnxruntime/core/platform/telemetry_redaction.h: strengthen relative-path anchors. - onnxruntime/test/platform/telemetry_redaction_test.cc: cover first-segment and spaced usernames. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b269873-a7bf-490e-a412-70a920868135
Document that external Windows telemetry builds remain unsupported because they require the private TraceLogging configuration header, while WebAssembly remains unsupported by 1DS. Files changed: - tools/ci_build/build_args.py Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Summary
Adds cross-platform 1DS telemetry for ONNX Runtime on Linux, macOS, Android, and iOS while keeping the existing Windows ETW provider unchanged. WebAssembly builds remain excluded.
Behavior
--use_telemetry; directbuild.py/CMake callers may omit it to build telemetry out.ORT_TELEMETRY_DISABLEDand the telemetry APIs disable session, model, execution-provider, performance, and error events; a minimalProcessInfoheartbeat may still be emitted outside CI/tests.Build integration
cpp-client-telemetryport when available, with a pinned FetchContent fallback.Validation
onnxruntime_commonbuild with GCC 13.onnxruntime_test_alltarget build and lintrunner checks.