winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }