Graphing Calculator Diagnostics Instrumentation (#1041)

* Add telemetry for keyboard button usage in graphing mode

* Added the diagnostics for EquationAdded and FunctionAnalysis

* Added remaining diagnostics events for graphing calculator

* Fix proj files to include the IsStoreBuild condition. Move the Delayer class to the Calculator/Utils folder

* Ensure the variable textbox has focus before logging diagnostics

* Move maxVariableCount check into the tracelogger class

* Created enums and updated the slider value changed method to remove the variable from the map after the log method is called

* Re-enable hidden lines when the expression is updated

* Fixed extra line in grapher.h and removed the conditional logging for variable count

* Updated logging per PR feedback

* Updated variable logging and fixed issues in the IsEquationLineDisabled binding the EditTextBox control.

* Update per PR feedback

* Added TraceLogging project to contain shared logging logic.

* Updated TraceLogging project and updated tracelogger classes to use the TraceLogging project methods

* Updated VariableLogging to log variable name. And updated per PR comments

* Updated Variables logging to log count changed instead of variable added and fixed issue with variableSliders not being initialized

* Remove outdated tracelogging call caused by rebase

* Updated Delayer class to DispatcherTimerDelayer and fixed some small formatting issues

* Fixed missing Dalyer class name updates

* Removed extra line in traceloger.h
This commit is contained in:
Stephanie Anderl
2020-03-12 14:05:47 -07:00
committed by GitHub
parent 4336c58105
commit 18a1f82035
42 changed files with 981 additions and 292 deletions

View File

@@ -314,7 +314,6 @@
<ClInclude Include="Common\NavCategory.h" />
<ClInclude Include="Common\NetworkManager.h" />
<ClInclude Include="Common\NumberBase.h" />
<ClInclude Include="Common\TraceActivity.h" />
<ClInclude Include="Common\TraceLogger.h" />
<ClInclude Include="Common\Utils.h" />
<ClInclude Include="DataLoaders\CurrencyDataLoader.h" />
@@ -383,6 +382,9 @@
<ProjectReference Include="..\GraphControl\GraphControl.vcxproj">
<Project>{e727a92b-f149-492c-8117-c039a298719b}</Project>
</ProjectReference>
<ProjectReference Include="..\TraceLogging\TraceLogging.vcxproj">
<Project>{fc81ff41-02cd-4cd9-9bc5-45a1e39ac6ed}</Project>
</ProjectReference>
</ItemGroup>
<ItemDefinitionGroup Condition="!Exists('DataLoaders\DataLoaderConstants.h')">
<ClCompile>

View File

@@ -169,9 +169,6 @@
<ClInclude Include="DataLoaders\UnitConverterDataLoader.h">
<Filter>DataLoaders</Filter>
</ClInclude>
<ClInclude Include="Common\TraceActivity.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="DataLoaders\DataLoaderMockConstants.h">
<Filter>DataLoaders</Filter>
</ClInclude>
@@ -200,7 +197,7 @@
<Filter>GraphingCalculator</Filter>
</ClInclude>
<ClInclude Include="Common\DelegateCommand.h">
<Filter>Common</Filter>
<Filter>Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

View File

@@ -202,6 +202,7 @@ public
GreaterThan,
GreaterThanOrEqualTo,
X,
Y
Y,
Submit
};
}

View File

@@ -1,55 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include <winmeta.h>
namespace CalculatorApp
{
// RAII wrapper that automatically sends the Stop event when the class gets destructed.
class TraceActivity
{
public:
TraceActivity()
: m_channel(nullptr)
, m_activity(nullptr)
, m_fields(nullptr)
{
}
TraceActivity(
winrt::Windows::Foundation::Diagnostics::LoggingChannel channel,
std::wstring_view activityName,
winrt::Windows::Foundation::Diagnostics::LoggingFields fields)
: m_channel(channel)
, m_activityName(activityName)
, m_fields(fields)
, m_activity(nullptr)
{
// Write the activity's START event. Note that you must not specify keyword
// or level for START and STOP events because they always use the activity's
// keyword and level.
m_activity = m_channel.StartActivity(
m_activityName,
m_fields,
winrt::Windows::Foundation::Diagnostics::LoggingLevel::Verbose,
winrt::Windows::Foundation::Diagnostics::LoggingOptions(WINEVENT_KEYWORD_RESPONSE_TIME));
}
~TraceActivity()
{
if (m_activity != nullptr)
{
// Write the activity's STOP event.
m_activity.StopActivity(m_activityName, m_fields);
m_activity = nullptr;
}
}
private:
std::wstring m_activityName;
winrt::Windows::Foundation::Diagnostics::LoggingChannel m_channel;
winrt::Windows::Foundation::Diagnostics::LoggingFields m_fields;
winrt::Windows::Foundation::Diagnostics::LoggingActivity m_activity;
};
}

