AppInstallerTelemetry.cpp (41684B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "Public/AppInstallerTelemetry.h" 5 #include "Public/AppInstallerLogging.h" 6 #include "Public/AppInstallerRuntime.h" 7 #include "Public/AppInstallerSHA256.h" 8 #include "Public/AppInstallerStrings.h" 9 #include "Public/winget/ThreadGlobals.h" 10 #include "winget/UserSettings.h" 11 12 #define AICLI_TraceLoggingStringView(_sv_,_name_) TraceLoggingCountedUtf8String(_sv_.data(), static_cast<ULONG>(_sv_.size()), _name_) 13 #define AICLI_TraceLoggingWStringView(_sv_,_name_) TraceLoggingCountedWideString(_sv_.data(), static_cast<ULONG>(_sv_.size()), _name_) 14 15 #define AICLI_TraceLoggingWriteActivity(_eventName_,...) TraceLoggingWriteActivity(\ 16 g_hTraceProvider,\ 17 _eventName_,\ 18 s_useGlobalTelemetryActivityId ? &s_globalTelemetryLoggerActivityId : GetActivityId(),\ 19 s_useGlobalTelemetryActivityId ? nullptr : GetParentActivityId(),\ 20 TraceLoggingCountedUtf8String(m_caller.c_str(), static_cast<ULONG>(m_caller.size()), "Caller"),\ 21 TraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast<ULONG>((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, "CvJson"),\ 22 __VA_ARGS__) 23 24 namespace AppInstaller::Logging 25 { 26 using namespace Utility; 27 28 namespace 29 { 30 // TODO: This and all usages should be removed after transition to summary event in back end. 31 static const uint32_t s_RootExecutionId = 0; 32 static std::atomic_uint32_t s_subExecutionId{ s_RootExecutionId }; 33 34 // Data that is needed by AnonymizeString 35 constexpr std::wstring_view s_UserProfileReplacement = L"%USERPROFILE%"sv; 36 37 // TODO: Temporary code to keep existing telemetry behavior 38 static bool s_useGlobalTelemetryActivityId = false; 39 static GUID s_globalTelemetryLoggerActivityId = GUID_NULL; 40 41 void __stdcall wilResultLoggingCallback(const wil::FailureInfo& info) noexcept 42 { 43 Telemetry().LogFailure(info); 44 } 45 46 FailureTypeEnum ConvertWilFailureTypeToFailureType(wil::FailureType failureType) 47 { 48 switch (failureType) 49 { 50 case wil::FailureType::Exception: 51 return FailureTypeEnum::ResultException; 52 case wil::FailureType::Return: 53 return FailureTypeEnum::ResultReturn; 54 case wil::FailureType::Log: 55 return FailureTypeEnum::ResultLog; 56 case wil::FailureType::FailFast: 57 return FailureTypeEnum::ResultFailFast; 58 default: 59 return FailureTypeEnum::Unknown; 60 } 61 } 62 63 std::string_view LogExceptionTypeToString(FailureTypeEnum exceptionType) 64 { 65 switch (exceptionType) 66 { 67 case FailureTypeEnum::ResultException: 68 return "wil::ResultException"sv; 69 case FailureTypeEnum::WinrtHResultError: 70 return "winrt::hresult_error"sv; 71 case FailureTypeEnum::ResourceOpen: 72 return "ResourceOpenException"sv; 73 case FailureTypeEnum::StdException: 74 return "std::exception"sv; 75 case FailureTypeEnum::Unknown: 76 default: 77 return "unknown"sv; 78 } 79 } 80 } 81 82 TelemetrySummary::TelemetrySummary(const TelemetrySummary& other) 83 { 84 this->IsCOMCall = other.IsCOMCall; 85 } 86 87 TelemetryTraceLogger::TelemetryTraceLogger(bool useSummary) : m_useSummary(useSummary) 88 { 89 std::ignore = CoCreateGuid(&m_activityId); 90 m_subExecutionId = s_RootExecutionId; 91 } 92 93 const GUID* TelemetryTraceLogger::GetActivityId() const 94 { 95 return &m_activityId; 96 } 97 98 const GUID* TelemetryTraceLogger::GetParentActivityId() const 99 { 100 return &m_parentActivityId; 101 } 102 103 bool TelemetryTraceLogger::DisableRuntime() 104 { 105 return m_isRuntimeEnabled.exchange(false); 106 } 107 108 void TelemetryTraceLogger::EnableRuntime() 109 { 110 m_isRuntimeEnabled = true; 111 } 112 113 void TelemetryTraceLogger::Initialize() 114 { 115 if (!m_isInitialized) 116 { 117 InitializeInternal(Settings::User()); 118 } 119 } 120 121 bool TelemetryTraceLogger::TryInitialize() 122 { 123 if (!m_isInitialized) 124 { 125 // Only initialize if we already have the user settings, so that we can respect the telemetry setting. 126 // We may not yet have the user settings if we are trying to report an error while reading them. 127 auto userSettings = Settings::TryGetUser(); 128 if (userSettings) 129 { 130 InitializeInternal(*userSettings); 131 } 132 } 133 134 return m_isInitialized; 135 } 136 137 void TelemetryTraceLogger::SetTelemetryCorrelationJson(const std::wstring_view jsonStr_view) noexcept 138 { 139 // Check if passed in string is a valid Json formatted before returning the value 140 // If invalid, return empty Json 141 Json::CharReaderBuilder jsonBuilder; 142 std::unique_ptr<Json::CharReader> jsonReader(jsonBuilder.newCharReader()); 143 std::unique_ptr<Json::Value> pJsonValue = std::make_unique<Json::Value>(); 144 std::string errors; 145 std::wstring jsonStrW{ jsonStr_view }; 146 std::string jsonStr = ConvertToUTF8(jsonStrW.c_str()); 147 148 bool result = jsonReader->parse(jsonStr.c_str(), 149 jsonStr.c_str() + jsonStr.size(), 150 pJsonValue.get(), 151 &errors); 152 153 if (result) 154 { 155 m_telemetryCorrelationJsonW = jsonStrW; 156 AICLI_LOG(Core, Info, << "Passed in Correlation Vector Json is valid: " << jsonStr); 157 } 158 else 159 { 160 AICLI_LOG(Core, Error, << "Passed in Correlation Vector Json is invalid: " << jsonStr << "; Error: " << errors); 161 } 162 } 163 164 void TelemetryTraceLogger::SetCaller(const std::string& caller) 165 { 166 auto callerUTF16 = Utility::ConvertToUTF16(caller); 167 auto anonCaller = AnonymizeString(callerUTF16); 168 m_caller = Utility::ConvertToUTF8(anonCaller); 169 } 170 171 void TelemetryTraceLogger::SetExecutionStage(uint32_t stage) noexcept 172 { 173 m_executionStage = stage; 174 } 175 176 std::unique_ptr<TelemetryTraceLogger> TelemetryTraceLogger::CreateSubTraceLogger() const 177 { 178 THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !this->m_isInitialized); 179 180 auto subTraceLogger = std::make_unique<TelemetryTraceLogger>(*this); 181 182 std::ignore = CoCreateGuid(&subTraceLogger->m_activityId); 183 subTraceLogger->m_parentActivityId = this->m_activityId; 184 subTraceLogger->m_subExecutionId = s_subExecutionId++; 185 186 return subTraceLogger; 187 } 188 189 void TelemetryTraceLogger::LogFailure(const wil::FailureInfo& failure) const noexcept 190 { 191 if (IsTelemetryEnabled()) 192 { 193 auto anonMessage = AnonymizeString(failure.pszMessage); 194 195 AICLI_TraceLoggingWriteActivity( 196 "FailureInfo", 197 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 198 TraceLoggingHResult(failure.hr, "HResult"), 199 AICLI_TraceLoggingWStringView(anonMessage, "Message"), 200 TraceLoggingString(failure.pszModule, "Module"), 201 TraceLoggingUInt32(failure.threadId, "ThreadId"), 202 TraceLoggingUInt32(static_cast<uint32_t>(failure.type), "Type"), 203 TraceLoggingString(failure.pszFile, "File"), 204 TraceLoggingUInt32(failure.uLineNumber, "Line"), 205 TraceLoggingUInt32(m_executionStage, "ExecutionStage"), 206 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 207 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 208 209 if (m_useSummary) 210 { 211 m_summary.FailureHResult = failure.hr; 212 m_summary.FailureMessage = anonMessage; 213 m_summary.FailureModule = StringOrEmptyIfNull(failure.pszModule); 214 m_summary.FailureThreadId = failure.threadId; 215 m_summary.FailureType = ConvertWilFailureTypeToFailureType(failure.type); 216 m_summary.FailureFile = StringOrEmptyIfNull(failure.pszFile); 217 m_summary.FailureLine = failure.uLineNumber; 218 } 219 } 220 221 // Also send failure to the log 222 AICLI_LOG(Fail, Error, << [&]() { 223 wchar_t message[2048]; 224 GetFailureLogString(message, ARRAYSIZE(message), failure); 225 return Utility::ConvertToUTF8(message); 226 }()); 227 } 228 229 void TelemetryTraceLogger::LogStartup(bool isCOMCall) const noexcept 230 { 231 LocIndString version = Runtime::GetClientVersion(); 232 LocIndString packageVersion; 233 if (Runtime::IsRunningInPackagedContext()) 234 { 235 packageVersion = Runtime::GetPackageVersion(); 236 } 237 238 if (IsTelemetryEnabled()) 239 { 240 AICLI_TraceLoggingWriteActivity( 241 "ClientVersion", 242 TraceLoggingBool(isCOMCall, "IsCOMCall"), 243 TraceLoggingCountedString(version->c_str(), static_cast<ULONG>(version->size()), "Version"), 244 TraceLoggingCountedString(packageVersion->c_str(), static_cast<ULONG>(packageVersion->size()), "PackageVersion"), 245 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 246 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 247 248 if (m_useSummary) 249 { 250 m_summary.IsCOMCall = isCOMCall; 251 } 252 } 253 254 AICLI_LOG(Core, Info, << "WinGet, version [" << version << "], activity [" << *GetActivityId() << ']'); 255 AICLI_LOG(Core, Info, << "OS: " << Runtime::GetOSVersion()); 256 AICLI_LOG(Core, Info, << "Command line Args: " << Utility::ConvertToUTF8(GetCommandLineW())); 257 if (Runtime::IsRunningInPackagedContext()) 258 { 259 AICLI_LOG(Core, Info, << "Package: " << packageVersion); 260 } 261 AICLI_LOG(Core, Info, << "IsCOMCall:" << isCOMCall << "; Caller: " << m_caller); 262 } 263 264 void TelemetryTraceLogger::LogCommand(std::string_view commandName) const noexcept 265 { 266 if (IsTelemetryEnabled()) 267 { 268 AICLI_TraceLoggingWriteActivity( 269 "CommandFound", 270 AICLI_TraceLoggingStringView(commandName, "Command"), 271 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage), 272 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 273 274 if (m_useSummary) 275 { 276 m_summary.Command = commandName; 277 } 278 } 279 280 AICLI_LOG(CLI, Info, << "Leaf command to execute: " << commandName); 281 } 282 283 void TelemetryTraceLogger::LogCommandSuccess(std::string_view commandName) const noexcept 284 { 285 if (IsTelemetryEnabled()) 286 { 287 AICLI_TraceLoggingWriteActivity( 288 "CommandSuccess", 289 AICLI_TraceLoggingStringView(commandName, "Command"), 290 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 291 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 292 293 if (m_useSummary) 294 { 295 m_summary.CommandSuccess = true; 296 } 297 } 298 299 AICLI_LOG(CLI, Info, << "Leaf command succeeded: " << commandName); 300 } 301 302 void TelemetryTraceLogger::LogCommandTermination(HRESULT hr, std::string_view file, size_t line) const noexcept 303 { 304 if (IsTelemetryEnabled()) 305 { 306 AICLI_TraceLoggingWriteActivity( 307 "CommandTermination", 308 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 309 TraceLoggingHResult(hr, "HResult"), 310 AICLI_TraceLoggingStringView(file, "File"), 311 TraceLoggingUInt64(static_cast<UINT64>(line), "Line"), 312 TraceLoggingUInt32(m_executionStage, "ExecutionStage"), 313 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 314 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 315 316 if (m_useSummary) 317 { 318 m_summary.FailureHResult = hr; 319 m_summary.FailureType = FailureTypeEnum::CommandTermination; 320 m_summary.FailureFile = file; 321 m_summary.FailureLine = static_cast<UINT32>(line); 322 } 323 } 324 325 AICLI_LOG(CLI, Error, << "Terminating context: 0x" << SetHRFormat << hr << " at " << file << ":" << line); 326 } 327 328 void TelemetryTraceLogger::LogException(FailureTypeEnum type, std::string_view message) const noexcept 329 { 330 auto exceptionTypeString = LogExceptionTypeToString(type); 331 332 if (IsTelemetryEnabled()) 333 { 334 auto anonMessage = AnonymizeString(Utility::ConvertToUTF16(message)); 335 336 AICLI_TraceLoggingWriteActivity( 337 "Exception", 338 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 339 AICLI_TraceLoggingStringView(exceptionTypeString, "Type"), 340 AICLI_TraceLoggingWStringView(anonMessage, "Message"), 341 TraceLoggingUInt32(m_executionStage, "ExecutionStage"), 342 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 343 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 344 345 if (m_useSummary) 346 { 347 m_summary.FailureType = type; 348 m_summary.FailureMessage = anonMessage; 349 } 350 } 351 352 AICLI_LOG(CLI, Error, << "Caught " << exceptionTypeString << ": " << message); 353 } 354 355 void TelemetryTraceLogger::LogIsManifestLocal(bool isLocalManifest) const noexcept 356 { 357 if (IsTelemetryEnabled()) 358 { 359 AICLI_TraceLoggingWriteActivity( 360 "GetManifest", 361 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 362 TraceLoggingBool(isLocalManifest, "IsManifestLocal"), 363 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 364 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 365 366 if (m_useSummary) 367 { 368 m_summary.IsManifestLocal = isLocalManifest; 369 } 370 } 371 } 372 373 void TelemetryTraceLogger::LogManifestFields(std::string_view id, std::string_view name, std::string_view version) const noexcept 374 { 375 if (IsTelemetryEnabled()) 376 { 377 AICLI_TraceLoggingWriteActivity( 378 "ManifestFields", 379 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 380 AICLI_TraceLoggingStringView(id, "Id"), 381 AICLI_TraceLoggingStringView(name, "Name"), 382 AICLI_TraceLoggingStringView(version, "Version"), 383 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 384 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 385 386 if (m_useSummary) 387 { 388 m_summary.PackageIdentifier = id; 389 m_summary.PackageName = name; 390 m_summary.PackageVersion = version; 391 } 392 } 393 394 AICLI_LOG(CLI, Info, << "Manifest fields: Name [" << name << "], Version [" << version << ']'); 395 } 396 397 void TelemetryTraceLogger::LogNoAppMatch() const noexcept 398 { 399 if (IsTelemetryEnabled()) 400 { 401 AICLI_TraceLoggingWriteActivity( 402 "NoAppMatch", 403 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 404 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 405 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 406 } 407 408 AICLI_LOG(CLI, Info, << "No app found matching input criteria"); 409 } 410 411 void TelemetryTraceLogger::LogMultiAppMatch() const noexcept 412 { 413 if (IsTelemetryEnabled()) 414 { 415 AICLI_TraceLoggingWriteActivity( 416 "MultiAppMatch", 417 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 418 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 419 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 420 } 421 422 AICLI_LOG(CLI, Info, << "Multiple apps found matching input criteria"); 423 } 424 425 void TelemetryTraceLogger::LogAppFound(std::string_view name, std::string_view id) const noexcept 426 { 427 if (IsTelemetryEnabled()) 428 { 429 AICLI_TraceLoggingWriteActivity( 430 "AppFound", 431 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 432 AICLI_TraceLoggingStringView(name, "Name"), 433 AICLI_TraceLoggingStringView(id, "Id"), 434 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 435 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 436 437 if (m_useSummary) 438 { 439 m_summary.PackageIdentifier = id; 440 m_summary.PackageName = name; 441 } 442 } 443 444 AICLI_LOG(CLI, Info, << "Found one app. App id: " << id << " App name: " << name); 445 } 446 447 void TelemetryTraceLogger::LogSelectedInstaller(int arch, std::string_view url, std::string_view installerType, std::string_view scope, std::string_view language) const noexcept 448 { 449 if (IsTelemetryEnabled()) 450 { 451 AICLI_TraceLoggingWriteActivity( 452 "SelectedInstaller", 453 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 454 TraceLoggingInt32(arch, "Arch"), 455 AICLI_TraceLoggingStringView(url, "Url"), 456 AICLI_TraceLoggingStringView(installerType, "InstallerType"), 457 AICLI_TraceLoggingStringView(scope, "Scope"), 458 AICLI_TraceLoggingStringView(language, "Language"), 459 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 460 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 461 462 if (m_useSummary) 463 { 464 m_summary.InstallerArchitecture = arch; 465 m_summary.InstallerUrl = url; 466 m_summary.InstallerType = installerType; 467 m_summary.InstallerScope = scope; 468 m_summary.InstallerLocale = language; 469 } 470 } 471 472 AICLI_LOG(CLI, Verbose, << "Completed installer selection."); 473 AICLI_LOG(CLI, Verbose, << "Selected installer Architecture: " << arch); 474 AICLI_LOG(CLI, Verbose, << "Selected installer URL: " << url); 475 AICLI_LOG(CLI, Verbose, << "Selected installer InstallerType: " << installerType); 476 AICLI_LOG(CLI, Verbose, << "Selected installer Scope: " << scope); 477 AICLI_LOG(CLI, Verbose, << "Selected installer Language: " << language); 478 } 479 480 void TelemetryTraceLogger::LogSearchRequest( 481 std::string_view type, 482 std::string_view query, 483 std::string_view id, 484 std::string_view name, 485 std::string_view moniker, 486 std::string_view tag, 487 std::string_view command, 488 size_t maximum, 489 std::string_view request) const noexcept 490 { 491 if (IsTelemetryEnabled()) 492 { 493 AICLI_TraceLoggingWriteActivity( 494 "SearchRequest", 495 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 496 AICLI_TraceLoggingStringView(type, "Type"), 497 AICLI_TraceLoggingStringView(query, "Query"), 498 AICLI_TraceLoggingStringView(id, "Id"), 499 AICLI_TraceLoggingStringView(name, "Name"), 500 AICLI_TraceLoggingStringView(moniker, "Moniker"), 501 AICLI_TraceLoggingStringView(tag, "Tag"), 502 AICLI_TraceLoggingStringView(command, "Command"), 503 TraceLoggingUInt64(static_cast<UINT64>(maximum), "Maximum"), 504 AICLI_TraceLoggingStringView(request, "Request"), 505 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 506 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 507 508 if (m_useSummary) 509 { 510 m_summary.SearchType = type; 511 m_summary.SearchQuery = query; 512 m_summary.SearchId = id; 513 m_summary.SearchName = name; 514 m_summary.SearchMoniker = moniker; 515 m_summary.SearchTag = tag; 516 m_summary.SearchCommand = command; 517 m_summary.SearchMaximum = static_cast<UINT64>(maximum); 518 m_summary.SearchRequest = request; 519 } 520 } 521 } 522 523 void TelemetryTraceLogger::LogSearchResultCount(uint64_t resultCount) const noexcept 524 { 525 if (IsTelemetryEnabled()) 526 { 527 AICLI_TraceLoggingWriteActivity( 528 "SearchResultCount", 529 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 530 TraceLoggingUInt64(resultCount, "ResultCount"), 531 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 532 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 533 534 if (m_useSummary) 535 { 536 m_summary.SearchResultCount = resultCount; 537 } 538 } 539 540 AICLI_LOG(CLI, Verbose, << "Search result size: " << resultCount); 541 } 542 543 void TelemetryTraceLogger::LogInstallerHashMismatch( 544 std::string_view id, 545 std::string_view version, 546 std::string_view channel, 547 const std::vector<uint8_t>& expected, 548 const std::vector<uint8_t>& actual, 549 bool overrideHashMismatch, 550 uint64_t downloadSizeInBytes, 551 const std::optional<std::string>& contentType) const noexcept 552 { 553 std::string actualContentType = contentType.value_or(std::string{}); 554 555 if (IsTelemetryEnabled()) 556 { 557 AICLI_TraceLoggingWriteActivity( 558 "HashMismatch", 559 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 560 AICLI_TraceLoggingStringView(id, "Id"), 561 AICLI_TraceLoggingStringView(version, "Version"), 562 AICLI_TraceLoggingStringView(channel, "Channel"), 563 TraceLoggingBinary(expected.data(), static_cast<ULONG>(expected.size()), "Expected"), 564 TraceLoggingBinary(actual.data(), static_cast<ULONG>(actual.size()), "Actual"), 565 TraceLoggingBool(overrideHashMismatch, "Override"), 566 TraceLoggingUInt64(downloadSizeInBytes, "ActualSize"), 567 AICLI_TraceLoggingStringView(actualContentType, "ContentType"), 568 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 569 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 570 571 if (m_useSummary) 572 { 573 m_summary.PackageIdentifier = id; 574 m_summary.PackageVersion = version; 575 m_summary.Channel = channel; 576 m_summary.HashMismatchExpected = expected; 577 m_summary.HashMismatchActual = actual; 578 m_summary.HashMismatchOverride = overrideHashMismatch; 579 m_summary.HashMismatchActualSize = downloadSizeInBytes; 580 m_summary.HashMismatchContentType = actualContentType; 581 } 582 } 583 584 AICLI_LOG(CLI, Error, 585 << "Package hash verification failed. SHA256 in manifest [" 586 << Utility::SHA256::ConvertToString(expected) 587 << "] does not match download [" 588 << Utility::SHA256::ConvertToString(actual) 589 << "] with file size [" << downloadSizeInBytes << "] and content type [" << actualContentType << "]"); 590 } 591 592 void TelemetryTraceLogger::LogInstallerFailure(std::string_view id, std::string_view version, std::string_view channel, std::string_view type, uint32_t errorCode) const noexcept 593 { 594 if (IsTelemetryEnabled()) 595 { 596 AICLI_TraceLoggingWriteActivity( 597 "InstallerFailure", 598 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 599 AICLI_TraceLoggingStringView(id, "Id"), 600 AICLI_TraceLoggingStringView(version, "Version"), 601 AICLI_TraceLoggingStringView(channel, "Channel"), 602 AICLI_TraceLoggingStringView(type, "Type"), 603 TraceLoggingUInt32(errorCode, "ErrorCode"), 604 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 605 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 606 607 if (m_useSummary) 608 { 609 m_summary.PackageIdentifier = id; 610 m_summary.PackageVersion = version; 611 m_summary.Channel = channel; 612 m_summary.InstallerExecutionType = type; 613 m_summary.InstallerErrorCode = errorCode; 614 } 615 } 616 617 AICLI_LOG(CLI, Error, << type << " installer failed: " << errorCode); 618 } 619 620 void TelemetryTraceLogger::LogUninstallerFailure(std::string_view id, std::string_view version, std::string_view type, uint32_t errorCode) const noexcept 621 { 622 if (IsTelemetryEnabled()) 623 { 624 AICLI_TraceLoggingWriteActivity( 625 "UninstallerFailure", 626 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 627 AICLI_TraceLoggingStringView(id, "Id"), 628 AICLI_TraceLoggingStringView(version, "Version"), 629 AICLI_TraceLoggingStringView(type, "Type"), 630 TraceLoggingUInt32(errorCode, "ErrorCode"), 631 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 632 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 633 634 if (m_useSummary) 635 { 636 m_summary.PackageIdentifier = id; 637 m_summary.PackageVersion = version; 638 m_summary.UninstallerExecutionType = type; 639 m_summary.UninstallerErrorCode = errorCode; 640 } 641 } 642 643 AICLI_LOG(CLI, Error, << type << " uninstaller failed: " << errorCode); 644 } 645 646 void TelemetryTraceLogger::LogSuccessfulInstallARPChange( 647 std::string_view sourceIdentifier, 648 std::string_view packageIdentifier, 649 std::string_view packageVersion, 650 std::string_view packageChannel, 651 size_t changesToARP, 652 size_t matchesInARP, 653 size_t countOfIntersectionOfChangesAndMatches, 654 std::string_view arpName, 655 std::string_view arpVersion, 656 std::string_view arpPublisher, 657 std::string_view arpLanguage) const noexcept 658 { 659 if (IsTelemetryEnabled()) 660 { 661 size_t languageNumber = 0xFFFF; 662 663 try 664 { 665 std::istringstream languageConversion{ std::string{ arpLanguage } }; 666 languageConversion >> languageNumber; 667 } 668 catch (...) {} 669 670 AICLI_TraceLoggingWriteActivity( 671 "InstallARPChange", 672 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 673 AICLI_TraceLoggingStringView(sourceIdentifier, "SourceIdentifier"), 674 AICLI_TraceLoggingStringView(packageIdentifier, "PackageIdentifier"), 675 AICLI_TraceLoggingStringView(packageVersion, "PackageVersion"), 676 AICLI_TraceLoggingStringView(packageChannel, "PackageChannel"), 677 TraceLoggingUInt64(static_cast<UINT64>(changesToARP), "ChangesToARP"), 678 TraceLoggingUInt64(static_cast<UINT64>(matchesInARP), "MatchesInARP"), 679 TraceLoggingUInt64(static_cast<UINT64>(countOfIntersectionOfChangesAndMatches), "ChangesThatMatch"), 680 AICLI_TraceLoggingStringView(arpName, "ARPName"), 681 AICLI_TraceLoggingStringView(arpVersion, "ARPVersion"), 682 AICLI_TraceLoggingStringView(arpPublisher, "ARPPublisher"), 683 TraceLoggingUInt64(static_cast<UINT64>(languageNumber), "ARPLanguage"), 684 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage | PDT_SoftwareSetupAndInventory), 685 TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); 686 687 if (m_useSummary) 688 { 689 m_summary.SourceIdentifier = sourceIdentifier; 690 m_summary.PackageIdentifier = packageIdentifier; 691 m_summary.PackageVersion = packageVersion; 692 m_summary.Channel = packageChannel; 693 m_summary.ChangesToARP = static_cast<UINT64>(changesToARP); 694 m_summary.MatchesInARP = static_cast<UINT64>(matchesInARP); 695 m_summary.ChangesThatMatch = static_cast<UINT64>(countOfIntersectionOfChangesAndMatches); 696 m_summary.ARPName = arpName; 697 m_summary.ARPVersion = arpVersion; 698 m_summary.ARPPublisher = arpPublisher; 699 m_summary.ARPLanguage = static_cast<UINT64>(languageNumber); 700 } 701 } 702 703 AICLI_LOG(CLI, Info, << "During package install, " << changesToARP << " changes to ARP were observed, " 704 << matchesInARP << " matches were found for the package, and " << countOfIntersectionOfChangesAndMatches << " packages were in both"); 705 706 if (arpName.empty()) 707 { 708 AICLI_LOG(CLI, Info, << "No single entry was determined to be associated with the package"); 709 } 710 else 711 { 712 AICLI_LOG(CLI, Info, << "The entry determined to be associated with the package is '" << arpName << "', with publisher '" << arpPublisher << "'"); 713 } 714 } 715 716 void TelemetryTraceLogger::LogNonFatalDOError(std::string_view url, HRESULT hr) const noexcept 717 { 718 if (IsTelemetryEnabled()) 719 { 720 AICLI_TraceLoggingWriteActivity( 721 "NonFatalDOError", 722 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 723 AICLI_TraceLoggingStringView(url, "Url"), 724 TraceLoggingHResult(hr, "HResult"), 725 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 726 TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); 727 728 if (m_useSummary) 729 { 730 m_summary.DOUrl = url; 731 m_summary.DOHResult = hr; 732 } 733 } 734 } 735 736 void TelemetryTraceLogger::LogRepairFailure(std::string_view id, std::string_view version, std::string_view type, uint32_t errorCode) const noexcept 737 { 738 if (IsTelemetryEnabled()) 739 { 740 AICLI_TraceLoggingWriteActivity( 741 "RepairFailure", 742 TraceLoggingUInt32(m_subExecutionId, "SubExecutionId"), 743 AICLI_TraceLoggingStringView(id, "Id"), 744 AICLI_TraceLoggingStringView(version, "Version"), 745 AICLI_TraceLoggingStringView(type, "Type"), 746 TraceLoggingUInt32(errorCode, "ErrorCode"), 747 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), 748 TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); 749 750 if (m_useSummary) 751 { 752 m_summary.PackageIdentifier = id; 753 m_summary.PackageVersion = version; 754 m_summary.RepairExecutionType = type; 755 m_summary.RepairErrorCode = errorCode; 756 757 } 758 } 759 760 AICLI_LOG(CLI, Error, << type << " repair failed: " << errorCode); 761 } 762 763 TelemetryTraceLogger::~TelemetryTraceLogger() 764 { 765 if (IsTelemetryEnabled()) 766 { 767 LocIndString version = Runtime::GetClientVersion(); 768 LocIndString packageVersion; 769 if (Runtime::IsRunningInPackagedContext()) 770 { 771 packageVersion = Runtime::GetPackageVersion(); 772 } 773 774 if (m_useSummary) 775 { 776 TraceLoggingWriteActivity( 777 g_hTraceProvider, 778 "SummaryV2", 779 GetActivityId(), 780 GetParentActivityId(), 781 // From member fields or program info. 782 AICLI_TraceLoggingStringView(m_caller, "Caller"), 783 TraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast<ULONG>((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, "CvJson"), 784 TraceLoggingCountedString(version->c_str(), static_cast<ULONG>(version->size()), "ClientVersion"), 785 TraceLoggingCountedString(packageVersion->c_str(), static_cast<ULONG>(packageVersion->size()), "ClientPackageVersion"), 786 TraceLoggingBool(Runtime::IsReleaseBuild(), "IsReleaseBuild"), 787 TraceLoggingUInt32(m_executionStage, "ExecutionStage"), 788 // From TelemetrySummary 789 TraceLoggingHResult(m_summary.FailureHResult, "FailureHResult"), 790 AICLI_TraceLoggingWStringView(m_summary.FailureMessage, "FailureMessage"), 791 AICLI_TraceLoggingStringView(m_summary.FailureModule, "FailureModule"), 792 TraceLoggingUInt32(m_summary.FailureThreadId, "FailureThreadId"), 793 TraceLoggingUInt32(static_cast<UINT32>(m_summary.FailureType), "FailureType"), 794 AICLI_TraceLoggingStringView(m_summary.FailureFile, "FailureFile"), 795 TraceLoggingUInt32(m_summary.FailureLine, "FailureLine"), 796 TraceLoggingBool(m_summary.IsCOMCall, "IsCOMCall"), 797 AICLI_TraceLoggingStringView(m_summary.Command, "Command"), 798 TraceLoggingBool(m_summary.CommandSuccess, "CommandSuccess"), 799 TraceLoggingBool(m_summary.IsManifestLocal, "IsManifestLocal"), 800 AICLI_TraceLoggingStringView(m_summary.PackageIdentifier, "PackageIdentifier"), 801 AICLI_TraceLoggingStringView(m_summary.PackageName, "PackageName"), 802 AICLI_TraceLoggingStringView(m_summary.PackageVersion, "PackageVersion"), 803 AICLI_TraceLoggingStringView(m_summary.Channel, "Channel"), 804 AICLI_TraceLoggingStringView(m_summary.SourceIdentifier, "SourceIdentifier"), 805 TraceLoggingInt32(m_summary.InstallerArchitecture, "InstallerArchitecture"), 806 AICLI_TraceLoggingStringView(m_summary.InstallerUrl, "InstallerUrl"), 807 AICLI_TraceLoggingStringView(m_summary.InstallerType, "InstallerType"), 808 AICLI_TraceLoggingStringView(m_summary.InstallerScope, "InstallerScope"), 809 AICLI_TraceLoggingStringView(m_summary.InstallerLocale, "InstallerLocale"), 810 AICLI_TraceLoggingStringView(m_summary.SearchType, "SearchType"), 811 AICLI_TraceLoggingStringView(m_summary.SearchQuery, "SearchQuery"), 812 AICLI_TraceLoggingStringView(m_summary.SearchId, "SearchId"), 813 AICLI_TraceLoggingStringView(m_summary.SearchName, "SearchName"), 814 AICLI_TraceLoggingStringView(m_summary.SearchMoniker, "SearchMoniker"), 815 AICLI_TraceLoggingStringView(m_summary.SearchTag, "SearchTag"), 816 AICLI_TraceLoggingStringView(m_summary.SearchCommand, "SearchCommand"), 817 TraceLoggingUInt64(m_summary.SearchMaximum, "SearchMaximum"), 818 AICLI_TraceLoggingStringView(m_summary.SearchRequest, "SearchRequest"), 819 TraceLoggingUInt64(m_summary.SearchResultCount, "SearchResultCount"), 820 TraceLoggingBinary(m_summary.HashMismatchExpected.data(), static_cast<ULONG>(m_summary.HashMismatchExpected.size()), "HashMismatchExpected"), 821 TraceLoggingBinary(m_summary.HashMismatchActual.data(), static_cast<ULONG>(m_summary.HashMismatchActual.size()), "HashMismatchActual"), 822 TraceLoggingBool(m_summary.HashMismatchOverride, "HashMismatchOverride"), 823 TraceLoggingUInt64(m_summary.HashMismatchActualSize, "HashMismatchActualSize"), 824 AICLI_TraceLoggingStringView(m_summary.HashMismatchContentType, "HashMismatchContentType"), 825 AICLI_TraceLoggingStringView(m_summary.InstallerExecutionType, "InstallerExecutionType"), 826 TraceLoggingUInt32(m_summary.InstallerErrorCode, "InstallerErrorCode"), 827 AICLI_TraceLoggingStringView(m_summary.UninstallerExecutionType, "UninstallerExecutionType"), 828 TraceLoggingUInt32(m_summary.UninstallerErrorCode, "UninstallerErrorCode"), 829 TraceLoggingUInt64(m_summary.ChangesToARP, "ChangesToARP"), 830 TraceLoggingUInt64(m_summary.MatchesInARP, "MatchesInARP"), 831 TraceLoggingUInt64(m_summary.ChangesThatMatch, "ChangesThatMatch"), 832 TraceLoggingUInt64(m_summary.ARPLanguage, "ARPLanguage"), 833 AICLI_TraceLoggingStringView(m_summary.ARPName, "ARPName"), 834 AICLI_TraceLoggingStringView(m_summary.ARPVersion, "ARPVersion"), 835 AICLI_TraceLoggingStringView(m_summary.ARPPublisher, "ARPPublisher"), 836 AICLI_TraceLoggingStringView(m_summary.DOUrl, "DOUrl"), 837 TraceLoggingHResult(m_summary.DOHResult, "DOHResult"), 838 AICLI_TraceLoggingStringView(m_summary.RepairExecutionType, "RepairExecutionType"), 839 TraceLoggingUInt32(m_summary.RepairErrorCode, "RepairErrorCode"), 840 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage | PDT_SoftwareSetupAndInventory), 841 TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); 842 } 843 } 844 } 845 846 bool TelemetryTraceLogger::IsTelemetryEnabled() const noexcept 847 { 848 return g_IsTelemetryProviderEnabled && m_isInitialized && m_isSettingEnabled && m_isRuntimeEnabled; 849 } 850 851 void TelemetryTraceLogger::InitializeInternal(const AppInstaller::Settings::UserSettings& userSettings) 852 { 853 m_isSettingEnabled = !userSettings.Get<Settings::Setting::TelemetryDisable>(); 854 m_isInitialized = true; 855 } 856 857 std::wstring TelemetryTraceLogger::AnonymizeString(const wchar_t* input) const noexcept 858 { 859 return input ? AnonymizeString(std::wstring_view{ input }) : std::wstring{}; 860 } 861 862 std::wstring TelemetryTraceLogger::AnonymizeString(std::wstring_view input) const noexcept try 863 { 864 // GetPathTo() may need to read the settings, so this function should only be called after settings are initialized. 865 // To ensure that, this function is only called when emitting an event, and we disable the telemetry until settings are ready. 866 static const std::wstring s_UserProfile = Runtime::GetPathTo(Runtime::PathName::UserProfile).wstring(); 867 868 return Utility::ReplaceWhileCopying(input, s_UserProfile, s_UserProfileReplacement); 869 } 870 catch (...) { return std::wstring{ input }; } 871 872 #ifndef AICLI_DISABLE_TEST_HOOKS 873 static std::shared_ptr<TelemetryTraceLogger> s_TelemetryTraceLogger_TestOverride; 874 #endif 875 876 TelemetryTraceLogger& Telemetry() 877 { 878 #ifndef AICLI_DISABLE_TEST_HOOKS 879 if (s_TelemetryTraceLogger_TestOverride) 880 { 881 return *s_TelemetryTraceLogger_TestOverride.get(); 882 } 883 #endif 884 ThreadLocalStorage::ThreadGlobals* pThreadGlobals = ThreadLocalStorage::ThreadGlobals::GetForCurrentThread(); 885 if (pThreadGlobals) 886 { 887 return *reinterpret_cast<TelemetryTraceLogger*>(pThreadGlobals->GetTelemetryObject()); 888 } 889 else 890 { 891 // For the global telemetry object, we may not have yet read the settings file. 892 // In that case, we will not be able to initialize it, so we need to try it 893 // each time we get the object. 894 static TelemetryTraceLogger processGlobalTelemetry(/* useSummary */ false); 895 processGlobalTelemetry.TryInitialize(); 896 return processGlobalTelemetry; 897 } 898 } 899 900 void EnableWilFailureTelemetry() 901 { 902 wil::SetResultLoggingCallback(wilResultLoggingCallback); 903 } 904 905 void UseGlobalTelemetryLoggerActivityIdOnly() 906 { 907 s_useGlobalTelemetryActivityId = true; 908 std::ignore = CoCreateGuid(&s_globalTelemetryLoggerActivityId); 909 } 910 911 DisableTelemetryScope::DisableTelemetryScope() 912 { 913 m_token = Telemetry().DisableRuntime(); 914 } 915 916 DisableTelemetryScope::~DisableTelemetryScope() 917 { 918 if (m_token) 919 { 920 Telemetry().EnableRuntime(); 921 } 922 } 923 924 #ifndef AICLI_DISABLE_TEST_HOOKS 925 // Replace this test hook with context telemetry when it gets moved over 926 void TestHook_SetTelemetryOverride(std::shared_ptr<TelemetryTraceLogger> ttl) 927 { 928 s_TelemetryTraceLogger_TestOverride = std::move(ttl); 929 } 930 #endif 931 }