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
Prevent relative environment paths from redirecting telemetry state into the working directory. Bind device ID operations to a validated owner-only directory descriptor and serialize corrupted-file repair with OGA so concurrent processes converge on one persistent ID. Files changed: - onnxruntime/core/platform/posix/device_id.cc: validate absolute storage paths, use dirfd-relative I/O, and lock corruption repair. - onnxruntime/test/platform/posix/device_id_test.cc: cover XDG handling, symlink rejection, and corruption recovery. - cmake/onnxruntime_unittests.cmake: include POSIX device ID tests only in telemetry-enabled desktop builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 59 out of 59 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
onnxruntime/core/platform/telemetry_environment.h:107
- The comment claims ORT_TELEMETRY_DISABLED is an opt-out that is "honored on every platform", but WindowsTelemetry does not consult this env var (and the public docs in this PR describe the env-var opt-out as non-Windows-only). This is misleading for future maintainers; either implement env-var handling on Windows or narrow the comment to the non-Windows (1DS) provider.
Keep 1DS configuration and manager ownership local until logger setup and context decoration complete. Any early return or exception now releases the pending manager before its configuration is destroyed, leaving global telemetry state empty and retryable. Files changed: - onnxruntime/core/platform/posix/telemetry.cc: guard and atomically publish fully initialized SDK state. - onnxruntime/test/platform/telemetry_redaction_test.cc: remove the duplicated word reported in review. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
A Windows environment value can grow between the size query and read. Retry with the returned required size so CI, unit-test, and POSIX opt-out detection do not silently treat a concurrently changed value as unset; also clarify that Windows ETW intentionally retains separate controls. Files changed: - onnxruntime/core/platform/telemetry_environment.h: retry resized values and correct platform-specific opt-out wording. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Report 0 when POSIX physical memory cannot be determined, matching Windows and OGA instead of emitting an invalid negative megabyte count. Files changed: - onnxruntime/core/platform/posix/telemetry.cc: use 0 as the total-memory failure sentinel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 59 out of 59 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
onnxruntime/core/platform/windows/telemetry.cc:265
- Telemetry suppression in CI appears inconsistent with the new cross-platform suppression policy. telemetry_environment.h documents CI-based suppression, and PosixTelemetry::Initialize() returns early when IsRunningInCI(), but WindowsTelemetry only checks IsRunningUnitTests(). This means a CI job that happens to have an ETW trace session could still record ORT events, contradicting the stated hard-suppression behavior.
Include the provider or extra symbol file path in duplicate-export failures so multi-file Android and provider builds identify the actionable input immediately. Files changed: - tools/ci_build/gen_def.py: add source-file context to both duplicate checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Bring in current generated operator documentation and upstream fixes without rewriting the reviewed branch history. Files changed: merge origin/main into bhamehta/posix-telemetry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
ORT_TELEMETRY_DISABLED implied a complete opt-out even though the provider still emits ProcessInfo. Rename it to ORT_MINIMAL_TELEMETRY and make detailed-versus-minimal state explicit so the environment and runtime controls match the documented behavior. Files changed: - docs/Privacy.md: describe complete build-time disable and runtime minimal mode. - onnxruntime/core/platform/telemetry_environment.h: expose the minimal-mode environment contract. - onnxruntime/core/platform/posix/telemetry.h: rename state around detailed and environment-selected minimal modes. - onnxruntime/core/platform/posix/telemetry.cc: apply and preserve explicit minimal-mode state. - onnxruntime/test/platform/telemetry_environment_test.cc: cover the renamed variable and mode precedence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Restore ORT_TELEMETRY_DISABLED and the prior telemetry state naming so Tianlei's full opt-out PR can be merged without conflicting with a parallel environment-variable redesign. Files changed: - docs/Privacy.md - onnxruntime/core/platform/telemetry_environment.h - onnxruntime/core/platform/posix/telemetry.h - onnxruntime/core/platform/posix/telemetry.cc - onnxruntime/test/platform/telemetry_environment_test.cc Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
### Description Makes `ORT_TELEMETRY_DISABLED` a **full** telemetry opt-out on the non-Windows (1DS) provider. Previously, setting the environment variable only flipped `enabled_ = false` while `Initialize()` still created the 1DS uploader, wrote the persistent device-id file to disk, and let `LogProcessInfo()` upload a one-shot `ProcessInfo` event (it only checked `logger_ != nullptr`, not `IsEnabled()`). So a user who explicitly opted out still got an on-disk identifier and a network upload. With this change, the env-var opt-out is treated like CI / unit-test suppression: the provider returns early before creating the uploader, so **nothing** is initialized, persisted, or sent. ### Key Changes | File | Change | |---|---| | `onnxruntime/core/platform/telemetry_environment.h` | `ShouldSuppressTelemetry()` now also returns true for `IsTelemetryDisabledByEnvVar()`, making it the single "collect nothing" gate. | | `onnxruntime/core/platform/posix/telemetry.cc` | `Initialize()` collapses the CI/unit-test and env-var checks into one early return on `ShouldSuppressTelemetry()`. When set, no `LogManager`/uploader is created, `DeviceId::GetValue()` is never called (no device-id file), and `LogProcessInfo()` returns early (no upload). `env_disabled_` is still latched so the runtime `EnableTelemetryEvents()` API cannot re-enable it. `LogProcessInfo()` comment updated. | | `docs/Privacy.md` | Documents the env-var as a full opt-out: no uploader, no init event, no persistent device id, latched for the process lifetime. | | `onnxruntime/test/platform/telemetry_environment_test.cc` | Adds assertions that `ShouldSuppressTelemetry()` is true when `ORT_TELEMETRY_DISABLED` is set. | ### Motivation and Context Addresses review feedback on #27379 (the "opt-out asymmetry" thread): an explicit `ORT_TELEMETRY_DISABLED=1` should leave no on-disk identifier and send nothing, rather than only suppressing usage events while still emitting an initialization heartbeat. The runtime API-based disable (`DisableTelemetryEvents()`) is unchanged and may still emit a minimal init event, matching the Windows ETW model. ### Testing - `TelemetryEnvironmentTest.EnvVarOptOut` now asserts full suppression via `ShouldSuppressTelemetry()`. - Verify on a non-Windows telemetry build that with `ORT_TELEMETRY_DISABLED=1`: no `onnxruntime.db`/`deviceid` file is created under the cache dir, and no `ProcessInfo` event is uploaded.
Rename the non-Windows full opt-out to ORT_DISABLE_TELEMETRY and replace partial-mode policy helpers with one process-lifetime suppression latch. This keeps uploader, events, and device identity disabled across ORT reinitialization while leaving the runtime API as the separate reversible control for non-essential events. Files changed: - docs/Privacy.md: distinguish full disable from runtime event suppression. - onnxruntime/core/platform/telemetry_environment.h: read ORT_DISABLE_TELEMETRY and remove obsolete policy helpers. - onnxruntime/core/platform/posix/telemetry.h: consolidate suppression state. - onnxruntime/core/platform/posix/telemetry.cc: latch all full-suppression reasons and simplify runtime enable behavior. - onnxruntime/test/platform/telemetry_environment_test.cc: cover the renamed full opt-out. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 59 out of 59 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
onnxruntime/core/platform/posix/telemetry.cc:225
- EventBuilder::AddStringMap serializes an std::unordered_map by iterating it directly, which makes the emitted string nondeterministic across runs. For telemetry, this can inflate cardinality and reduce aggregation usefulness for the same logical map contents. Consider sorting by key first to make the output stable.
// Helper for string map
EventBuilder& AddStringMap(const char* key, const std::unordered_map<std::string, std::string>& map) {
if (!map.empty()) {
std::string result;
bool first = true;
onnxruntime/core/platform/posix/telemetry.cc:240
- EventBuilder::AddBatchSizeDurations builds a string from an unordered_map, so the output order can change across runs for identical input. For telemetry aggregation/debugging it’s usually preferable to keep this deterministic (e.g., sort by batch size).
// Helper for batch size duration map
EventBuilder& AddBatchSizeDurations(const std::unordered_map<int64_t, long long>& durations) {
std::string result;
for (const auto& [batch_size, duration] : durations) {
if (!result.empty()) {
Sort map entries by key before converting them to string-valued telemetry fields so logically identical model metadata, opset maps, and batch durations do not produce different values from unordered-map iteration order. Files changed: - onnxruntime/core/platform/posix/telemetry.cc: share deterministic key ordering across all map serializers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Document that the initialization event may precede API-based suppression on every telemetry-enabled platform, while Windows ETW records events only when a trace session is collecting. Files changed: - docs/Privacy.md: align API-disable wording across POSIX and Windows telemetry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Use high-level language for the initialization event that may remain after API-based suppression. Files changed: - docs/Privacy.md: describe the remaining minimal initialization event concisely. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
State that the minimal initialization event may precede API-based telemetry suppression. Files changed: - docs/Privacy.md: preserve the initialization timing detail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Allow scrubbed telemetry strings, including error messages, to retain up to 2,000,000 bytes while preserving path redaction and UTF-8 boundary safety. Files changed: - onnxruntime/core/platform/telemetry_redaction.h: raise the shared scrubbed-string cap. - onnxruntime/test/platform/telemetry_redaction_test.cc: exercise truncation at the new boundary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Use the revised 40,960-byte cap while retaining path redaction and UTF-8-safe truncation. Files changed: - onnxruntime/core/platform/telemetry_redaction.h: set the scrubbed-string limit to 40,960 bytes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5a640c3d-b813-4671-84cf-ad98db91b480
Summary
Adds 1DS-backed telemetry to ONNX Runtime on Linux, macOS, Android, and iOS. Windows continues to use its existing ETW provider, with aligned metadata, redaction, and unit-test suppression. WebAssembly remains telemetry-free.
No public ABI is changed.
Behavior and controls
ProcessInfoevent plus low-frequency session, model, execution-provider, error, and aggregate runtime events.popSamplemetadata.RuntimePerf. POSIXEvaluationStart/EvaluationStopare no-ops, andSystemMetricsfollows theRuntimePerfcadence instead of running on every inference.--use_telemetry; directbuild.py/CMake builds can omit it completely.ORT_DISABLE_TELEMETRY=1is a full non-Windows opt-out when set before initialization: no uploader, events, persistent device identifier, or offline cache is created. The decision is latched for the process lifetime.Privacy, safety, and reliability
Build and package integration
cpp-client-telemetryvcpkg port when available, with a pinned FetchContent fallback.Performance
A Release benchmark using
mul_1.onnx, alternating enabled/disabled samples, CPU affinity, isolated caches, and blocked network showed that the original synchronous per-inference 1DS events were too expensive:Network upload remains asynchronous inside 1DS; this change removes serialized SDK intake from each successful
Run().Validation
ProcessInfo,SessionCreationStart,SessionCreation, andSessionCreationEnd, including shared process correlation and platform device identity.