View File

@@ -8,15 +8,15 @@
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace TraceLogging;
using namespace Concurrency;
using namespace std;
using namespace Platform;
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Diagnostics;
using namespace winrt::Windows::Globalization;
using namespace winrt::Windows::Globalization::DateTimeFormatting;
using namespace winrt::Windows::System::UserProfile;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Diagnostics;
using namespace Windows::Globalization;
using namespace Windows::Globalization::DateTimeFormatting;
using namespace Windows::System::UserProfile;
namespace CalculatorApp
{
@@ -35,36 +35,22 @@ namespace CalculatorApp
constexpr auto EVENT_NAME_VISUAL_STATE_CHANGED = L"VisualStateChanged";
constexpr auto EVENT_NAME_CONVERTER_INPUT_RECEIVED = L"ConverterInputReceived";
constexpr auto EVENT_NAME_INPUT_PASTED = L"InputPasted";
constexpr auto EVENT_NAME_SHOW_HIDE_BUTTON_CLICKED = L"ShowHideButtonClicked";
constexpr auto EVENT_NAME_GRAPH_BUTTON_CLICKED = L"GraphButtonClicked";
constexpr auto EVENT_NAME_GRAPH_LINE_STYLE_CHANGED = L"GraphLineStyleChanged";
constexpr auto EVENT_NAME_VARIABLE_CHANGED = L"VariableChanged";
constexpr auto EVENT_NAME_VARIABLE_SETTING_CHANGED = L"VariableSettingChanged";
constexpr auto EVENT_NAME_GRAPH_SETTINGS_CHANGED = L"GraphSettingsChanged";
constexpr auto EVENT_NAME_EXCEPTION = L"Exception";
constexpr auto PDT_PRIVACY_DATA_TAG = L"PartA_PrivTags";
constexpr auto PDT_PRODUCT_AND_SERVICE_USAGE = 0x0000'0000'0200'0000u;
#ifdef SEND_DIAGNOSTICS
// c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords
// c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords
constexpr int64_t MICROSOFT_KEYWORD_LEVEL_1 = 0x0000800000000000; // Bit 47
constexpr int64_t MICROSOFT_KEYWORD_LEVEL_2 = 0x0000400000000000; // Bit 46
constexpr int64_t MICROSOFT_KEYWORD_LEVEL_3 = 0x0000200000000000; // Bit 45
#else
// define all Keyword options as 0 when we do not want to upload app diagnostics
constexpr int64_t MICROSOFT_KEYWORD_LEVEL_1 = 0;
constexpr int64_t MICROSOFT_KEYWORD_LEVEL_2 = 0;
constexpr int64_t MICROSOFT_KEYWORD_LEVEL_3 = 0;
#endif
constexpr auto CALC_MODE = L"CalcMode";
constexpr auto GRAPHING_MODE = L"Graphing";
#pragma region TraceLogger setup and cleanup
TraceLogger::TraceLogger()
: g_calculatorProvider(
L"MicrosoftCalculator",
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }),
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 })
, // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
m_appLaunchActivity{ nullptr }
{
CoCreateGuid(&sessionGuid);
}
TraceLogger ^ TraceLogger::GetInstance()
@@ -73,33 +59,6 @@ namespace CalculatorApp
return s_selfInstance;
}
bool TraceLogger::GetTraceLoggingProviderEnabled()
{
return g_calculatorProvider.Enabled();
}
#pragma region Tracing methods
void TraceLogger::LogLevel1Event(wstring_view eventName, LoggingFields fields)
{
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_1));
}
void TraceLogger::LogLevel2Event(wstring_view eventName, LoggingFields fields)
{
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_2));
}
void TraceLogger::LogLevel3Event(wstring_view eventName, LoggingFields fields)
{
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_3));
}
unique_ptr<TraceActivity> TraceLogger::CreateTraceActivity(wstring_view eventName, LoggingFields fields)
{
return make_unique<TraceActivity>(g_calculatorProvider, eventName, fields);
}
#pragma endregion
// return true if windowId is logged once else return false
bool TraceLogger::IsWindowIdInLog(int windowId)
{
@@ -116,18 +75,12 @@ namespace CalculatorApp
void TraceLogger::LogVisualStateChanged(ViewMode mode, String ^ state, bool isAlwaysOnTop)
{
if (!GetTraceLoggingProviderEnabled())
{
return;
}
auto fields = ref new LoggingFields();
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"VisualState", state->Data());
fields.AddBoolean(L"IsAlwaysOnTop", isAlwaysOnTop);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_VISUAL_STATE_CHANGED, fields);
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddString(StringReference(L"VisualState"), state);
fields->AddBoolean(StringReference(L"IsAlwaysOnTop"), isAlwaysOnTop);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_VISUAL_STATE_CHANGED), fields);
}
void TraceLogger::LogWindowCreated(ViewMode mode, int windowId)
@@ -138,122 +91,69 @@ namespace CalculatorApp
windowIdLog.push_back(windowId);
}
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddUInt64(L"NumOfOpenWindows", currentWindowCount);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_WINDOW_ON_CREATED, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddUInt64(StringReference(L"NumOfOpenWindows"), currentWindowCount);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_WINDOW_ON_CREATED), fields);
}
void TraceLogger::LogModeChange(ViewMode mode)
{
if (!GetTraceLoggingProviderEnabled())
return;
if (NavCategory::IsValidViewMode(mode))
{
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_MODE_CHANGED, fields);
auto fields = ref new LoggingFields();
;
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_MODE_CHANGED), fields);
}
}
void TraceLogger::LogHistoryItemLoad(ViewMode mode, int historyListSize, int loadedIndex)
{
if (!GetTraceLoggingProviderEnabled())
{
return;
}
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddInt32(L"HistoryListSize", historyListSize);
fields.AddInt32(L"HistoryItemIndex", loadedIndex);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_HISTORY_ITEM_LOAD, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddInt32(StringReference(L"HistoryListSize"), historyListSize);
fields->AddInt32(StringReference(L"HistoryItemIndex"), loadedIndex);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_HISTORY_ITEM_LOAD), fields);
}
void TraceLogger::LogMemoryItemLoad(ViewMode mode, int memoryListSize, int loadedIndex)
{
if (!GetTraceLoggingProviderEnabled())
{
return;
}
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddInt32(L"MemoryListSize", memoryListSize);
fields.AddInt32(L"MemoryItemIndex", loadedIndex);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_MEMORY_ITEM_LOAD, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddInt32(StringReference(L"MemoryListSize"), memoryListSize);
fields->AddInt32(StringReference(L"MemoryItemIndex"), loadedIndex);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_MEMORY_ITEM_LOAD), fields);
}
void TraceLogger::LogError(ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString)
{
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"FunctionName", functionName->Data());
fields.AddString(L"Message", errorString->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddString(StringReference(L"FunctionName"), functionName);
fields->AddString(StringReference(L"Message"), errorString);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields);
}
void TraceLogger::LogStandardException(ViewMode mode, wstring_view functionName, const exception& e)
{
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"FunctionName", functionName);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddString(StringReference(L"FunctionName"), StringReference(functionName.data()));
wstringstream exceptionMessage;
exceptionMessage << e.what();
fields.AddString(L"Message", exceptionMessage.str());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
}
void TraceLogger::LogWinRTException(ViewMode mode, wstring_view functionName, hresult_error const& e)
{
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"FunctionName", functionName);
fields.AddString(L"Message", e.message());
fields.AddInt32(L"HRESULT", e.code());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
fields->AddString(StringReference(L"Message"), StringReference(exceptionMessage.str().data()));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields);
}
void TraceLogger::LogPlatformException(ViewMode mode, wstring_view functionName, Platform::Exception ^ e)
{
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"FunctionName", functionName);
fields.AddString(L"Message", e->Message->Data());
fields.AddInt32(L"HRESULT", e->HResult);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
fields->AddString(StringReference(L"FunctionName"), StringReference(functionName.data()));
fields->AddString(StringReference(L"Message"), e->Message);
fields->AddInt32(StringReference(L"HRESULT"), e->HResult);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields);
}
void TraceLogger::UpdateButtonUsage(NumbersAndOperatorsEnum button, ViewMode mode)
@@ -305,9 +205,6 @@ namespace CalculatorApp
void TraceLogger::LogButtonUsage()
{
if (!GetTraceLoggingProviderEnabled())
return;
// Writer lock for the buttonLog resource
reader_writer_lock::scoped_lock lock(s_traceLoggerLock);
@@ -330,11 +227,9 @@ namespace CalculatorApp
}
}
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"ButtonUsage", buttonUsageString->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_BUTTON_USAGE, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(L"ButtonUsage"), buttonUsageString);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_BUTTON_USAGE), fields);
buttonLog.clear();
}
@@ -342,46 +237,78 @@ namespace CalculatorApp
void TraceLogger::LogDateCalculationModeUsed(bool AddSubtractMode)
{
const wchar_t* calculationType = AddSubtractMode ? L"AddSubtractMode" : L"DateDifferenceMode";
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(ViewMode::Date)->Data());
fields.AddString(L"CalculationType", calculationType);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_DATE_CALCULATION_MODE_USED, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(ViewMode::Date));
fields->AddString(StringReference(L"CalculationType"), StringReference(calculationType));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_DATE_CALCULATION_MODE_USED), fields);
}
void TraceLogger::LogConverterInputReceived(ViewMode mode)
{
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_CONVERTER_INPUT_RECEIVED, fields);
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_CONVERTER_INPUT_RECEIVED), fields);
}
void TraceLogger::LogNavBarOpened()
{
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_NAV_BAR_OPENED, fields);
auto fields = ref new LoggingFields();
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_NAV_BAR_OPENED), fields);
}
void TraceLogger::LogInputPasted(ViewMode mode)
{
if (!GetTraceLoggingProviderEnabled())
return;
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_INPUT_PASTED), fields);
}
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_INPUT_PASTED, fields);
void TraceLogger::LogShowHideButtonClicked(bool isHideButton)
{
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
fields->AddBoolean(StringReference(L"IsHideButton"), isHideButton);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_SHOW_HIDE_BUTTON_CLICKED), fields);
}
void TraceLogger::LogGraphButtonClicked(GraphButton buttonName)
{
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
fields->AddInt16(StringReference(L"ButtonName"), static_cast<int16>(buttonName));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_GRAPH_BUTTON_CLICKED), fields);
}
void TraceLogger::LogGraphLineStyleChanged(LineStyleType style)
{
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
fields->AddInt16(StringReference(L"StyleType"), static_cast<int16>(style));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_GRAPH_LINE_STYLE_CHANGED), fields);
}
void TraceLogger::LogVariableChanged(String ^ inputChangedType, String ^ variableName)
{
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
fields->AddString(StringReference(L"InputChangedType"), inputChangedType);
fields->AddString(StringReference(L"VariableName"), variableName);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_VARIABLE_CHANGED), fields);
}
void TraceLogger::LogVariableSettingsChanged(String ^ setting)
{
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
fields->AddString(StringReference(L"SettingChanged"), setting);
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_VARIABLE_SETTING_CHANGED), fields);
}
void TraceLogger::LogGraphSettingsChanged(GraphSettingsType settingType)
{
auto fields = ref new LoggingFields();
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
fields->AddInt16(L"SettingType", static_cast<int16>(settingType));
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_GRAPH_SETTINGS_CHANGED), fields);
}
}

View File

@@ -3,13 +3,9 @@
#pragma once
#include "CalcManager/Command.h"
#include "TraceActivity.h"
#include "NavCategory.h"
#include "CalculatorButtonUser.h"
static const int maxFunctionSize = (int)CalculationManager::Command::CommandBINEDITEND;
// A trace logging provider can only be instantiated and registered once per module.
// This class implements a singleton model ensure that only one instance is created.
namespace CalculatorApp
@@ -28,12 +24,35 @@ namespace CalculatorApp
}
};
public
ref class TraceLogger sealed
public enum class GraphSettingsType
{
Grid,
TrigUnits
};
public enum class GraphButton
{
StylePicker,
RemoveFunction,
ActiveTracingChecked,
ActiveTracingUnchecked,
GraphSettings,
Share,
ZoomIn,
ZoomOut,
ZoomReset
};
public enum class LineStyleType
{
Color
};
public ref class TraceLogger sealed
{
public:
static TraceLogger ^ GetInstance();
bool GetTraceLoggingProviderEnabled();
void LogModeChange(CalculatorApp::Common::ViewMode mode);
void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex);
void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex);
@@ -48,9 +67,14 @@ public
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode);
void LogNavBarOpened();
void LogError(CalculatorApp::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString);
internal :
void LogShowHideButtonClicked(bool isHideButton);
void LogGraphButtonClicked(GraphButton buttonName);
void LogGraphLineStyleChanged(LineStyleType style);
void LogVariableChanged(Platform::String ^ inputChangedType, Platform::String ^ variableName);
void LogVariableSettingsChanged(Platform::String ^ setting);
void LogGraphSettingsChanged(GraphSettingsType settingsType);
internal:
void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e);
void LogWinRTException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ winrt::hresult_error const& e);
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e);
void LogInputPasted(CalculatorApp::Common::ViewMode mode);
@@ -58,24 +82,8 @@ public
// Create an instance of TraceLogger
TraceLogger();
// As mentioned in Microsoft's Privacy Statement(https://privacy.microsoft.com/en-US/privacystatement#maindiagnosticsmodule),
// sampling is involved in Microsoft's diagnostic data collection process.
// These keywords provide additional input into how frequently an event might be sampled.
// The lower the level of the keyword, the higher the possibility that the corresponding event may be sampled.
void LogLevel1Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
void LogLevel2Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
void LogLevel3Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
std::unique_ptr<TraceActivity> CreateTraceActivity(std::wstring_view activityName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
winrt::Windows::Foundation::Diagnostics::LoggingChannel g_calculatorProvider;
std::vector<ButtonLog> buttonLog;
std::vector<int> windowIdLog;
GUID sessionGuid;
uint64 currentWindowCount = 0;
winrt::Windows::Foundation::Diagnostics::LoggingActivity m_appLaunchActivity;
};
}

View File

@@ -99,6 +99,8 @@ void GraphingSettingsViewModel::UpdateDisplayRange()
}
m_Graph->SetDisplayRanges(m_XMinValue, m_XMaxValue, m_YMinValue, m_YMaxValue);
TraceLogger::GetInstance()->LogGraphSettingsChanged(GraphSettingsType::Grid);
}
bool GraphingSettingsViewModel::HasError()

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT License.
#include "../Common/Utils.h"
#include "CalcViewModel/Common/TraceLogger.h"
namespace CalculatorApp::ViewModel
{
@@ -226,9 +227,12 @@ namespace CalculatorApp::ViewModel
if (value && m_Graph != nullptr && m_Graph->TrigUnitMode != (int)Graphing::EvalTrigUnitMode::Radians)
{
m_Graph->TrigUnitMode = (int)Graphing::EvalTrigUnitMode::Radians;
RaisePropertyChanged(L"TrigModeRadians");
RaisePropertyChanged(L"TrigModeDegrees");
RaisePropertyChanged(L"TrigModeGradians");
TraceLogger::GetInstance()->LogGraphSettingsChanged(GraphSettingsType::TrigUnits);
}
}
}
@@ -244,9 +248,12 @@ namespace CalculatorApp::ViewModel
if (value && m_Graph != nullptr && m_Graph->TrigUnitMode != (int)Graphing::EvalTrigUnitMode::Degrees)
{
m_Graph->TrigUnitMode = (int)Graphing::EvalTrigUnitMode::Degrees;
RaisePropertyChanged(L"TrigModeDegrees");
RaisePropertyChanged(L"TrigModeRadians");
RaisePropertyChanged(L"TrigModeGradians");
TraceLogger::GetInstance()->LogGraphSettingsChanged(GraphSettingsType::TrigUnits);
}
}
}
@@ -262,9 +269,12 @@ namespace CalculatorApp::ViewModel
if (value && m_Graph != nullptr && m_Graph->TrigUnitMode != (int)Graphing::EvalTrigUnitMode::Grads)
{
m_Graph->TrigUnitMode = (int)Graphing::EvalTrigUnitMode::Grads;
RaisePropertyChanged(L"TrigModeGradians");
RaisePropertyChanged(L"TrigModeDegrees");
RaisePropertyChanged(L"TrigModeRadians");
TraceLogger::GetInstance()->LogGraphSettingsChanged(GraphSettingsType::TrigUnits);
}
}
}