Repository: Azure/WALinuxAgent
Pull request #1911 (2020-06-18 01:12:54)

Fix generic logs event code
<!-- DO NOT DELETE THIS TEMPLATE -->

## Description
This PR contains - 
- Adding timestamp to Context2 for GAGenericLogs table
- adding a force flag to add_log_event to force send log event in certain cases
- Not adding parameters to events that do not need it
- Refactoring: Created Enums for TelemetryEventSchemas and reformatted code 

Issue # <!-- if any -->
<!--
Please add an informative description that covers that changes made by the pull request. 
This checklist is used to make sure that common issues in a pull request are addressed.
This will expedite the process of getting your pull request merged and avoid extra work on your part to fix issues discovered during the review process.
-->

---

### PR information
- [ ] The title of the PR is clear and informative.
- [ ] There are a small number of commits, each of which has an informative message. This means that previously merged commits do not appear in the history of the PR. For information on cleaning up the commits in your pull request, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md).
- [ ] Except for special cases involving multiple contributors, the PR is started from a fork of the main repository, not a branch.
- [ ] If applicable, the PR references the bug/issue that it fixes in the description.
- [ ] New Unit tests were added for the changes made and Travis.CI is passing.

### Quality of Code and Contribution Guidelines
- [ ] I have read the [contribution guidelines](https://github.com/Azure/WALinuxAgent/blob/master/.github/CONTRIBUTING.md).

codecov[bot]: # [Codecov](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=h1) Report
> Merging [#1911](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=desc) into [develop](https://codecov.io/gh/Azure/WALinuxAgent/commit/29f5b67318603eeb5a2566301f61a7479dc0377b&el=desc) will **increase** coverage by `0.10%`.
> The diff coverage is `97.70%`.

[![Impacted file tree graph](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911/graphs/tree.svg?width=650&height=150&src=pr&token=ae90E2KYCw)](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##           develop    #1911      +/-   ##
===========================================
+ Coverage    69.49%   69.60%   +0.10%     
===========================================
  Files           85       85              
  Lines        11865    11906      +41     
  Branches      1666     1667       +1     
===========================================
+ Hits          8246     8287      +41     
  Misses        3249     3249              
  Partials       370      370              
```


| [Impacted Files](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [azurelinuxagent/common/telemetryevent.py](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911/diff?src=pr&el=tree#diff-YXp1cmVsaW51eGFnZW50L2NvbW1vbi90ZWxlbWV0cnlldmVudC5weQ==) | `88.40% <95.23%> (+15.99%)` | :arrow_up: |
| [azurelinuxagent/common/event.py](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911/diff?src=pr&el=tree#diff-YXp1cmVsaW51eGFnZW50L2NvbW1vbi9ldmVudC5weQ==) | `85.96% <100.00%> (ø)` | |
| [azurelinuxagent/common/logger.py](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911/diff?src=pr&el=tree#diff-YXp1cmVsaW51eGFnZW50L2NvbW1vbi9sb2dnZXIucHk=) | `90.96% <100.00%> (+0.05%)` | :arrow_up: |
| [azurelinuxagent/common/protocol/wire.py](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911/diff?src=pr&el=tree#diff-YXp1cmVsaW51eGFnZW50L2NvbW1vbi9wcm90b2NvbC93aXJlLnB5) | `77.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=footer). Last update [29f5b67...f09c602](https://codecov.io/gh/Azure/WALinuxAgent/pull/1911?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/azurelinuxagent/common/event.py b/azurelinuxagent/common/event.py
index e5860d90..5fd52b3c 100644
--- a/azurelinuxagent/common/event.py
+++ b/azurelinuxagent/common/event.py
@@ -33,7 +33,8 @@ from azurelinuxagent.common.exception import EventError, OSUtilError
 from azurelinuxagent.common.future import ustr
 from azurelinuxagent.common.datacontract import get_properties, set_properties
 from azurelinuxagent.common.osutil import get_osutil
-from azurelinuxagent.common.telemetryevent import TelemetryEventParam, TelemetryEvent
+from azurelinuxagent.common.telemetryevent import TelemetryEventParam, TelemetryEvent, CommonTelemetryEventSchema, \
+    GuestAgentGenericLogsSchema, GuestAgentExtensionEventsSchema, GuestAgentPerfCounterEventsSchema
 from azurelinuxagent.common.utils import fileutil, textutil
 from azurelinuxagent.common.utils.textutil import parse_doc, findall, find, getattrib
 from azurelinuxagent.common.version import CURRENT_VERSION, CURRENT_AGENT, AGENT_NAME, DISTRO_NAME, DISTRO_VERSION, DISTRO_CODE_NAME, AGENT_EXECUTION_MODE
@@ -305,23 +306,22 @@ class EventLogger(object):
 
         # Parameters from OS
         osutil = get_osutil()
-        self._common_parameters.append(TelemetryEventParam("OSVersion", EventLogger._get_os_version()))
-        self._common_parameters.append(TelemetryEventParam("ExecutionMode", AGENT_EXECUTION_MODE))
-        self._common_parameters.append(TelemetryEventParam("RAM", int(EventLogger._get_ram(osutil))))
-        self._common_parameters.append(TelemetryEventParam("Processors", int(EventLogger._get_processors(osutil))))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.OSVersion, EventLogger._get_os_version()))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.ExecutionMode, AGENT_EXECUTION_MODE))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.RAM, int(EventLogger._get_ram(osutil))))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.Processors, int(EventLogger._get_processors(osutil))))
 
         # Parameters from goal state
-        self._common_parameters.append(TelemetryEventParam("VMName", "VMName_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam("TenantName", "TenantName_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam("RoleName", "RoleName_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam("RoleInstanceName", "RoleInstanceName_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.TenantName, "TenantName_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.RoleName, "RoleName_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.RoleInstanceName, "RoleInstanceName_UNINITIALIZED"))
         #
         # # Parameters from IMDS
-        self._common_parameters.append(TelemetryEventParam('Location', "Location_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam('SubscriptionId', "SubscriptionId_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam('ResourceGroupName', "ResourceGroupName_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam('VMId', "VMId_UNINITIALIZED"))
-        self._common_parameters.append(TelemetryEventParam('ImageOrigin', 0))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.Location, "Location_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.SubscriptionId, "SubscriptionId_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.ResourceGroupName, "ResourceGroupName_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.VMId, "VMId_UNINITIALIZED"))
+        self._common_parameters.append(TelemetryEventParam(CommonTelemetryEventSchema.ImageOrigin, 0))
 
     @staticmethod
     def _get_os_version():
@@ -354,21 +354,20 @@ class EventLogger(object):
 
         try:
             vminfo = protocol.get_vminfo()
-            parameters["VMName"].value = vminfo.vmName
-            parameters["TenantName"].value = vminfo.tenantName
-            parameters["RoleName"].value = vminfo.roleName
-            parameters["RoleInstanceName"].value = vminfo.roleInstanceName
+            parameters[CommonTelemetryEventSchema.TenantName].value = vminfo.tenantName
+            parameters[CommonTelemetryEventSchema.RoleName].value = vminfo.roleName
+            parameters[CommonTelemetryEventSchema.RoleInstanceName].value = vminfo.roleInstanceName
         except Exception as e:
             logger.warn("Failed to get VM info from goal state; will be missing from telemetry: {0}", ustr(e))
 
         try:
             imds_client = get_imds_client(protocol.get_endpoint())
             imds_info = imds_client.get_compute()
-            parameters['Location'].value = imds_info.location
-            parameters['SubscriptionId'].value = imds_info.subscriptionId
-            parameters['ResourceGroupName'].value = imds_info.resourceGroupName
-            parameters['VMId'].value = imds_info.vmId
-            parameters['ImageOrigin'].value = int(imds_info.image_origin)
+            parameters[CommonTelemetryEventSchema.Location].value = imds_info.location
+            parameters[CommonTelemetryEventSchema.SubscriptionId].value = imds_info.subscriptionId
+            parameters[CommonTelemetryEventSchema.ResourceGroupName].value = imds_info.resourceGroupName
+            parameters[CommonTelemetryEventSchema.VMId].value = imds_info.vmId
+            parameters[CommonTelemetryEventSchema.ImageOrigin].value = int(imds_info.image_origin)
         except Exception as e:
             logger.warn("Failed to get IMDS info; will be missing from telemetry: {0}", ustr(e))
 
@@ -430,12 +429,12 @@ class EventLogger(object):
             _log_event(name, op, message, duration, is_success=is_success)
 
         event = TelemetryEvent(TELEMETRY_EVENT_EVENT_ID, TELEMETRY_EVENT_PROVIDER_ID)
-        event.parameters.append(TelemetryEventParam('Name', str(name)))
-        event.parameters.append(TelemetryEventParam('Version', str(version)))
-        event.parameters.append(TelemetryEventParam('Operation', str(op)))
-        event.parameters.append(TelemetryEventParam('OperationSuccess', bool(is_success)))
-        event.parameters.append(TelemetryEventParam('Message', str(message)))
-        event.parameters.append(TelemetryEventParam('Duration', int(duration)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Name, str(name)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Version, str(version)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Operation, str(op)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.OperationSuccess, bool(is_success)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Message, str(message)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Duration, int(duration)))
         self._add_common_event_parameters(event, datetime.utcnow())
 
         data = get_properties(event)
@@ -446,11 +445,11 @@ class EventLogger(object):
 
     def add_log_event(self, level, message):
         event = TelemetryEvent(TELEMETRY_LOG_EVENT_ID, TELEMETRY_LOG_PROVIDER_ID)
-        event.parameters.append(TelemetryEventParam('EventName', WALAEventOperation.Log))
-        event.parameters.append(TelemetryEventParam('CapabilityUsed', logger.LogLevel.STRINGS[level]))
-        event.parameters.append(TelemetryEventParam('Context1', self._clean_up_message(message)))
-        event.parameters.append(TelemetryEventParam('Context2', ''))
-        event.parameters.append(TelemetryEventParam('Context3', ''))
+        event.parameters.append(TelemetryEventParam(GuestAgentGenericLogsSchema.EventName, WALAEventOperation.Log))
+        event.parameters.append(TelemetryEventParam(GuestAgentGenericLogsSchema.CapabilityUsed, logger.LogLevel.STRINGS[level]))
+        event.parameters.append(TelemetryEventParam(GuestAgentGenericLogsSchema.Context1, self._clean_up_message(message)))
+        event.parameters.append(TelemetryEventParam(GuestAgentGenericLogsSchema.Context2, datetime.utcnow().strftime(logger.Logger.LogTimeFormatInUTC)))
+        event.parameters.append(TelemetryEventParam(GuestAgentGenericLogsSchema.Context3, ''))
         self._add_common_event_parameters(event, datetime.utcnow())
 
         data = get_properties(event)
@@ -475,10 +474,10 @@ class EventLogger(object):
             _log_event(AGENT_NAME, "METRIC", message, 0)
 
         event = TelemetryEvent(TELEMETRY_METRICS_EVENT_ID, TELEMETRY_EVENT_PROVIDER_ID)
-        event.parameters.append(TelemetryEventParam('Category', str(category)))
-        event.parameters.append(TelemetryEventParam('Counter', str(counter)))
-        event.parameters.append(TelemetryEventParam('Instance', str(instance)))
-        event.parameters.append(TelemetryEventParam('Value', float(value)))
+        event.parameters.append(TelemetryEventParam(GuestAgentPerfCounterEventsSchema.Category, str(category)))
+        event.parameters.append(TelemetryEventParam(GuestAgentPerfCounterEventsSchema.Counter, str(counter)))
+        event.parameters.append(TelemetryEventParam(GuestAgentPerfCounterEventsSchema.Instance, str(instance)))
+        event.parameters.append(TelemetryEventParam(GuestAgentPerfCounterEventsSchema.Value, float(value)))
         self._add_common_event_parameters(event, datetime.utcnow())
 
         data = get_properties(event)
@@ -533,15 +532,19 @@ class EventLogger(object):
         This method is called for all events and ensures all telemetry fields are added before the event is sent out.
         Note that the event timestamp is saved in the OpcodeName field.
         """
-        common_params = [TelemetryEventParam('GAVersion', CURRENT_AGENT),
-                         TelemetryEventParam('ContainerId', AgentGlobals.get_container_id()),
-                         TelemetryEventParam('OpcodeName', event_timestamp.strftime(u'%Y-%m-%dT%H:%M:%S.%fZ')),
-                         TelemetryEventParam('EventTid', threading.current_thread().ident),
-                         TelemetryEventParam('EventPid', os.getpid()),
-                         TelemetryEventParam('TaskName', threading.current_thread().getName()),
-                         TelemetryEventParam('KeywordName', ''),
-                         TelemetryEventParam('ExtensionType', event.file_type),
-                         TelemetryEventParam('IsInternal', False)]
+        common_params = [TelemetryEventParam(CommonTelemetryEventSchema.GAVersion, CURRENT_AGENT),
+                         TelemetryEventParam(CommonTelemetryEventSchema.ContainerId, AgentGlobals.get_container_id()),
+                         TelemetryEventParam(CommonTelemetryEventSchema.OpcodeName, event_timestamp.strftime(logger.Logger.LogTimeFormatInUTC)),
+                         TelemetryEventParam(CommonTelemetryEventSchema.EventTid, threading.current_thread().ident),
+                         TelemetryEventParam(CommonTelemetryEventSchema.EventPid, os.getpid()),
+                         TelemetryEventParam(CommonTelemetryEventSchema.TaskName, threading.current_thread().getName()),
+                         TelemetryEventParam(CommonTelemetryEventSchema.KeywordName, '')]
+
+        if event.eventId == TELEMETRY_EVENT_EVENT_ID and event.providerId == TELEMETRY_EVENT_PROVIDER_ID:
+            # Currently only the GuestAgentExtensionEvents has these columns, the other tables dont have them so skipping
+            # this data in those tables.
+            common_params.extend([TelemetryEventParam(GuestAgentExtensionEventsSchema.ExtensionType, event.file_type),
+                         TelemetryEventParam(GuestAgentExtensionEventsSchema.IsInternal, False)])
 
         event.parameters.extend(common_params)
         event.parameters.extend(self._common_parameters)
@@ -557,7 +560,14 @@ class EventLogger(object):
         :param event: Extension event to trim.
         :return: Trimmed extension event; containing only extension-specific parameters.
         """
-        params_to_keep = dict().fromkeys(['Name', 'Version', 'Operation', 'OperationSuccess', 'Message', 'Duration'])
+        params_to_keep = dict().fromkeys([
+            GuestAgentExtensionEventsSchema.Name,
+            GuestAgentExtensionEventsSchema.Version,
+            GuestAgentExtensionEventsSchema.Operation,
+            GuestAgentExtensionEventsSchema.OperationSuccess,
+            GuestAgentExtensionEventsSchema.Message,
+            GuestAgentExtensionEventsSchema.Duration
+        ])
         trimmed_params = []
 
         for param in event.parameters:
@@ -705,17 +715,19 @@ def add_event(name=AGENT_NAME, op=WALAEventOperation.Unknown, is_success=True, d
                            log_event=log_event)
 
 
-def add_log_event(level, message, reporter=__event_logger__):
+def add_log_event(level, message, forced=False, reporter=__event_logger__):
     """
     :param level: LoggerLevel of the log event
     :param message: Message
+    :param forced: Force write the event even if send_logs_to_telemetry() is disabled
+        (NOTE: Remove this flag once send_logs_to_telemetry() is enabled for all events)
     :param reporter:
     :return:
     """
     if reporter.event_dir is None:
         return
 
-    if not send_logs_to_telemetry():
+    if not (forced or send_logs_to_telemetry()):
         return
 
     if level >= logger.LogLevel.WARNING:
diff --git a/azurelinuxagent/common/logger.py b/azurelinuxagent/common/logger.py
index c10591a9..2b1e8ab7 100644
--- a/azurelinuxagent/common/logger.py
+++ b/azurelinuxagent/common/logger.py
@@ -36,6 +36,10 @@ class Logger(object):
     """
     Logger class
     """
+
+    # This format is based on ISO-8601, Z represents UTC (Zero offset)
+    LogTimeFormatInUTC = u'%Y-%m-%dT%H:%M:%S.%fZ'
+
     def __init__(self, logger=None, prefix=None):
         self.appenders = []
         self.logger = self if logger is None else logger
@@ -127,8 +131,7 @@ class Logger(object):
             msg = msg_format.format(*args)
         else:
             msg = msg_format
-            # This format is based on ISO-8601, Z represents UTC (Zero offset)
-        time = datetime.utcnow().strftime(u'%Y-%m-%dT%H:%M:%S.%fZ')
+        time = datetime.utcnow().strftime(Logger.LogTimeFormatInUTC)
         level_str = LogLevel.STRINGS[level]
         thread_name = currentThread().getName()
         if self.prefix is not None:
diff --git a/azurelinuxagent/common/protocol/wire.py b/azurelinuxagent/common/protocol/wire.py
index ff072689..b373ea2a 100644
--- a/azurelinuxagent/common/protocol/wire.py
+++ b/azurelinuxagent/common/protocol/wire.py
@@ -37,7 +37,7 @@ from azurelinuxagent.common.protocol.goal_state import GoalState, TRANSPORT_CERT
 from azurelinuxagent.common.protocol.hostplugin import HostPluginProtocol
 from azurelinuxagent.common.protocol.restapi import DataContract, ExtensionStatus, ExtHandlerPackage, \
     ExtHandlerPackageList, ExtHandlerVersionUri, ProvisionStatus, VMInfo, VMStatus
-from azurelinuxagent.common.telemetryevent import TelemetryEventList
+from azurelinuxagent.common.telemetryevent import TelemetryEventList, GuestAgentExtensionEventsSchema
 from azurelinuxagent.common.utils import fileutil, restutil
 from azurelinuxagent.common.utils.archive import StateFlusher
 from azurelinuxagent.common.utils.cryptutil import CryptUtil
@@ -1100,7 +1100,9 @@ class WireClient(object):
             event_str = event_to_v1(event)
             if len(event_str) >= MAX_EVENT_BUFFER_SIZE:
                 details_of_event = [ustr(x.name) + ":" + ustr(x.value) for x in event.parameters if x.name in
-                                    ["Name", "Version", "Operation", "OperationSuccess"]]
+                                    [GuestAgentExtensionEventsSchema.Name, GuestAgentExtensionEventsSchema.Version,
+                                     GuestAgentExtensionEventsSchema.Operation,
+                                     GuestAgentExtensionEventsSchema.OperationSuccess]]
                 logger.periodic_warn(logger.EVERY_HALF_HOUR,
                                      "Single event too large: {0}, with the length: {1} more than the limit({2})"
                                      .format(str(details_of_event), len(event_str), MAX_EVENT_BUFFER_SIZE))
diff --git a/azurelinuxagent/common/telemetryevent.py b/azurelinuxagent/common/telemetryevent.py
index b8aeb9ec..bbd7af26 100644
--- a/azurelinuxagent/common/telemetryevent.py
+++ b/azurelinuxagent/common/telemetryevent.py
@@ -20,6 +20,58 @@
 from azurelinuxagent.common.datacontract import DataContract, DataContractList
 from azurelinuxagent.common.version import AGENT_NAME
 
+class CommonTelemetryEventSchema(object):
+
+    # Common schema keys for GuestAgentExtensionEvents, GuestAgentGenericLogs
+    # and GuestAgentPerformanceCounterEvents tables in Kusto.
+    EventPid = "EventPid"
+    EventTid = "EventTid"
+    GAVersion = "GAVersion"
+    ContainerId = "ContainerId"
+    TaskName = "TaskName"
+    OpcodeName = "OpcodeName"
+    KeywordName = "KeywordName"
+    OSVersion = "OSVersion"
+    ExecutionMode = "ExecutionMode"
+    RAM = "RAM"
+    Processors = "Processors"
+    TenantName = "TenantName"
+    RoleName = "RoleName"
+    RoleInstanceName = "RoleInstanceName"
+    Location = "Location"
+    SubscriptionId = "SubscriptionId"
+    ResourceGroupName = "ResourceGroupName"
+    VMId = "VMId"
+    ImageOrigin = "ImageOrigin"
+
+class GuestAgentGenericLogsSchema(CommonTelemetryEventSchema):
+
+    # GuestAgentGenericLogs table specific schema keys
+    EventName = "EventName"
+    CapabilityUsed = "CapabilityUsed"
+    Context1 = "Context1"
+    Context2 = "Context2"
+    Context3 = "Context3"
+
+class GuestAgentExtensionEventsSchema(CommonTelemetryEventSchema):
+
+    # GuestAgentExtensionEvents table specific schema keys
+    ExtensionType = "ExtensionType"
+    IsInternal = "IsInternal"
+    Name = "Name"
+    Version = "Version"
+    Operation = "Operation"
+    OperationSuccess = "OperationSuccess"
+    Message = "Message"
+    Duration = "Duration"
+
+class GuestAgentPerfCounterEventsSchema(CommonTelemetryEventSchema):
+
+    # GuestAgentPerformanceCounterEvents table specific schema keys
+    Category = "Category"
+    Counter = "Counter"
+    Instance = "Instance"
+    Value = "Value"
 
 class TelemetryEventParam(DataContract):
     def __init__(self, name=None, value=None):
@@ -46,13 +98,13 @@ class TelemetryEvent(DataContract):
         # parameter, in the case of log and metric events. So, in case the Name parameter exists and it is not
         # "WALinuxAgent", it is an extension event.
         for param in self.parameters:
-            if param.name == "Name":
+            if param.name == GuestAgentExtensionEventsSchema.Name:
                 return param.value != AGENT_NAME
         return False
 
     def get_version(self):
         for param in self.parameters:
-            if param.name == "Version":
+            if param.name == GuestAgentExtensionEventsSchema.Version:
                 return param.value
         return None
 


Test patch:
diff --git a/tests/common/test_event.py b/tests/common/test_event.py
index 83971da2..85602eb9 100644
--- a/tests/common/test_event.py
+++ b/tests/common/test_event.py
@@ -28,8 +28,11 @@ import azurelinuxagent.common.utils.textutil as textutil
 from azurelinuxagent.common import event, logger
 from azurelinuxagent.common.AgentGlobals import AgentGlobals
 from azurelinuxagent.common.event import add_event, add_periodic, add_log_event, elapsed_milliseconds, report_metric, \
-    WALAEventOperation, parse_xml_event, parse_json_event, AGENT_EVENT_FILE_EXTENSION, EVENTS_DIRECTORY
+    WALAEventOperation, parse_xml_event, parse_json_event, AGENT_EVENT_FILE_EXTENSION, EVENTS_DIRECTORY, \
+    TELEMETRY_EVENT_EVENT_ID, TELEMETRY_EVENT_PROVIDER_ID, TELEMETRY_LOG_EVENT_ID, TELEMETRY_LOG_PROVIDER_ID
 from azurelinuxagent.common.future import ustr
+from azurelinuxagent.common.telemetryevent import CommonTelemetryEventSchema, GuestAgentGenericLogsSchema, \
+    GuestAgentExtensionEventsSchema, GuestAgentPerfCounterEventsSchema
 from tests.protocol import mockwiredata
 from tests.protocol.mocks import mock_wire_protocol, HttpRequestPredicates, MockHttpResponse
 from azurelinuxagent.common.version import CURRENT_AGENT, CURRENT_VERSION, AGENT_EXECUTION_MODE
@@ -50,31 +53,42 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
         self.expected_common_parameters = {
             # common parameters computed at event creation; the timestamp (stored as the opcode name) is not included here and
             # is checked separately from these parameters
-            'GAVersion': CURRENT_AGENT,
-            'ContainerId': AgentGlobals.get_container_id(),
-            'EventTid': threading.current_thread().ident,
-            'EventPid': os.getpid(),
-            'TaskName': threading.current_thread().getName(),
-            'KeywordName': '',
-            'IsInternal': False,
+            CommonTelemetryEventSchema.GAVersion: CURRENT_AGENT,
+            CommonTelemetryEventSchema.ContainerId: AgentGlobals.get_container_id(),
+            CommonTelemetryEventSchema.EventTid: threading.current_thread().ident,
+            CommonTelemetryEventSchema.EventPid: os.getpid(),
+            CommonTelemetryEventSchema.TaskName: threading.current_thread().getName(),
+            CommonTelemetryEventSchema.KeywordName: '',
             # common parameters computed from the OS platform
-            'OSVersion': EventLoggerTools.get_expected_os_version(),
-            'ExecutionMode': AGENT_EXECUTION_MODE,
-            'RAM': int(osutil.get_total_mem()),
-            'Processors': osutil.get_processor_cores(),
+            CommonTelemetryEventSchema.OSVersion: EventLoggerTools.get_expected_os_version(),
+            CommonTelemetryEventSchema.ExecutionMode: AGENT_EXECUTION_MODE,
+            CommonTelemetryEventSchema.RAM: int(osutil.get_total_mem()),
+            CommonTelemetryEventSchema.Processors: osutil.get_processor_cores(),
             # common parameters from the goal state
-            'VMName': 'MachineRole_IN_0',
-            'TenantName': 'db00a7755a5e4e8a8fe4b19bc3b330c3',
-            'RoleName': 'MachineRole',
-            'RoleInstanceName': 'MachineRole_IN_0',
+            CommonTelemetryEventSchema.TenantName: 'db00a7755a5e4e8a8fe4b19bc3b330c3',
+            CommonTelemetryEventSchema.RoleName: 'MachineRole',
+            CommonTelemetryEventSchema.RoleInstanceName: 'MachineRole_IN_0',
             # common parameters
-            'Location': EventLoggerTools.mock_imds_data['location'],
-            'SubscriptionId': EventLoggerTools.mock_imds_data['subscriptionId'],
-            'ResourceGroupName': EventLoggerTools.mock_imds_data['resourceGroupName'],
-            'VMId': EventLoggerTools.mock_imds_data['vmId'],
-            'ImageOrigin': EventLoggerTools.mock_imds_data['image_origin'],
+            CommonTelemetryEventSchema.Location: EventLoggerTools.mock_imds_data['location'],
+            CommonTelemetryEventSchema.SubscriptionId: EventLoggerTools.mock_imds_data['subscriptionId'],
+            CommonTelemetryEventSchema.ResourceGroupName: EventLoggerTools.mock_imds_data['resourceGroupName'],
+            CommonTelemetryEventSchema.VMId: EventLoggerTools.mock_imds_data['vmId'],
+            CommonTelemetryEventSchema.ImageOrigin: EventLoggerTools.mock_imds_data['image_origin'],
         }
 
+        self.expected_extension_events_params = {
+            GuestAgentExtensionEventsSchema.IsInternal: False,
+            GuestAgentExtensionEventsSchema.ExtensionType: ""
+        }
+
+    @staticmethod
+    def _is_guest_extension_event(event):
+        return event.eventId == TELEMETRY_EVENT_EVENT_ID and event.providerId == TELEMETRY_EVENT_PROVIDER_ID
+
+    @staticmethod
+    def _is_telemetry_log_event(event):
+        return event.eventId == TELEMETRY_LOG_EVENT_ID and event.providerId == TELEMETRY_LOG_PROVIDER_ID
+
     def test_parse_xml_event(self, *args):
         data_str = load_data('ext/event_from_extension.xml')
         event = parse_xml_event(data_str)
@@ -96,7 +110,7 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
             self.assertEquals(len(event_list.events), 1, "Could not find the event created by add_event")
 
             for p in event_list.events[0].parameters:
-                if p.name == 'ContainerId':
+                if p.name == CommonTelemetryEventSchema.ContainerId:
                     return p.value
 
             self.fail("Could not find Contained ID on event")
@@ -348,7 +362,7 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
     @staticmethod
     def _get_event_message(evt):
         for p in evt.parameters:
-            if p.name == 'Message':
+            if p.name == GuestAgentExtensionEventsSchema.Message:
                 return p.value
         return None
 
@@ -456,6 +470,8 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
     def _assert_event_includes_all_parameters_in_the_telemetry_schema(self, actual_event, expected_parameters, assert_timestamp):
         # add the common parameters to the set of expected parameters
         all_expected_parameters = self.expected_common_parameters.copy()
+        if self._is_guest_extension_event(actual_event):
+            all_expected_parameters.update(self.expected_extension_events_params.copy())
         all_expected_parameters.update(expected_parameters)
 
         # convert the event parameters to a dictionary; do not include the timestamp,
@@ -463,11 +479,17 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
         event_parameters = {}
         timestamp = None
         for p in actual_event.parameters:
-            if p.name == 'OpcodeName':  # the timestamp is stored in the opcode name
+            if p.name == CommonTelemetryEventSchema.OpcodeName:  # the timestamp is stored in the opcode name
                 timestamp = p.value
             else:
                 event_parameters[p.name] = p.value
 
+        if self._is_telemetry_log_event(actual_event):
+            # Remove Context2 from event parameters and verify that the timestamp is correct
+            telemetry_log_event_timestamp = event_parameters.pop(GuestAgentGenericLogsSchema.Context2, None)
+            self.assertIsNotNone(telemetry_log_event_timestamp, "Context2 should be filled with a timestamp")
+            assert_timestamp(telemetry_log_event_timestamp)
+
         self.maxDiff = None  # the dictionary diffs can be quite large; display the whole thing
         self.assertDictEqual(event_parameters, all_expected_parameters)
 
@@ -476,7 +498,7 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
 
     @staticmethod
     def _datetime_to_event_timestamp(dt):
-        return dt.strftime(u'%Y-%m-%dT%H:%M:%S.%fZ')
+        return dt.strftime(logger.Logger.LogTimeFormatInUTC)
 
     def _test_create_event_function_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(self, create_event_function, expected_parameters):
         """
@@ -511,13 +533,13 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
                     version="1.2.3.4",
                     message="Test Message"),
             expected_parameters={
-                'Name': 'TestEvent',
-                'Version': '1.2.3.4',
-                'Operation': 'AgentEnabled',
-                'OperationSuccess': True,
-                'Message': 'Test Message',
-                'Duration': 1234,
-                'ExtensionType': ''})
+                GuestAgentExtensionEventsSchema.Name: 'TestEvent',
+                GuestAgentExtensionEventsSchema.Version: '1.2.3.4',
+                GuestAgentExtensionEventsSchema.Operation: 'AgentEnabled',
+                GuestAgentExtensionEventsSchema.OperationSuccess: True,
+                GuestAgentExtensionEventsSchema.Message: 'Test Message',
+                GuestAgentExtensionEventsSchema.Duration: 1234,
+                GuestAgentExtensionEventsSchema.ExtensionType: ''})
 
     def test_add_periodic_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(self):
         self._test_create_event_function_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(
@@ -531,35 +553,50 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
                     version="4.3.2.1",
                     message="Test Periodic Message"),
             expected_parameters={
-                'Name': 'TestPeriodicEvent',
-                'Version': '4.3.2.1',
-                'Operation': 'HostPlugin',
-                'OperationSuccess': False,
-                'Message': 'Test Periodic Message',
-                'Duration': 4321,
-                'ExtensionType': ''})
+                GuestAgentExtensionEventsSchema.Name: 'TestPeriodicEvent',
+                GuestAgentExtensionEventsSchema.Version: '4.3.2.1',
+                GuestAgentExtensionEventsSchema.Operation: 'HostPlugin',
+                GuestAgentExtensionEventsSchema.OperationSuccess: False,
+                GuestAgentExtensionEventsSchema.Message: 'Test Periodic Message',
+                GuestAgentExtensionEventsSchema.Duration: 4321,
+                GuestAgentExtensionEventsSchema.ExtensionType: ''})
 
     @skip_if_predicate_true(lambda: True, "Enable this test when SEND_LOGS_TO_TELEMETRY is enabled")
     def test_add_log_event_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(self):
         self._test_create_event_function_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(
             create_event_function=lambda: add_log_event(logger.LogLevel.INFO, 'A test INFO log event'),
             expected_parameters={
-                'EventName': 'Log',
-                'CapabilityUsed': 'INFO',
-                'Context1': 'A test INFO log event',
-                'Context2': '',
-                'Context3': '',
-                'ExtensionType': ''})
+                GuestAgentGenericLogsSchema.EventName: 'Log',
+                GuestAgentGenericLogsSchema.CapabilityUsed: 'INFO',
+                GuestAgentGenericLogsSchema.Context1: 'log event',
+                GuestAgentGenericLogsSchema.Context3: ''
+            })
+
+    def test_add_log_event_should_always_create_events_when_forced(self):
+        self._test_create_event_function_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(
+            create_event_function=lambda: add_log_event(logger.LogLevel.WARNING, 'A test WARNING log event',
+                                                        forced=True),
+            expected_parameters={
+                GuestAgentGenericLogsSchema.EventName: 'Log',
+                GuestAgentGenericLogsSchema.CapabilityUsed: 'WARNING',
+                GuestAgentGenericLogsSchema.Context1: 'log event',
+                GuestAgentGenericLogsSchema.Context3: ''
+            })
+
+    def test_add_log_event_should_not_create_event_if_not_allowed_and_not_forced(self):
+        add_log_event(logger.LogLevel.WARNING, 'A test WARNING log event')
+        event_list = event.collect_events()
+        self.assertEquals(len(event_list.events), 0, "No events should be created if not forced and not allowed")
 
     def test_report_metric_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(self):
         self._test_create_event_function_should_create_events_that_have_all_the_parameters_in_the_telemetry_schema(
             create_event_function=lambda: report_metric("cpu", "%idle", "total", 12.34),
             expected_parameters={
-                'Category': 'cpu',
-                'Counter': '%idle',
-                'Instance': 'total',
-                'Value': 12.34,
-                'ExtensionType': ''})
+                GuestAgentPerfCounterEventsSchema.Category: 'cpu',
+                GuestAgentPerfCounterEventsSchema.Counter: '%idle',
+                GuestAgentPerfCounterEventsSchema.Instance: 'total',
+                GuestAgentPerfCounterEventsSchema.Value: 12.34
+            })
 
     def _create_test_event_file(self, source_file):
         source_file_path = os.path.join(data_dir, "events", source_file)
@@ -583,20 +620,20 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
         self._assert_event_includes_all_parameters_in_the_telemetry_schema(
             event_list.events[0],
             expected_parameters={
-                "Name": "WALinuxAgent",
-                "Version": "9.9.9",
-                "IsInternal": False,
-                "Operation": "InitializeCGroups",
-                "OperationSuccess": True,
-                "Message": "The cgroup filesystem is ready to use",
-                "Duration": 1234,
-                "ExtensionType": "ALegacyExtensionType",
-                "GAVersion": "WALinuxAgent-1.1.1",
-                "ContainerId": "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
-                "EventTid": 98765,
-                "EventPid": 4321,
-                "TaskName": "ALegacyTask",
-                "KeywordName": "ALegacyKeywordName"},
+                GuestAgentExtensionEventsSchema.Name: "WALinuxAgent",
+                GuestAgentExtensionEventsSchema.Version: "9.9.9",
+                GuestAgentExtensionEventsSchema.IsInternal: False,
+                GuestAgentExtensionEventsSchema.Operation: "InitializeCGroups",
+                GuestAgentExtensionEventsSchema.OperationSuccess: True,
+                GuestAgentExtensionEventsSchema.Message: "The cgroup filesystem is ready to use",
+                GuestAgentExtensionEventsSchema.Duration: 1234,
+                GuestAgentExtensionEventsSchema.ExtensionType: "ALegacyExtensionType",
+                CommonTelemetryEventSchema.GAVersion: "WALinuxAgent-1.1.1",
+                CommonTelemetryEventSchema.ContainerId: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
+                CommonTelemetryEventSchema.EventTid: 98765,
+                CommonTelemetryEventSchema.EventPid: 4321,
+                CommonTelemetryEventSchema.TaskName: "ALegacyTask",
+                CommonTelemetryEventSchema.KeywordName: "ALegacyKeywordName"},
             assert_timestamp=lambda timestamp:
                 self.assertEquals(timestamp, '1970-01-01 12:00:00', "The event timestamp (opcode) is incorrect")
         )
@@ -613,20 +650,20 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
         self._assert_event_includes_all_parameters_in_the_telemetry_schema(
             event_list.events[0],
             expected_parameters={
-                "Name": "WALinuxAgent",
-                "Version": "9.9.9",
-                "IsInternal": False,
-                "Operation": "InitializeCGroups",
-                "OperationSuccess": True,
-                "Message": "The cgroup filesystem is ready to use",
-                "Duration": 1234,
-                "ExtensionType": "ALegacyExtensionType",
-                "GAVersion": "WALinuxAgent-1.1.1",
-                "ContainerId": "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
-                "EventTid": 98765,
-                "EventPid": 4321,
-                "TaskName": "ALegacyTask",
-                "KeywordName": "ALegacyKeywordName"},
+                GuestAgentExtensionEventsSchema.Name: "WALinuxAgent",
+                GuestAgentExtensionEventsSchema.Version: "9.9.9",
+                GuestAgentExtensionEventsSchema.IsInternal: False,
+                GuestAgentExtensionEventsSchema.Operation: "InitializeCGroups",
+                GuestAgentExtensionEventsSchema.OperationSuccess: True,
+                GuestAgentExtensionEventsSchema.Message: "The cgroup filesystem is ready to use",
+                GuestAgentExtensionEventsSchema.Duration: 1234,
+                GuestAgentExtensionEventsSchema.ExtensionType: "ALegacyExtensionType",
+                CommonTelemetryEventSchema.GAVersion: "WALinuxAgent-1.1.1",
+                CommonTelemetryEventSchema.ContainerId: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE",
+                CommonTelemetryEventSchema.EventTid: 98765,
+                CommonTelemetryEventSchema.EventPid: 4321,
+                CommonTelemetryEventSchema.TaskName: "ALegacyTask",
+                CommonTelemetryEventSchema.KeywordName: "ALegacyKeywordName"},
             assert_timestamp=lambda timestamp:
                 self.assertEquals(timestamp, event_creation_time, "The event timestamp (opcode) is incorrect")
         )
@@ -645,13 +682,13 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
         self._assert_event_includes_all_parameters_in_the_telemetry_schema(
             event_list.events[0],
             expected_parameters={
-                'Name': 'Microsoft.Azure.Extensions.CustomScript',
-                'Version': '2.0.4',
-                'Operation': 'Scenario',
-                'OperationSuccess': True,
-                'Message': 'A test telemetry message.',
-                'Duration': 150000,
-                'ExtensionType': 'json'},
+                GuestAgentExtensionEventsSchema.Name: 'Microsoft.Azure.Extensions.CustomScript',
+                GuestAgentExtensionEventsSchema.Version: '2.0.4',
+                GuestAgentExtensionEventsSchema.Operation: 'Scenario',
+                GuestAgentExtensionEventsSchema.OperationSuccess: True,
+                GuestAgentExtensionEventsSchema.Message: 'A test telemetry message.',
+                GuestAgentExtensionEventsSchema.Duration: 150000,
+                GuestAgentExtensionEventsSchema.ExtensionType: 'json'},
             assert_timestamp=lambda timestamp:
                 self.assertEquals(timestamp, event_creation_time, "The event timestamp (opcode) is incorrect")
             )
@@ -674,7 +711,7 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
             telemetry_event = json.loads(event_data)
 
             for p in telemetry_event['parameters']:
-                if p['name'] == 'Message':
+                if p['name'] == GuestAgentExtensionEventsSchema.Message:
                     return p['value']
 
             raise ValueError('Could not find the Message for the telemetry event in {0}'.format(path))
@@ -703,7 +740,7 @@ class TestEvent(HttpRequestPredicates, AgentTestCase):
             helper_node = textutil.find(event_xml_doc, "Helper")
 
             for child in helper_node.childNodes:
-                if child.getAttribute('Name') == 'Message':
+                if child.getAttribute('Name') == GuestAgentExtensionEventsSchema.Message:
                     return child.getAttribute('Value')
 
             raise ValueError('Could not find the Message for the telemetry event. Request body: {0}'.format(http_request_body))
@@ -740,7 +777,7 @@ class TestMetrics(AgentTestCase):
         event_dictionary = json.loads(event_json)
         self.assertEqual(event_dictionary['providerId'], event.TELEMETRY_EVENT_PROVIDER_ID)
         for parameter in event_dictionary["parameters"]:
-            if parameter['name'] == 'Counter':
+            if parameter['name'] == GuestAgentPerfCounterEventsSchema.Counter:
                 self.assertEqual(parameter['value'], '%idle')
                 break
         else:
diff --git a/tests/common/test_logger.py b/tests/common/test_logger.py
index 78869efd..8698ed20 100644
--- a/tests/common/test_logger.py
+++ b/tests/common/test_logger.py
@@ -184,7 +184,7 @@ class TestLogger(AgentTestCase):
             log = log_file.read()
             try:
                 time_in_file = datetime.strptime(log.split(logger.LogLevel.STRINGS[logger.LogLevel.INFO])[0].strip()
-                                                 , u'%Y-%m-%dT%H:%M:%S.%fZ')
+                                                 , logger.Logger.LogTimeFormatInUTC)
             except ValueError:
                 self.fail("Ensure timestamp follows ISO-8601 format + 'Z' for UTC")
 
@@ -209,7 +209,7 @@ class TestLogger(AgentTestCase):
             log = log_file.read()
             try:
                 time_in_file = datetime.strptime(log.split(logger.LogLevel.STRINGS[logger.LogLevel.INFO])[0].strip()
-                                                 , u'%Y-%m-%dT%H:%M:%S.%fZ')
+                                                 , logger.Logger.LogTimeFormatInUTC)
             except ValueError:
                 self.fail("Ensure timestamp follows ISO-8601 format and has micro seconds in it")
 
diff --git a/tests/common/test_telemetryevent.py b/tests/common/test_telemetryevent.py
index de75f3cb..e23ab684 100644
--- a/tests/common/test_telemetryevent.py
+++ b/tests/common/test_telemetryevent.py
@@ -14,21 +14,22 @@
 #
 # Requires Python 2.6+ and Openssl 1.0+
 #
-from azurelinuxagent.common.telemetryevent import TelemetryEvent, TelemetryEventParam
+from azurelinuxagent.common.telemetryevent import TelemetryEvent, TelemetryEventParam, GuestAgentExtensionEventsSchema, \
+    CommonTelemetryEventSchema
 from tests.tools import AgentTestCase
 
 
 def get_test_event(name="DummyExtension", op="Unknown", is_success=True, duration=0, version="foo", evt_type="", is_internal=False,
                       message="DummyMessage", eventId=1):
     event = TelemetryEvent(eventId, "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
-    event.parameters.append(TelemetryEventParam('Name', name))
-    event.parameters.append(TelemetryEventParam('Version', str(version)))
-    event.parameters.append(TelemetryEventParam('IsInternal', is_internal))
-    event.parameters.append(TelemetryEventParam('Operation', op))
-    event.parameters.append(TelemetryEventParam('OperationSuccess', is_success))
-    event.parameters.append(TelemetryEventParam('Message', message))
-    event.parameters.append(TelemetryEventParam('Duration', duration))
-    event.parameters.append(TelemetryEventParam('ExtensionType', evt_type))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Name, name))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Version, str(version)))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.IsInternal, is_internal))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Operation, op))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.OperationSuccess, is_success))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Message, message))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Duration, duration))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.ExtensionType, evt_type))
     return event
 
 
@@ -36,14 +37,14 @@ class TestTelemetryEvent(AgentTestCase):
     def test_contains_works_for_TelemetryEvent(self):
         test_event = get_test_event(message="Dummy Event")
 
-        self.assertTrue('Name' in test_event)
-        self.assertTrue('Version' in test_event)
-        self.assertTrue('IsInternal' in test_event)
-        self.assertTrue('Operation' in test_event)
-        self.assertTrue('OperationSuccess' in test_event)
-        self.assertTrue('Message' in test_event)
-        self.assertTrue('Duration' in test_event)
-        self.assertTrue('ExtensionType' in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.Name in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.Version in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.IsInternal in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.Operation in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.OperationSuccess in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.Message in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.Duration in test_event)
+        self.assertTrue(GuestAgentExtensionEventsSchema.ExtensionType in test_event)
 
-        self.assertFalse('GAVersion' in test_event)
-        self.assertFalse('ContainerId' in test_event)
\ No newline at end of file
+        self.assertFalse(CommonTelemetryEventSchema.GAVersion in test_event)
+        self.assertFalse(CommonTelemetryEventSchema.ContainerId in test_event)
\ No newline at end of file
diff --git a/tests/ga/test_monitor.py b/tests/ga/test_monitor.py
index 6482d61f..294db288 100644
--- a/tests/ga/test_monitor.py
+++ b/tests/ga/test_monitor.py
@@ -39,7 +39,7 @@ from azurelinuxagent.common.exception import HttpError
 from azurelinuxagent.common.logger import Logger
 from azurelinuxagent.common.osutil import get_osutil
 from azurelinuxagent.common.protocol.wire import WireProtocol
-from azurelinuxagent.common.telemetryevent import TelemetryEvent, TelemetryEventParam
+from azurelinuxagent.common.telemetryevent import TelemetryEvent, TelemetryEventParam, GuestAgentExtensionEventsSchema
 from azurelinuxagent.common.utils import fileutil, restutil
 from azurelinuxagent.common.version import AGENT_VERSION, CURRENT_VERSION, CURRENT_AGENT, DISTRO_NAME, DISTRO_VERSION, DISTRO_CODE_NAME
 from azurelinuxagent.ga.monitor import get_monitor_handler, MonitorHandler, PeriodicOperation, ResetPeriodicLogMessagesOperation, PollResourceUsageOperation
@@ -177,6 +177,8 @@ class TestEventMonitoring(AgentTestCase, HttpRequestPredicates):
     def tearDown(self):
         fileutil.rm_dirs(self.lib_dir)
 
+    _TEST_EVENT_PROVIDER_ID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
+
     def _create_extension_event(self,
                                size=0,
                                name="DummyExtension",
@@ -197,17 +199,18 @@ class TestEventMonitoring(AgentTestCase, HttpRequestPredicates):
 
     @staticmethod
     def _get_event_data(duration, is_success, message, name, op, version, eventId=1):
-        event = TelemetryEvent(eventId, "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
-        event.parameters.append(TelemetryEventParam('Name', name))
-        event.parameters.append(TelemetryEventParam('Version', str(version)))
-        event.parameters.append(TelemetryEventParam('Operation', op))
-        event.parameters.append(TelemetryEventParam('OperationSuccess', is_success))
-        event.parameters.append(TelemetryEventParam('Message', message))
-        event.parameters.append(TelemetryEventParam('Duration', duration))
+        event = TelemetryEvent(eventId, TestEventMonitoring._TEST_EVENT_PROVIDER_ID)
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Name, name))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Version, str(version)))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Operation, op))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.OperationSuccess, is_success))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Message, message))
+        event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Duration, duration))
 
         data = get_properties(event)
         return json.dumps(data)
 
+    @patch("azurelinuxagent.common.event.TELEMETRY_EVENT_PROVIDER_ID", _TEST_EVENT_PROVIDER_ID)
     @patch("azurelinuxagent.common.protocol.wire.WireClient.send_event")
     @patch("azurelinuxagent.common.conf.get_lib_dir")
     def test_collect_and_send_events(self, mock_lib_dir, patch_send_event, *_):
@@ -217,7 +220,7 @@ class TestEventMonitoring(AgentTestCase, HttpRequestPredicates):
             self._create_extension_event(message="Message-Test")
 
             test_mtime = 1000  # epoch time, in ms
-            test_opcodename = datetime.datetime.fromtimestamp(test_mtime).strftime(u'%Y-%m-%dT%H:%M:%S.%fZ')
+            test_opcodename = datetime.datetime.fromtimestamp(test_mtime).strftime(logger.Logger.LogTimeFormatInUTC)
             test_eventtid = 42
             test_eventpid = 24
             test_taskname = "TEST_TaskName"
@@ -256,7 +259,6 @@ class TestEventMonitoring(AgentTestCase, HttpRequestPredicates):
                              '<Param Name="ExecutionMode" Value="IAAS" T="mt:wstr" />' \
                              '<Param Name="RAM" Value="{7}" T="mt:uint64" />' \
                              '<Param Name="Processors" Value="{8}" T="mt:uint64" />' \
-                             '<Param Name="VMName" Value="MachineRole_IN_0" T="mt:wstr" />' \
                              '<Param Name="TenantName" Value="db00a7755a5e4e8a8fe4b19bc3b330c3" T="mt:wstr" />' \
                              '<Param Name="RoleName" Value="MachineRole" T="mt:wstr" />' \
                              '<Param Name="RoleInstanceName" Value="MachineRole_IN_0" T="mt:wstr" />' \
diff --git a/tests/protocol/test_wire.py b/tests/protocol/test_wire.py
index 9cd8ddcd..b98f89f0 100644
--- a/tests/protocol/test_wire.py
+++ b/tests/protocol/test_wire.py
@@ -32,7 +32,8 @@ from azurelinuxagent.common.protocol.hostplugin import HostPluginProtocol
 from azurelinuxagent.common.protocol.restapi import VMAgentManifestUri
 from azurelinuxagent.common.protocol.wire import WireProtocol, WireClient, \
     InVMArtifactsProfile, StatusBlob, VMStatus
-from azurelinuxagent.common.telemetryevent import TelemetryEvent, TelemetryEventParam, TelemetryEventList
+from azurelinuxagent.common.telemetryevent import TelemetryEventList, GuestAgentExtensionEventsSchema, \
+    TelemetryEventParam, TelemetryEvent
 from azurelinuxagent.common.utils import restutil
 from azurelinuxagent.common.version import CURRENT_VERSION, DISTRO_NAME, DISTRO_VERSION
 from tests.ga.test_monitor import random_generator
@@ -51,14 +52,14 @@ WIRESERVER_URL = '168.63.129.16'
 def get_event(message, duration=30000, evt_type="", is_internal=False, is_success=True,
               name="", op="Unknown", version=CURRENT_VERSION, eventId=1):
     event = TelemetryEvent(eventId, "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
-    event.parameters.append(TelemetryEventParam('Name', name))
-    event.parameters.append(TelemetryEventParam('Version', str(version)))
-    event.parameters.append(TelemetryEventParam('IsInternal', is_internal))
-    event.parameters.append(TelemetryEventParam('Operation', op))
-    event.parameters.append(TelemetryEventParam('OperationSuccess', is_success))
-    event.parameters.append(TelemetryEventParam('Message', message))
-    event.parameters.append(TelemetryEventParam('Duration', duration))
-    event.parameters.append(TelemetryEventParam('ExtensionType', evt_type))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Name, name))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Version, str(version)))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.IsInternal, is_internal))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Operation, op))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.OperationSuccess, is_success))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Message, message))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.Duration, duration))
+    event.parameters.append(TelemetryEventParam(GuestAgentExtensionEventsSchema.ExtensionType, evt_type))
     return event