diff --git a/onnxruntime/core/platform/telemetry.cc b/onnxruntime/core/platform/telemetry.cc index 2008f998384a3..20ec11bf7deb2 100644 --- a/onnxruntime/core/platform/telemetry.cc +++ b/onnxruntime/core/platform/telemetry.cc @@ -64,6 +64,7 @@ void Telemetry::LogSessionCreation(uint32_t session_id, int64_t ir_version, cons const std::string& loadedFrom, const std::vector& execution_provider_ids, const std::string& hardware_device_types, const std::string& hardware_vendor_ids, + const std::string& ep_versions, bool use_fp16, bool captureState) const { ORT_UNUSED_PARAMETER(session_id); ORT_UNUSED_PARAMETER(ir_version); @@ -81,6 +82,7 @@ void Telemetry::LogSessionCreation(uint32_t session_id, int64_t ir_version, cons ORT_UNUSED_PARAMETER(execution_provider_ids); ORT_UNUSED_PARAMETER(hardware_device_types); ORT_UNUSED_PARAMETER(hardware_vendor_ids); + ORT_UNUSED_PARAMETER(ep_versions); ORT_UNUSED_PARAMETER(use_fp16); ORT_UNUSED_PARAMETER(captureState); } @@ -124,6 +126,15 @@ void Telemetry::LogRuntimeError(uint32_t session_id, const common::Status& statu ORT_UNUSED_PARAMETER(line); } +void Telemetry::LogRuntimeInferenceError(uint32_t session_id, const common::Status& status, + const std::string& ep_versions, + const std::string& ep_device_types) const { + ORT_UNUSED_PARAMETER(session_id); + ORT_UNUSED_PARAMETER(status); + ORT_UNUSED_PARAMETER(ep_versions); + ORT_UNUSED_PARAMETER(ep_device_types); +} + void Telemetry::LogRuntimePerf(uint32_t session_id, uint32_t total_runs_since_last, int64_t total_run_duration_since_last, const std::unordered_map& duration_per_batch_size) const { ORT_UNUSED_PARAMETER(session_id); @@ -139,6 +150,7 @@ void Telemetry::LogEpDeviceUsage(uint32_t session_id, uint32_t hardware_device_id, const std::string& hardware_vendor, const std::string& ep_vendor, + const std::string& ep_version, int assigned_node_count, uint32_t total_runs_since_last, int64_t total_run_duration_since_last) const { @@ -149,6 +161,7 @@ void Telemetry::LogEpDeviceUsage(uint32_t session_id, ORT_UNUSED_PARAMETER(hardware_device_id); ORT_UNUSED_PARAMETER(hardware_vendor); ORT_UNUSED_PARAMETER(ep_vendor); + ORT_UNUSED_PARAMETER(ep_version); ORT_UNUSED_PARAMETER(assigned_node_count); ORT_UNUSED_PARAMETER(total_runs_since_last); ORT_UNUSED_PARAMETER(total_run_duration_since_last); diff --git a/onnxruntime/core/platform/telemetry.h b/onnxruntime/core/platform/telemetry.h index c2dce68faa2dd..946e34ee35832 100644 --- a/onnxruntime/core/platform/telemetry.h +++ b/onnxruntime/core/platform/telemetry.h @@ -66,6 +66,7 @@ class Telemetry { const std::string& loadedFrom, const std::vector& execution_provider_ids, const std::string& hardware_device_types, const std::string& hardware_vendor_ids, + const std::string& ep_versions, bool use_fp16, bool captureState) const; virtual void LogCompileModelStart(uint32_t session_id, @@ -86,6 +87,10 @@ class Telemetry { virtual void LogRuntimeError(uint32_t session_id, const common::Status& status, const char* file, const char* function, uint32_t line) const; + virtual void LogRuntimeInferenceError(uint32_t session_id, const common::Status& status, + const std::string& ep_versions, + const std::string& ep_device_types) const; + virtual void LogRuntimePerf(uint32_t session_id, uint32_t total_runs_since_last, int64_t total_run_duration_since_last, const std::unordered_map& duration_per_batch_size) const; @@ -100,6 +105,7 @@ class Telemetry { uint32_t hardware_device_id, const std::string& hardware_vendor, const std::string& ep_vendor, + const std::string& ep_version, int assigned_node_count, uint32_t total_runs_since_last, int64_t total_run_duration_since_last) const; diff --git a/onnxruntime/core/platform/windows/telemetry.cc b/onnxruntime/core/platform/windows/telemetry.cc index 04b9aaa0eb8ed..342b937ffb656 100644 --- a/onnxruntime/core/platform/windows/telemetry.cc +++ b/onnxruntime/core/platform/windows/telemetry.cc @@ -285,6 +285,7 @@ void WindowsTelemetry::LogSessionCreationStart(uint32_t session_id) const { TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } @@ -318,6 +319,7 @@ void WindowsTelemetry::LogSessionCreation(uint32_t session_id, int64_t ir_versio const std::string& loaded_from, const std::vector& execution_provider_ids, const std::string& hardware_device_types, const std::string& hardware_vendor_ids, + const std::string& ep_versions, bool use_fp16, bool captureState) const { if (global_register_count_ == 0 || enabled_ == false) return; @@ -373,7 +375,8 @@ void WindowsTelemetry::LogSessionCreation(uint32_t session_id, int64_t ir_versio TraceLoggingLevel(WINEVENT_LEVEL_INFO), // Telemetry info // schemaVersion 1: added hardwareDeviceTypes and hardwareVendorIds - TraceLoggingUInt8(1, "schemaVersion"), + // schemaVersion 2: added executionProviderVersions + TraceLoggingUInt8(2, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingInt64(ir_version, "irVersion"), TraceLoggingUInt32(projection_, "OrtProgrammingProjection"), @@ -392,6 +395,7 @@ void WindowsTelemetry::LogSessionCreation(uint32_t session_id, int64_t ir_versio TraceLoggingString(execution_provider_string.c_str(), "executionProviderIds"), TraceLoggingString(hardware_device_types.c_str(), "hardwareDeviceTypes"), TraceLoggingString(hardware_vendor_ids.c_str(), "hardwareVendorIds"), + TraceLoggingString(ep_versions.c_str(), "executionProviderVersions"), TraceLoggingString(service_names.c_str(), "serviceNames"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } else { @@ -404,7 +408,8 @@ void WindowsTelemetry::LogSessionCreation(uint32_t session_id, int64_t ir_versio TraceLoggingLevel(WINEVENT_LEVEL_INFO), // Telemetry info // schemaVersion 1: added hardwareDeviceTypes and hardwareVendorIds - TraceLoggingUInt8(1, "schemaVersion"), + // schemaVersion 2: added executionProviderVersions + TraceLoggingUInt8(2, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingInt64(ir_version, "irVersion"), TraceLoggingUInt32(projection_, "OrtProgrammingProjection"), @@ -423,6 +428,7 @@ void WindowsTelemetry::LogSessionCreation(uint32_t session_id, int64_t ir_versio TraceLoggingString(execution_provider_string.c_str(), "executionProviderIds"), TraceLoggingString(hardware_device_types.c_str(), "hardwareDeviceTypes"), TraceLoggingString(hardware_vendor_ids.c_str(), "hardwareVendorIds"), + TraceLoggingString(ep_versions.c_str(), "executionProviderVersions"), TraceLoggingString(service_names.c_str(), "serviceNames"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } @@ -457,7 +463,7 @@ void WindowsTelemetry::LogCompileModelStart(uint32_t session_id, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TraceLoggingLevel(WINEVENT_LEVEL_INFO), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingString(input_source.c_str(), "inputSource"), TraceLoggingString(output_target.c_str(), "outputTarget"), @@ -466,6 +472,7 @@ void WindowsTelemetry::LogCompileModelStart(uint32_t session_id, TraceLoggingBool(embed_ep_context, "embedEpContext"), TraceLoggingBool(has_external_initializers_file, "hasExternalInitializersFile"), TraceLoggingString(execution_provider_string.c_str(), "executionProviderIds"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } @@ -507,7 +514,7 @@ void WindowsTelemetry::LogRuntimeError(uint32_t session_id, const common::Status TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingHResult(hr, "hResult"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingUInt32(status.Code(), "errorCode"), @@ -516,6 +523,7 @@ void WindowsTelemetry::LogRuntimeError(uint32_t session_id, const common::Status TraceLoggingString(file, "file"), TraceLoggingString(function, "function"), TraceLoggingInt32(line, "line"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); #else TraceLoggingWrite(telemetry_provider_handle, @@ -525,7 +533,7 @@ void WindowsTelemetry::LogRuntimeError(uint32_t session_id, const common::Status TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingUInt32(status.Code(), "errorCode"), TraceLoggingUInt32(status.Category(), "errorCategory"), @@ -533,10 +541,35 @@ void WindowsTelemetry::LogRuntimeError(uint32_t session_id, const common::Status TraceLoggingString(file, "file"), TraceLoggingString(function, "function"), TraceLoggingInt32(line, "line"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); #endif } +void WindowsTelemetry::LogRuntimeInferenceError(uint32_t session_id, const common::Status& status, + const std::string& ep_versions, + const std::string& ep_device_types) const { + if (global_register_count_ == 0 || enabled_ == false) + return; + + TraceLoggingWrite(telemetry_provider_handle, + "RuntimeInferenceError", + TraceLoggingBool(true, "UTCReplace_AppSessionGuid"), + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TraceLoggingLevel(WINEVENT_LEVEL_ERROR), + // Telemetry info + TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt32(session_id, "sessionId"), + TraceLoggingUInt32(status.Code(), "errorCode"), + TraceLoggingUInt32(status.Category(), "errorCategory"), + TraceLoggingString(status.ErrorMessage().c_str(), "errorMessage"), + TraceLoggingString(ep_versions.c_str(), "executionProviderVersions"), + TraceLoggingString(ep_device_types.c_str(), "executionProviderDeviceTypes"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), + TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); +} + void WindowsTelemetry::LogRuntimePerf(uint32_t session_id, uint32_t total_runs_since_last, int64_t total_run_duration_since_last, const std::unordered_map& duration_per_batch_size) const { if (global_register_count_ == 0 || enabled_ == false) @@ -559,11 +592,12 @@ void WindowsTelemetry::LogRuntimePerf(uint32_t session_id, uint32_t total_runs_s TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingUInt32(total_runs_since_last, "totalRuns"), TraceLoggingInt64(total_run_duration_since_last, "totalRunDuration"), TraceLoggingString(total_duration_per_batch_size.c_str(), "totalRunDurationPerBatchSize"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } @@ -574,6 +608,7 @@ void WindowsTelemetry::LogEpDeviceUsage(uint32_t session_id, uint32_t hardware_device_id, const std::string& hardware_vendor, const std::string& ep_vendor, + const std::string& ep_version, int assigned_node_count, uint32_t total_runs_since_last, int64_t total_run_duration_since_last) const { @@ -588,7 +623,8 @@ void WindowsTelemetry::LogEpDeviceUsage(uint32_t session_id, TraceLoggingKeyword(static_cast(onnxruntime::logging::ORTTraceLoggingKeyword::Session)), TraceLoggingLevel(WINEVENT_LEVEL_INFO), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + // schemaVersion 1: added epVersion, runtimeVersion + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), TraceLoggingString(ep_type.c_str(), "executionProviderType"), TraceLoggingString(hardware_device_type.c_str(), "hardwareDeviceType"), @@ -596,9 +632,11 @@ void WindowsTelemetry::LogEpDeviceUsage(uint32_t session_id, TraceLoggingUInt32(hardware_device_id, "hardwareDeviceId"), TraceLoggingString(hardware_vendor.c_str(), "hardwareVendor"), TraceLoggingString(ep_vendor.c_str(), "epVendor"), + TraceLoggingString(ep_version.c_str(), "epVersion"), TraceLoggingInt32(assigned_node_count, "assignedNodeCount"), TraceLoggingUInt32(total_runs_since_last, "totalRunsSinceLast"), TraceLoggingInt64(total_run_duration_since_last, "totalRunDurationSinceLast"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } @@ -724,8 +762,9 @@ void WindowsTelemetry::LogModelLoadStart(uint32_t session_id) const { TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TraceLoggingLevel(WINEVENT_LEVEL_INFO), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingUInt32(session_id, "sessionId"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } @@ -799,8 +838,9 @@ void WindowsTelemetry::LogRegisterEpLibraryStart(const std::string& registration TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TraceLoggingLevel(WINEVENT_LEVEL_INFO), // Telemetry info - TraceLoggingUInt8(0, "schemaVersion"), + TraceLoggingUInt8(1, "schemaVersion"), TraceLoggingString(registration_name.c_str(), "registrationName"), + TraceLoggingString(ORT_VERSION, "runtimeVersion"), TraceLoggingString(ORT_CALLER_FRAMEWORK, "frameworkName")); } diff --git a/onnxruntime/core/platform/windows/telemetry.h b/onnxruntime/core/platform/windows/telemetry.h index 8295d042d7ec9..46c262e1479d3 100644 --- a/onnxruntime/core/platform/windows/telemetry.h +++ b/onnxruntime/core/platform/windows/telemetry.h @@ -59,6 +59,7 @@ class WindowsTelemetry : public Telemetry { const std::string& loadedFrom, const std::vector& execution_provider_ids, const std::string& hardware_device_types, const std::string& hardware_vendor_ids, + const std::string& ep_versions, bool use_fp16, bool captureState) const override; void LogCompileModelStart(uint32_t session_id, @@ -79,6 +80,10 @@ class WindowsTelemetry : public Telemetry { void LogRuntimeError(uint32_t session_id, const common::Status& status, const char* file, const char* function, uint32_t line) const override; + void LogRuntimeInferenceError(uint32_t session_id, const common::Status& status, + const std::string& ep_versions, + const std::string& ep_device_types) const override; + void LogRuntimePerf(uint32_t session_id, uint32_t total_runs_since_last, int64_t total_run_duration_since_last, const std::unordered_map& duration_per_batch_size) const override; @@ -89,6 +94,7 @@ class WindowsTelemetry : public Telemetry { uint32_t hardware_device_id, const std::string& hardware_vendor, const std::string& ep_vendor, + const std::string& ep_version, int assigned_node_count, uint32_t total_runs_since_last, int64_t total_run_duration_since_last) const override; diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index bf21b300f07b6..ce2dc38dd0c26 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -78,6 +78,7 @@ #include "core/session/environment.h" #include "core/session/IOBinding.h" #include "core/session/inference_session_utils.h" +#include "core/session/onnxruntime_ep_device_ep_metadata_keys.h" #include "core/session/onnxruntime_session_options_config_keys.h" #include "core/session/onnxruntime_run_options_config_keys.h" #include "core/session/user_logging_sink.h" @@ -871,7 +872,7 @@ InferenceSession::~InferenceSession() { telemetry_provider.LogEpDeviceUsage( session_id_, ep_info.ep_type, ep_info.hardware_device_type, ep_info.vendor_id, ep_info.device_id, ep_info.vendor, ep_info.ep_vendor, - ep_info.assigned_node_count, + ep_info.ep_version, ep_info.assigned_node_count, telemetry_.total_runs_since_last_, telemetry_.total_run_duration_since_last_); } } @@ -2778,6 +2779,7 @@ common::Status InferenceSession::Initialize() { graph.DomainToVersionMap(), model_file_name, graph.Name(), model_weight_type, model_graph_hash, model_weight_hash, model_->MetaData(), telemetry_.event_name_, execution_providers_.GetIds(), telemetry_.ep_device_types_summary_, telemetry_.ep_device_vendor_ids_summary_, + telemetry_.ep_versions_summary_, model_has_fp16_inputs, false); // Emit one initial EpDeviceUsage event per (EP, device) pair with run counts of 0. @@ -2787,7 +2789,7 @@ common::Status InferenceSession::Initialize() { env.GetTelemetryProvider().LogEpDeviceUsage( session_id_, ep_info.ep_type, ep_info.hardware_device_type, ep_info.vendor_id, ep_info.device_id, ep_info.vendor, ep_info.ep_vendor, - ep_info.assigned_node_count, 0, 0); + ep_info.ep_version, ep_info.assigned_node_count, 0, 0); } LOGS(*session_logger_, INFO) << "Session successfully initialized."; @@ -3453,7 +3455,7 @@ Status InferenceSession::RunImpl(const RunOptions& run_options, env.GetTelemetryProvider().LogEpDeviceUsage( session_id_, ep_info.ep_type, ep_info.hardware_device_type, ep_info.vendor_id, ep_info.device_id, ep_info.vendor, ep_info.ep_vendor, - ep_info.assigned_node_count, + ep_info.ep_version, ep_info.assigned_node_count, telemetry_.total_runs_since_last_, telemetry_.total_run_duration_since_last_); } // reset counters @@ -3467,6 +3469,10 @@ Status InferenceSession::RunImpl(const RunOptions& run_options, Telemetry::kRuntimePerfMaxInterval); } } + } else { + // Log runtime error with EP versions + env.GetTelemetryProvider().LogRuntimeInferenceError(session_id_, retval, telemetry_.ep_versions_summary_, + telemetry_.ep_device_types_summary_); } // log evaluation stop to trace logging provider @@ -4072,6 +4078,7 @@ void InferenceSession::PopulateEpDeviceInfo(const onnxruntime::Graph& graph) { telemetry_.ep_device_info_.clear(); telemetry_.ep_device_types_summary_.clear(); telemetry_.ep_device_vendor_ids_summary_.clear(); + telemetry_.ep_versions_summary_.clear(); // First, count nodes assigned to each EP type after graph partitioning. // The graph node only carries the EP type string, so when a single EP targets @@ -4109,6 +4116,10 @@ void InferenceSession::PopulateEpDeviceInfo(const onnxruntime::Graph& graph) { Telemetry::EpDeviceInfo entry; entry.ep_type = ep_type; entry.ep_vendor = ep_device->ep_vendor; + auto it = ep_device->ep_metadata.Entries().find(kOrtEpDevice_EpMetadataKey_Version); + if (it != ep_device->ep_metadata.Entries().end()) { + entry.ep_version = it->second; + } if (ep_device->device != nullptr) { entry.hardware_device_type = HardwareDeviceTypeToString(ep_device->device->type); entry.vendor_id = ep_device->device->vendor_id; @@ -4143,11 +4154,13 @@ void InferenceSession::PopulateEpDeviceInfo(const onnxruntime::Graph& graph) { // by position against the existing executionProviderIds field. std::ostringstream types_oss; std::ostringstream vendor_ids_oss; + std::ostringstream versions_oss; bool first = true; for (const auto& entry : telemetry_.ep_device_info_) { if (!first) { types_oss << ','; vendor_ids_oss << ','; + versions_oss << ','; } first = false; types_oss << entry.hardware_device_type; @@ -4155,9 +4168,11 @@ void InferenceSession::PopulateEpDeviceInfo(const onnxruntime::Graph& graph) { vendor_ids_oss << "0x" << std::hex << std::uppercase << std::setw(4) << std::setfill('0') << entry.vendor_id << std::dec << std::nouppercase << std::setfill(' '); + versions_oss << entry.ep_type << ':' << entry.ep_version; } telemetry_.ep_device_types_summary_ = types_oss.str(); telemetry_.ep_device_vendor_ids_summary_ = vendor_ids_oss.str(); + telemetry_.ep_versions_summary_ = versions_oss.str(); } #if !defined(ORT_MINIMAL_BUILD) @@ -4404,6 +4419,7 @@ void InferenceSession::LogAllSessions() { graph.DomainToVersionMap(), model_file_name, graph.Name(), model_weight_type, model_graph_hash, model_weight_hash, model->MetaData(), session->telemetry_.event_name_, session->execution_providers_.GetIds(), session->telemetry_.ep_device_types_summary_, session->telemetry_.ep_device_vendor_ids_summary_, + session->telemetry_.ep_versions_summary_, model_has_fp16_inputs, true); } diff --git a/onnxruntime/core/session/inference_session.h b/onnxruntime/core/session/inference_session.h index 3d4256dbc2747..da2984ea96aa7 100644 --- a/onnxruntime/core/session/inference_session.h +++ b/onnxruntime/core/session/inference_session.h @@ -1017,12 +1017,14 @@ class InferenceSession { uint32_t device_id = 0; // PCI device ID (0 when unavailable) std::string vendor; // e.g. "Qualcomm" std::string ep_vendor; // e.g. "Qualcomm" (from OrtEpDevice) + std::string ep_version; // e.g. "1.2.3" (from OrtEpFactory::GetVersion, empty when unavailable) int assigned_node_count = 0; // # graph nodes assigned to this EP type }; std::vector ep_device_info_; // Pre-formatted comma-separated summaries used to enrich SessionCreation. std::string ep_device_types_summary_; // "NPU,CPU" std::string ep_device_vendor_ids_summary_; // "0x5143,0x0000" + std::string ep_versions_summary_; // "QNNExecutionProvider:1.2.3,CPUExecutionProvider:" } telemetry_; mutable std::mutex telemetry_mutex_; // to ensure thread-safe access to telemetry data