diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/FastTrackFscmTelemetrySamples.sln b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/FastTrackFscmTelemetrySamples.sln
index 0502a9a..0480e88 100644
--- a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/FastTrackFscmTelemetrySamples.sln
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/FastTrackFscmTelemetrySamples.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.8.34322.80
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FC65038C-1B2F-41E1-A629-BED71D161FFF}") = "Order2Cash (USR) [FTApplicationInsightsTelemetry]", "Order2Cash\Order2Cash.rnrproj", "{A24B055C-A29A-4198-AA06-F62C9471F635}"
EndProject
+Project("{FC65038C-1B2F-41E1-A629-BED71D161FFF}") = "TelemetryExtensionExample (SYS) [Application Suite]", "TelemetryExtensionExample\TelemetryExtensionExample.rnrproj", "{7A2363FB-28BD-4203-BDDC-661CC58FBC68}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -12,6 +14,8 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A24B055C-A29A-4198-AA06-F62C9471F635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A24B055C-A29A-4198-AA06-F62C9471F635}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A2363FB-28BD-4203-BDDC-661CC58FBC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A2363FB-28BD-4203-BDDC-661CC58FBC68}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ApplicationInsights.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ApplicationInsights.png
new file mode 100644
index 0000000..64d4473
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ApplicationInsights.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ConcreteTelemetryClass.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ConcreteTelemetryClass.png
new file mode 100644
index 0000000..a3bf239
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ConcreteTelemetryClass.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/FineGrainedControlwithinTheTelemetryClass.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/FineGrainedControlwithinTheTelemetryClass.png
new file mode 100644
index 0000000..1d17f4a
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/FineGrainedControlwithinTheTelemetryClass.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/HowToDisableParticularTelemetry.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/HowToDisableParticularTelemetry.png
new file mode 100644
index 0000000..1069a1c
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/HowToDisableParticularTelemetry.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/LoggingTelemetry.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/LoggingTelemetry.png
new file mode 100644
index 0000000..a3ee249
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/LoggingTelemetry.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/MyTelemetryBase.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/MyTelemetryBase.png
new file mode 100644
index 0000000..2c6b6c7
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/MyTelemetryBase.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ProjectStructure.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ProjectStructure.png
new file mode 100644
index 0000000..83f22a9
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/ProjectStructure.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/RefreshAOT.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/RefreshAOT.png
new file mode 100644
index 0000000..9c6753a
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/RefreshAOT.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/TelemetryLogSettings.png b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/TelemetryLogSettings.png
new file mode 100644
index 0000000..3236758
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/ScreenShots/TelemetryLogSettings.png differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/TelemetryExtensionExample.rnrproj b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/TelemetryExtensionExample.rnrproj
new file mode 100644
index 0000000..6bb0b6a
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/TelemetryExtensionExample.rnrproj
@@ -0,0 +1,119 @@
+
+
+
+ Debug
+ AnyCPU
+ $(MSBuildProgramFiles32)\MSBuild\Microsoft\Dynamics\AX
+ Foundation
+ v4.6
+ bin
+ 2.0
+ True
+ False
+ False
+ False
+ {7a2363fb-28bd-4203-bddc-661cc58fbc68}
+ TelemetryExtensionExample
+ TelemetryExtensionExample
+ Class
+
+
+ Debug
+ False
+ False
+
+
+ initial
+ AnyCPU
+ False
+ False
+
+
+ true
+ false
+
+
+
+ Content
+ DMFDefinitionGroupExecutionHistory_Extension
+ DMFDefinitionGroupExecutionHistory_Extension
+
+
+ Content
+ MyApplicationInsightsEventIds
+ MyApplicationInsightsEventIds
+
+
+ Content
+ MyApplicationInsightsEventNames
+ MyApplicationInsightsEventNames
+
+
+ Content
+ MyApplicationInsightsEventProperties
+ MyApplicationInsightsEventProperties
+
+
+ Content
+ MyApplicationInsightsProperty
+ MyApplicationInsightsProperty
+
+
+ Content
+ MySysIntParametersFormEventHandler
+ MySysIntParametersFormEventHandler
+
+
+ Content
+ MyTelemetryBase
+ MyTelemetryBase
+
+
+ Content
+ TelemetryDataManagementImport
+ TelemetryDataManagementImport
+
+
+ Content
+ TelemetryPurchaseOrderConfirm
+ TelemetryPurchaseOrderConfirm
+
+
+ Content
+ TelemetrySalesOrderConfirm
+ TelemetrySalesOrderConfirm
+
+
+ Content
+ TelemetryShipConfirm
+ TelemetryShipConfirm
+
+
+ Content
+ WhsShipConfirm_Extension
+ WhsShipConfirm_Extension
+
+
+ Content
+ MyTelemetryClass
+ MyTelemetryClass
+
+
+ Content
+ MyTelemetrySeverityLevel
+ MyTelemetrySeverityLevel
+
+
+ Content
+ SysIntParameters.MyExtension
+ SysIntParameters.MyExtension
+
+
+ Content
+ MyTelemetryParameters
+ MyTelemetryParameters
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/DMFDefinitionGroupExecutionHistory_Extension.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/DMFDefinitionGroupExecutionHistory_Extension.xml
new file mode 100644
index 0000000..99483eb
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/DMFDefinitionGroupExecutionHistory_Extension.xml
@@ -0,0 +1,41 @@
+
+
+ DMFDefinitionGroupExecutionHistory_Extension
+
+
+/// DMFDefinitionGroupExecutionHistory_Extension Table extension
+///
+[ExtensionOf(tableStr(DMFDefinitionGroupExecutionHistory))]
+final class DMFDefinitionGroupExecutionHistory_Extension
+{
+}
+]]>
+
+
+ insertExecutionHistory
+
+ /// Insert execution history
+ ///
+ /// DMFDefinitionGroupExecution record
+ public void insertExecutionHistory(DMFDefinitionGroupExecution _definitionGroupExecution)
+ {
+ next insertExecutionHistory(_definitionGroupExecution);
+
+ DMFDefinitionGroupExecution dmfDefinitionGroupExecution = DMFDefinitionGroupExecution::find(_definitionGroupExecution.DefinitionGroup,_definitionGroupExecution.Entity,_definitionGroupExecution.ExecutionId);
+ DMFDefinitionGroupExecutionHistory dmfDefinitionGroupExecutionHistory = DMFDefinitionGroupExecutionHistory::find(dmfDefinitionGroupExecution.DefinitionGroup, dmfDefinitionGroupExecution.Entity,
+ dmfDefinitionGroupExecution.ExecutionId, dmfDefinitionGroupExecution.WriteStartDateTime, true);
+
+ // Add any other conditions to log only for the entities you want here.
+ if (dmfDefinitionGroupExecutionHistory.RecId)
+ {
+ new TelemetryDataManagementImport(dmfDefinitionGroupExecutionHistory.WriteStartDateTime, dmfDefinitionGroupExecutionHistory.WriteEndDateTime, dmfDefinitionGroupExecutionHistory).processEvent(MyApplicationInsightsEventNames::DMFDefinitionGroupExecutionHistory);
+ }
+ }
+
+]]>
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventIds.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventIds.xml
new file mode 100644
index 0000000..8d72f4c
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventIds.xml
@@ -0,0 +1,14 @@
+
+
+ MyApplicationInsightsEventIds
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventNames.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventNames.xml
new file mode 100644
index 0000000..6caf09e
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventNames.xml
@@ -0,0 +1,14 @@
+
+
+ MyApplicationInsightsEventNames
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventProperties.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventProperties.xml
new file mode 100644
index 0000000..28c25bf
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsEventProperties.xml
@@ -0,0 +1,38 @@
+
+
+ MyApplicationInsightsEventProperties
+
+
+/// The MyApplicationInsightsEventProperties class contains all available event properties that can be used in the Application Insights telemetry.
+///
+///
+/// The names must be unique.
+/// Please keep the list sorted alphabetically in ascending order.
+///
+internal static final class MyApplicationInsightsEventProperties
+{
+ internal static const str InventLocationId = 'inventLocationId';
+ internal static const str LoadId = 'loadId';
+ internal static const str LoadStatus = 'loadStatus';
+ internal static const str NumOfLines = 'numOfLines';
+ internal static const str SalesId = 'salesId';
+ internal static const str CustAccount = 'custAccount';
+ internal static const str SalesStatus = 'salesStatus';
+ internal static const str DeliveryDate = 'deliveryDate';
+ internal static const str PurchId = 'PurchId';
+ internal static const str VendorName = 'vendorName';
+ internal static const str PurchStatus = 'PurchStatus';
+ internal static const str ElapsedMilliseconds = 'ElapsedMilliseconds';
+ internal static const str DefinitionGroup = 'DefinitionGroup';
+ internal static const str Entity = 'Entity';
+ internal static const str ExecutionId = 'ExecutionId';
+ internal static const str NoOfRecords = 'NoOfRecords';
+ internal static const str NumOfTargetNew = 'NumOfTargetNew';
+ internal static const str NumOfTargetUpdated = 'NumOfTargetUpdated';
+
+}
+]]>
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsProperty.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsProperty.xml
new file mode 100644
index 0000000..2829035
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyApplicationInsightsProperty.xml
@@ -0,0 +1,42 @@
+
+
+ MyApplicationInsightsProperty
+
+
+/// Concrete class for Application Insights message payload properties.
+///
+public final class MyApplicationInsightsProperty extends SysApplicationInsightsProperty
+{
+ private str key;
+ private SysApplicationInsightsComplianceDataType dataType;
+
+}
+]]>
+
+
+ new
+
+
+
+ initialize
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MySysIntParametersFormEventHandler.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MySysIntParametersFormEventHandler.xml
new file mode 100644
index 0000000..c076b4d
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MySysIntParametersFormEventHandler.xml
@@ -0,0 +1,78 @@
+
+
+ MySysIntParametersFormEventHandler
+
+
+
+
+ SysIntParameters_OnInitializing
+
+///
+///
+///
+///
+[FormEventHandler(formStr(SysIntParameters), FormEventType::Initializing)]
+public static void SysIntParameters_OnInitializing(xFormRun sender, FormEventArgs e)
+ {
+
+ #define.ClassPath(@"\Classes\%1")
+
+ SysDictClass dictClass;
+ List extendedClassList;
+ ListEnumerator listEnumerator;
+ ClassName className;
+ // MethodName methodName;
+ ClassId childClass;
+ TreeNode childClassNode;
+ TreeNode methodNode;
+ int numberofMethods;
+ MyTelemetryParameters param;
+
+ //set parent class and method you want to investigate
+ className = classStr(MyTelemetryBase);
+ //methodName = "DefaultDimension";
+
+ dictClass = new SysDictClass(className2Id(classname));
+ extendedClassList = dictClass.extendedBy();
+
+ //loop through all child classes
+ if (extendedClassList.elements())
+ {
+ listEnumerator = extendedClassList.getEnumerator();
+
+ setprefix(strfmt("Class %1 extended by %2 classes.", className, int2str(extendedClassList.elements())));
+
+ while (listEnumerator.moveNext())
+ {
+ childClass = listEnumerator.current();
+ childClassNode = TreeNode::findNode(strFmt(#ClassPath, classId2Name(childClass)));
+
+ param = MyTelemetryParameters::find(childClassNode.AOTname());
+
+ if(!param)
+ {
+ ttsbegin;
+ param.clear();
+ param.TelemetryClass = childClassNode.AOTname();
+ param.IsEnabled = NoYes::Yes;
+ param.SeverityLevel = MyTelemetrySeverityLevel::Information;
+ param.insert();
+ ttscommit;
+ }
+
+ }
+
+ }
+
+}
+
+]]>
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyTelemetryBase.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyTelemetryBase.xml
new file mode 100644
index 0000000..da9fefa
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/MyTelemetryBase.xml
@@ -0,0 +1,461 @@
+
+
+ MyTelemetryBase
+
+
+/// MyTelemetryBase class
+///
+///
+
+ using DataContracts = Microsoft.ApplicationInsights.DataContracts;
+
+abstract class MyTelemetryBase
+{
+ protected Map basePropertyMap = new Map(Types::String, Types::string);
+ protected Map runtimePropertyMap = new Map(Types::String, Types::string);
+
+ System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
+
+ protected MyTelemetryParameters telemetryLoggingParams;
+ //you can fill this field or not, if you dont fill it, it will be set to 0
+ protected str eventId = "0";
+}
+]]>
+
+
+ new
+
+
+
+ telemetryName
+
+ /// Class telemetryName
+ ///
+ /// Telemetry
+ protected ClassName telemetryName()
+ {
+ return classId2Name(classIdGet(this));
+ }
+
+]]>
+
+
+ setElapsedMilliseconds
+
+
+
+ addBaseProperty
+
+
+
+ addRuntimeProperty
+
+
+
+ clearRuntimeProperties
+
+
+
+ shouldSkipLogging
+
+
+
+ shouldSkipOnSeverityLevel
+ severity)
+ return true;
+
+ return false;
+ }
+
+]]>
+
+
+ processMetric
+
+ /// Method ProcessMetric
+ ///
+ public final void processMetric(real _value)
+ {
+ try
+ {
+ this.logMetric(_value);
+ }
+ catch
+ {
+ warning(strFmt("Telemetry Metric Processing Error - className : %1",classId2Name(classIdGet(this))));
+ }
+ }
+
+]]>
+
+
+ processEvent
+
+ /// Method processEvent
+ ///
+ public final void processEvent(str _name)
+ {
+ try
+ {
+
+ if(this.shouldSkipLogging())
+ return;
+
+ if(!_name)
+ _name = this.telemetryName();
+
+ this.populateProperties();
+ this.logEvent(this.eventId, _name);
+ }
+ catch
+ {
+ warning(strFmt("Telemetry Event Processing Error: className : %1 - EventName: %2", classId2Name(classIdGet(this)), _name));
+ }
+ }
+
+]]>
+
+
+ processTrace
+
+ /// Method processTrace
+ ///
+ public final void processTrace(str traceMessage, MyTelemetrySeverityLevel severity = MyTelemetrySeverityLevel::Information)
+ {
+ try
+ {
+ if(this.shouldSkipLogging())
+ return;
+
+ if(this.shouldSkipOnSeverityLevel(severity))
+ return;
+
+ this.populateProperties();
+ this.logTrace(traceMessage, severity);
+ }
+ catch
+ {
+ warning(strFmt("Telemetry Trace Processing Error: className : %1 - TraceMessage: %2", classId2Name(classIdGet(this)), traceMessage));
+ }
+ }
+
+]]>
+
+
+ populateProperties
+
+ /// Method Populate properties. This housld be implemented by the concrete class that extends this base.
+ ///
+ protected abstract void populateProperties()
+ {
+ }
+
+]]>
+
+
+ metricName
+
+ /// Class metricName
+ ///
+ /// Telemetry
+ protected ClassName metricName()
+ {
+ return classId2Name(classIdGet(this));
+ }
+
+]]>
+
+
+ logMetric
+
+ ///
+ protected void logMetric(real _value)
+ {
+ SysApplicationInsightsTelemetryLogger::instance().trackMetric(this.metricName(), _value);
+ }
+
+]]>
+
+
+ logMetricWithDimensions
+
+ ///
+ protected void logMetricWithDimensions(real _value, str _dimension1Name, str _dimension1Value, str _dimension2Name = "", str _dimension2Value = '', str _dimension3Name = '', str _dimension3Value = '')
+ {
+ SysApplicationInsightsTelemetryLogger::instance().trackMetricWithDimensions(this.metricName(), _value, _dimension1Name, _dimension1Value, _dimension2Name, _dimension2Value, _dimension3Name, _dimension3Value);
+ }
+
+]]>
+
+
+ logEvent
+
+ /// Method Log
+ ///
+ protected void logEvent(str _eventId, str _name)
+ {
+ SysApplicationInsightsEventTelemetry eventTelemetry = SysApplicationInsightsEventTelemetry::newFromEventIdName(_eventId, _name);
+
+ MapIterator iterator;
+ str key, value;
+
+ // Get an iterator for the map
+ iterator = new MapIterator(basePropertyMap);
+
+ // Loop through the map & add base properties
+ while (iterator.more())
+ {
+ key = iterator.key();
+ value = iterator.value();
+
+ var property = new MyApplicationInsightsProperty(key, value, SysApplicationInsightsComplianceDataType::CustomerContent);
+ eventTelemetry.addProperty(property);
+ iterator.next();
+ }
+
+ //add runtime properties:
+ iterator = new MapIterator(runtimePropertyMap);
+
+ // Loop through the map & add base properties
+ while (iterator.more())
+ {
+ key = iterator.key();
+ value = iterator.value();
+
+ var property = new MyApplicationInsightsProperty(key, value, SysApplicationInsightsComplianceDataType::CustomerContent);
+ eventTelemetry.addProperty(property);
+ iterator.next();
+ }
+
+ SysApplicationInsightsTelemetryLogger::instance().trackEvent(eventTelemetry);
+ }
+
+]]>
+
+
+ shouldLogEvent
+
+
+
+ logTrace
+
+ /// Method Log
+ ///
+ protected void logTrace(str traceMessage, MyTelemetrySeverityLevel severity = MyTelemetrySeverityLevel::Information)
+ {
+ DataContracts.SeverityLevel dotNetSeverity;
+ switch(severity)
+ {
+ case MyTelemetrySeverityLevel::Critical:
+ dotNetSeverity = DataContracts.SeverityLevel::Critical;
+ break;
+ case MyTelemetrySeverityLevel::Error:
+ dotNetSeverity = DataContracts.SeverityLevel::Error;
+ break;
+ case MyTelemetrySeverityLevel::Warning:
+ dotNetSeverity = DataContracts.SeverityLevel::Warning;
+ break;
+ case MyTelemetrySeverityLevel::Information:
+ dotNetSeverity = DataContracts.SeverityLevel::Information;
+ break;
+ case MyTelemetrySeverityLevel::Verbose:
+ dotNetSeverity = DataContracts.SeverityLevel::Verbose;
+ break;
+ default:
+ dotNetSeverity = DataContracts.SeverityLevel::Information;
+ break;
+ }
+ SysApplicationInsightsTraceTelemetry traceTelemetry = SysApplicationInsightsTraceTelemetry::newFromEventIdName(traceMessage, dotNetSeverity);
+
+ MapIterator iterator;
+ str key, value;
+
+ // Get an iterator for the map
+ iterator = new MapIterator(basePropertyMap);
+
+ // Loop through the map & add base properties
+ while (iterator.more())
+ {
+ key = iterator.key();
+ value = iterator.value();
+
+ var property = new MyApplicationInsightsProperty(key, value, SysApplicationInsightsComplianceDataType::CustomerContent);
+ traceTelemetry.addProperty(property);
+ iterator.next();
+ }
+
+ //add runtime properties:
+ iterator = new MapIterator(runtimePropertyMap);
+
+ // Loop through the map & add base properties
+ while (iterator.more())
+ {
+ key = iterator.key();
+ value = iterator.value();
+
+ var property = new MyApplicationInsightsProperty(key, value, SysApplicationInsightsComplianceDataType::CustomerContent);
+ traceTelemetry.addProperty(property);
+ iterator.next();
+ }
+
+ SysApplicationInsightsTelemetryLogger::instance().trackTrace(traceTelemetry);
+ }
+
+]]>
+
+
+ logException
+
+ /// Method Log
+ ///
+ protected void logException(str message)
+ {
+ SysApplicationInsightsExceptionTelemetry exceptionTelemetry = SysApplicationInsightsExceptionTelemetry::newFromExceptionMessage(message);
+
+ MapIterator iterator;
+ str key, value;
+
+ // Get an iterator for the map
+ iterator = new MapIterator(basePropertyMap);
+
+ // Loop through the map & add base properties
+ while (iterator.more())
+ {
+ key = iterator.key();
+ value = iterator.value();
+
+ var property = new MyApplicationInsightsProperty(key, value, SysApplicationInsightsComplianceDataType::CustomerContent);
+ exceptionTelemetry.addProperty(property);
+ iterator.next();
+ }
+
+ //add runtime properties:
+ iterator = new MapIterator(runtimePropertyMap);
+
+ // Loop through the map & add base properties
+ while (iterator.more())
+ {
+ key = iterator.key();
+ value = iterator.value();
+
+ var property = new MyApplicationInsightsProperty(key, value, SysApplicationInsightsComplianceDataType::CustomerContent);
+ exceptionTelemetry.addProperty(property);
+ iterator.next();
+ }
+
+ SysApplicationInsightsTelemetryLogger::instance().trackException(exceptionTelemetry);
+ }
+
+]]>
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryDataManagementImport.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryDataManagementImport.xml
new file mode 100644
index 0000000..1dd6ef6
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryDataManagementImport.xml
@@ -0,0 +1,63 @@
+
+
+ TelemetryDataManagementImport
+
+
+/// TelemetryDataManagementImport class log monitoring and telemetry custom events/metrics
+///
+internal final class TelemetryDataManagementImport extends MyTelemetryBase
+{
+ private DMFDefinitionGroupExecutionHistory dmfDefinitionGroupExecutionHistory;
+ private TransDateTime executionStartTime;
+ private TransDateTime executionEndTime;
+}
+]]>
+
+
+ new
+
+
+
+ shouldLogEvent
+
+
+
+ populateProperties
+
+ /// populate telemetry entries to a map
+ ///
+ protected void populateProperties()
+ {
+ // We don't have to call the SetElapsedMilliSeconds() because we are getting the execution time from the table entry
+ // this.setElapsedMilliseconds();
+ this.addBaseProperty(MyApplicationInsightsEventProperties::ElapsedMilliseconds, int642Str(DateTimeUtil::getDifference(executionEndTime, executionStartTime)));
+ this.addBaseProperty(MyApplicationInsightsEventProperties::DefinitionGroup, dmfDefinitionGroupExecutionHistory.DefinitionGroup);
+ this.addBaseProperty(MyApplicationInsightsEventProperties::Entity, dmfDefinitionGroupExecutionHistory.Entity);
+ this.addBaseProperty(MyApplicationInsightsEventProperties::ExecutionId,dmfDefinitionGroupExecutionHistory.ExecutionId);
+ this.addBaseProperty(MyApplicationInsightsEventProperties::NoOfRecords, int2Str(dmfDefinitionGroupExecutionHistory.NoOfRecords));
+ this.addBaseProperty(MyApplicationInsightsEventProperties::NumOfTargetNew,int2Str(dmfDefinitionGroupExecutionHistory.NumOfTargetNew));
+ this.addBaseProperty(MyApplicationInsightsEventProperties::NumOfTargetUpdated, int2Str(dmfDefinitionGroupExecutionHistory.NumOfTargetUpdated));
+ }
+
+]]>
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryPurchaseOrderConfirm.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryPurchaseOrderConfirm.xml
new file mode 100644
index 0000000..83962f1
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryPurchaseOrderConfirm.xml
@@ -0,0 +1,53 @@
+
+
+ TelemetryPurchaseOrderConfirm
+
+
+/// TelemetryPurchaseOrderConfirm class extending methods of MyTelemetryBase class
+///
+final class TelemetryPurchaseOrderConfirm extends MyTelemetryBase
+{
+ private PurchTable purchTable;
+
+}
+]]>
+
+
+ new
+
+
+
+ shouldLogEvent
+
+
+
+ populateProperties
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetrySalesOrderConfirm.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetrySalesOrderConfirm.xml
new file mode 100644
index 0000000..eb39de2
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetrySalesOrderConfirm.xml
@@ -0,0 +1,61 @@
+
+
+ TelemetrySalesOrderConfirm
+
+
+/// TelemetrySalesOrderConfirm class extending methods of MyTelemetryBase class
+///
+final class TelemetrySalesOrderConfirm extends MyTelemetryBase
+{
+ private SalesTable salesTable;
+ private str error;
+}
+]]>
+
+
+ new
+
+
+
+ shouldLogEvent
+ MyTelemetrySeverityLevel::Information)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+]]>
+
+
+ populateProperties
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryShipConfirm.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryShipConfirm.xml
new file mode 100644
index 0000000..2bf09b9
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/TelemetryShipConfirm.xml
@@ -0,0 +1,59 @@
+
+
+ TelemetryShipConfirm
+
+
+/// TelemetryShipConfirm class extending methods of MyTelemetryBase class
+///
+final class TelemetryShipConfirm extends MyTelemetryBase
+{
+ private WHSLoadTable load;
+
+}
+]]>
+
+
+ new
+
+
+
+ shouldLogEvent
+
+
+
+ populateProperties
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/WhsShipConfirm_Extension.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/WhsShipConfirm_Extension.xml
new file mode 100644
index 0000000..dfffce8
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxClass/WhsShipConfirm_Extension.xml
@@ -0,0 +1,69 @@
+
+
+ WhsShipConfirm_Extension
+
+
+/// Extension for the class WhsShipConfirm .
+///
+[ExtensionOf(classStr(WhsShipConfirm))]
+final class WhsShipConfirm_Extension
+{
+}
+]]>
+
+
+ shipConfirm
+
+ /// Wrapper to WhsShipConfirm.shipConfirm(WHSLoadId loadId). Insert your logic around shipConfirm here.
+ ///
+ /// loadId value
+ public void shipConfirm(WHSLoadId loadId)
+ {
+ // Generate telemetry after the shipConfirm operation
+ WHSLoadTable loadTable = WHSLoadTable::find(loadId);
+ var telemetry = new TelemetryShipConfirm(loadTable);
+
+ try
+ {
+ // Call the original shipConfirm method
+ next shipConfirm(loadId);
+ }
+ catch (Exception::Deadlock)
+ {
+ retry;
+ }
+ catch (Exception::UpdateConflict)
+ {
+ if (appl.ttsLevel() == 0)
+ {
+ // Define the retry count globally.
+ var retryCount = 3;
+ if (xSession::currentRetryCount() >= retryCount)
+ {
+ throw Exception::UpdateConflictNotRecovered;
+ }
+ else
+ {
+ retry;
+ }
+ }
+ else
+ {
+ throw Exception::UpdateConflict;
+ }
+ }
+ catch (Exception::Error)
+ {
+ throw Exception::Error;
+ }
+
+ telemetry.processEvent(MyApplicationInsightsEventNames::WHSShipConfirm);
+ }
+
+]]>
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxEdt/MyTelemetryClass.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxEdt/MyTelemetryClass.xml
new file mode 100644
index 0000000..6c5874e
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxEdt/MyTelemetryClass.xml
@@ -0,0 +1,12 @@
+
+
+ MyTelemetryClass
+
+ MyTelemetryClass
+
+
+
+
+ 100
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxEnum/MyTelemetrySeverityLevel.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxEnum/MyTelemetrySeverityLevel.xml
new file mode 100644
index 0000000..5986d9a
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxEnum/MyTelemetrySeverityLevel.xml
@@ -0,0 +1,47 @@
+
+
+ MyTelemetrySeverityLevel
+
+ MyTelemetrySeverityLevelHelp
+
+
+ MyTelemetrySeverityLevel
+
+
+
+ Verbose
+
+ MyTelemetrySeverityVerbose
+
+ 1
+
+
+ Information
+
+ MyTelemetrySeverityInformation
+
+ 2
+
+
+ Warning
+
+ MyTelemetrySeverityWarning
+
+ 3
+
+
+ Error
+
+ MyTelemetrySeverityError
+
+ 4
+
+
+ Critical
+
+ MyelemetrySeverityCritical
+
+ 5
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxFormExtension/SysIntParameters.MyExtension.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxFormExtension/SysIntParameters.MyExtension.xml
new file mode 100644
index 0000000..e7f8986
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxFormExtension/SysIntParameters.MyExtension.xml
@@ -0,0 +1,140 @@
+
+
+ SysIntParameters.MyExtension
+
+
+
+ FormExtensionControl
+
+ MySettings
+ TabPage
+
+
+
+ MyTelemetryTitleGroup
+ Yes
+ Group
+ SizeToAvailable
+
+
+
+ MyTelemetryLogSettingsText
+ Yes
+ StaticText
+ SizeToAvailable
+
+
+
+ MyTelemetryLogSettings
+
+
+
+ No
+ None
+
+
+
+ MyTelemetryGrid
+ SizeToAvailable
+ ToolbarList
+ 1.2
+ Group
+ SizeToAvailable
+
+
+
+ MyTelemetryLogParam
+ Grid
+
+
+
+ MyTelemetryLogParam_TelemetryClass
+ No
+ String
+
+ TelemetryClass
+ MyTelemetryParameters
+
+
+ MyTelemetryLogParam_IsEnabled
+ CheckBox
+
+ IsEnabled
+ MyTelemetryParameters
+
+
+ MyTelemetryLogParam_SeverityLevel
+ ComboBox
+
+ SeverityLevel
+ MyTelemetryParameters
+
+
+
+ TelemetryFields
+ MyTelemetryParameters
+
+
+ None
+
+
+
+ MyTelemetryLogSettings
+
+
+ TableOfContents
+
+
+
+
+
+
+ MyTelemetryParameters
+
+
+
+ DataAreaId
+
+
+ IsEnabled
+
+
+ Partition
+
+
+ RecId
+
+
+ SeverityLevel
+
+
+ TableId
+
+
+ TelemetryClass
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxTable/MyTelemetryParameters.xml b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxTable/MyTelemetryParameters.xml
new file mode 100644
index 0000000..95936f9
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/bin/AxTable/MyTelemetryParameters.xml
@@ -0,0 +1,119 @@
+
+
+ MyTelemetryParameters
+
+
+
+
+
+
+ find
+
+
+
+
+
+
+
+ MyTelemetryParameters
+
+
+ Allow
+
+ TelemetryClass
+ Yes
+ FoundAndEmpty
+
+
+
+ AutoReport
+
+
+
+ AutoLookup
+
+
+
+ AutoIdentification
+ Yes
+
+
+
+ AutoSummary
+
+
+
+ AutoBrowse
+
+
+
+ TelemetryFields
+
+
+ TelemetryClass
+
+
+ IsEnabled
+
+
+ SeverityLevel
+
+
+
+
+
+
+ TelemetryClass
+ MyTelemetryClass
+ Yes
+
+
+ IsEnabled
+ NoYes
+
+
+ SeverityLevel
+ MyTelemetrySeverityLevel
+
+
+
+
+
+ TelemetryClass
+
+
+ TelemetryClass
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/obj/Debug/TelemetryExtensionExample.rnrproj.AssemblyReference.cache b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/obj/Debug/TelemetryExtensionExample.rnrproj.AssemblyReference.cache
new file mode 100644
index 0000000..04557dc
Binary files /dev/null and b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/obj/Debug/TelemetryExtensionExample.rnrproj.AssemblyReference.cache differ
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/obj/Debug/TelemetryExtensionExample.rnrproj.FileListAbsolute.txt b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/obj/Debug/TelemetryExtensionExample.rnrproj.FileListAbsolute.txt
new file mode 100644
index 0000000..e69de29
diff --git a/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/readme.md b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/readme.md
new file mode 100644
index 0000000..75847a0
--- /dev/null
+++ b/SampleXppExtensions/Projects/FastTrackFscmTelemetrySamples/TelemetryExtensionExample/readme.md
@@ -0,0 +1,82 @@
+# Dynamics 365 FastTrack FSCM Telemetry Samples - TelemetryExtensionExample
+
+This folder contains sample code and guidelines for implementing telemetry in Dynamics 365 Finance and Supply Chain Management (FSCM). The samples are intended to help customers utilize telemetry to monitor and optimize their D365 applications. The code is provided As-is to customer usage. No gaurentees are provided
+
+## Table of Contents
+
+- [Introduction](#introduction)
+- [Prerequisites](#prerequisites)
+- [Installation](#installation)
+- [Usage](#usage)
+- [Contributing](#contributing)
+- [License](#license)
+
+## Introduction
+
+This project provides sample implementations of telemetry in D365 FSCM. It includes creation of a telemetry Base class to demonstrate how to utilize SysApplicationInsightsTelemetryLogger to log Events/metrics/traces with properties to ApplicationInsights. It also includes an extension to the MonitoringAndTelemetry module to control the granularity of logging to Application Insights.
+
+## Prerequisites
+
+- Dynamics 365 Finance and Supply Chain Management environment
+- Visual Studio 2019 or later
+- .NET Framework 4.7.2 or later
+- Access to Azure Application Insights
+
+## Installation
+
+1. Clone the repository:
+
+ ```bash
+ git clone https://github.com/microsoft/Dynamics-365-FastTrack-FSCM-Telemetry-Samples.git
+ cd Dynamics-365-FastTrack-FSCM-Telemetry-Samples\SampleXppExtensions\Projects\FastTrackFscmTelemetrySamples
+ ```
+
+2. Open the solution in Visual Studio in adminstrator mode and open FastTrackFscmTelemetrySamples.sln:
+
+ Create the classes, enums, tables for the code under "\TelemetryExtensionExample\bin"
+ The project structure will look like
+ 
+
+3. Once you create all the dependencies of the project, build the project and refresh AOT
+
+
+if all the classes are built fine, you should see the Cost control configuration ('My Telemetry Log Settings' feel free to rename it as appropriate in your project)in Monitoring and Telemetry settings in your D365 F&O
+
+
+## Usage
+
+1. `MyTelemetryBase` class is the base class which provides structured access to SysApplicationInsightsTelemetryLogger. In this class you can aggregare Properties as your product code is executing and call the ProcessEvent, ProcessTrace, ProcessException etc methods at appropriate points to send those events to ApplicationInsights
+
+ 
+
+2. For each different event/metric/Trace you want to log to AppInsights create a concrete class extending from MyTelemetryBase. Here's an example
+
+
+3. Use the telemetry class to log telemetry.
+ 
+
+4. Monitor the telemetry data in Azure Application Insights. Depending on whether you have logged an event, trace or exception etc, your data will be available in that respective table
+
+ 
+
+5. As you implement telemetry classes and log data into AppInsights, you can control the which events and which severity levels are logged in AppInsights by 2 different ways.
+a> You can disable particular kind of event sall together in the Extension UI
+ 
+
+b> within the event class itself you can set a particular condition for the event to be logged. For example, in this class I have set only severity level above Information to be logged
+
+
+## Contributing
+
+We welcome contributions to this project. To contribute:
+
+1. Fork the repository.
+2. Create a new branch for your feature or bugfix.
+3. Make your changes and commit them.
+4. Push your changes to your fork.
+5. Open a pull request to the main repository.
+
+## License
+
+This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
+