diff --git a/src/base/src/AXOpen.Base.Abstractions/App/AxoApplication.cs b/src/base/src/AXOpen.Base.Abstractions/App/AxoApplication.cs
index 0e9a9070a..d5dc659d5 100644
--- a/src/base/src/AXOpen.Base.Abstractions/App/AxoApplication.cs
+++ b/src/base/src/AXOpen.Base.Abstractions/App/AxoApplication.cs
@@ -1,4 +1,5 @@
-using AXOpen.Logging;
+using System.Security.Principal;
+using AXOpen.Logging;
namespace AXOpen
{
@@ -39,5 +40,7 @@ public IAxoApplication Build()
/// Get currently running application.
///
public static IAxoApplication Current => _current;
+
+ public IIdentity ControllerIdentity { get; } = new ControllerIdentity();
}
}
diff --git a/src/base/src/AXOpen.Base.Abstractions/App/IAxoApplication.cs b/src/base/src/AXOpen.Base.Abstractions/App/IAxoApplication.cs
index f794bb118..a376d36e4 100644
--- a/src/base/src/AXOpen.Base.Abstractions/App/IAxoApplication.cs
+++ b/src/base/src/AXOpen.Base.Abstractions/App/IAxoApplication.cs
@@ -5,6 +5,7 @@
// https://github.com/ix-ax/axsharp/blob/dev/LICENSE
// Third party licenses: https://github.com/ix-ax/axsharp/blob/dev/notices.md
+using System.Security.Principal;
using AXOpen.Logging;
namespace AXOpen;
@@ -18,4 +19,9 @@ public interface IAxoApplication
/// Gets logger configured for this application.
///
ILogger Logger { get; }
+
+ ///
+ /// Provides identity for the logging operation for controller provenience.
+ ///
+ IIdentity ControllerIdentity { get; }
}
\ No newline at end of file
diff --git a/src/base/src/AXOpen.Base.Abstractions/ControllerIdentity.cs b/src/base/src/AXOpen.Base.Abstractions/ControllerIdentity.cs
new file mode 100644
index 000000000..3b5bf33fb
--- /dev/null
+++ b/src/base/src/AXOpen.Base.Abstractions/ControllerIdentity.cs
@@ -0,0 +1,8 @@
+using System.Security.Principal;
+
+namespace AXOpen;
+
+///
+/// Provides identity for the operations from the controller.
+///
+internal class ControllerIdentity() : GenericIdentity("Controller");
\ No newline at end of file
diff --git a/src/core/src/AXOpen.Core/AxoLogger/AxoLogger.cs b/src/core/src/AXOpen.Core/AxoLogger/AxoLogger.cs
index 146201988..247ef864a 100644
--- a/src/core/src/AXOpen.Core/AxoLogger/AxoLogger.cs
+++ b/src/core/src/AXOpen.Core/AxoLogger/AxoLogger.cs
@@ -83,25 +83,26 @@ await Task.Run(async () =>
private void CreateLogEntry(eLogLevel level, string message, ITwinObject? sender)
{
+ var controllerIdentity = AxoApplication.Current.ControllerIdentity;
switch (level)
{
case eLogLevel.Verbose:
- _logger.Verbose($"{message}", sender, new GenericIdentity("Controller"), sender);
+ _logger.Verbose($"{message}", sender, controllerIdentity, sender);
break;
case eLogLevel.Debug:
- _logger.Debug($"{message}", sender, new GenericIdentity("Controller"), sender);
+ _logger.Debug($"{message}", sender, controllerIdentity, sender);
break;
case eLogLevel.Information:
- _logger.Information($"{message}", sender, new GenericIdentity("Controller"), sender);
+ _logger.Information($"{message}", sender, controllerIdentity, sender);
break;
case eLogLevel.Warning:
- _logger.Warning($"{message}", sender, new GenericIdentity("Controller"), sender);
+ _logger.Warning($"{message}", sender, controllerIdentity, sender);
break;
case eLogLevel.Error:
- _logger.Error($"{message}", sender, new GenericIdentity("Controller"), sender);
+ _logger.Error($"{message}", sender, controllerIdentity, sender);
break;
case eLogLevel.Fatal:
- _logger.Fatal($"{message}", sender, new GenericIdentity("Controller"), sender);
+ _logger.Fatal($"{message}", sender, controllerIdentity, sender);
break;
}
}
diff --git a/src/data/src/AXOpen.Data/DataExchange/AxoDataExchange.cs b/src/data/src/AXOpen.Data/DataExchange/AxoDataExchange.cs
index 18bdf7faa..49bc25bdb 100644
--- a/src/data/src/AXOpen.Data/DataExchange/AxoDataExchange.cs
+++ b/src/data/src/AXOpen.Data/DataExchange/AxoDataExchange.cs
@@ -6,6 +6,7 @@
// Third party licenses: https://github.com/ix-ax/axsharp/blob/dev/notices.md
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
@@ -181,16 +182,18 @@ public IEnumerable GetRecords(string identifier)
return DataRepository.GetRecords(identifier).Cast();
}
+ private Stopwatch sw = new Stopwatch();
+
///
public async Task RemoteCreate(string identifier)
{
+ sw.Restart();
await Operation.ReadAsync();
await DataEntity.DataEntityId.SetAsync(identifier);
-
- var cloned = await ((ITwinObject)DataEntity).OnlineToPlain();
-
+ var cloned = await ((ITwinObject)DataEntity).OnlineToPlain();
Repository.Create(identifier, cloned);
-
+ sw.Stop();
+ AxoApplication.Current.Logger.Information($"Record '{identifier}' created in '{this.Symbol}' in '{sw.ElapsedMilliseconds} ms'", this, AxoApplication.Current.ControllerIdentity);
return true;
}
@@ -199,9 +202,12 @@ public async Task RemoteRead(string identifier)
{
try
{
+ sw.Restart();
await Operation.ReadAsync();
var record = Repository.Read(identifier);
await ((ITwinObject)DataEntity).PlainToOnline(record);
+ sw.Stop();
+ AxoApplication.Current.Logger.Information($"Record '{identifier}' read from '{this.Symbol}' in '{sw.ElapsedMilliseconds} ms'", this, AxoApplication.Current.ControllerIdentity);
return true;
}
catch (Exception exception)
@@ -213,6 +219,7 @@ public async Task RemoteRead(string identifier)
///
public async Task RemoteUpdate(string identifier)
{
+ sw.Restart();
await Operation.ReadAsync();
await DataEntity.DataEntityId.SetAsync(identifier);
@@ -220,29 +227,39 @@ public async Task RemoteUpdate(string identifier)
cloned.Hash = HashHelper.CreateHash(cloned);
Repository.Update(identifier, cloned);
+ sw.Stop();
+ AxoApplication.Current.Logger.Information($"Record '{identifier}' updated in '{this.Symbol}' in '{sw.ElapsedMilliseconds} ms'", this, AxoApplication.Current.ControllerIdentity);
return true;
}
///
public async Task RemoteDelete(string identifier)
{
+ sw.Restart();
await Operation.ReadAsync();
await DataEntity.DataEntityId.SetAsync(identifier);
Repository.Delete(identifier);
+ sw.Stop();
+ AxoApplication.Current.Logger.Information($"Record '{identifier}' deleted in '{this.Symbol}' in '{sw.ElapsedMilliseconds} ms'", this, AxoApplication.Current.ControllerIdentity);
return true;
}
///
public async Task RemoteEntityExist(string identifier)
{
+ sw.Restart();
await Operation.ReadAsync();
await DataEntity.DataEntityId.SetAsync(identifier);
- return Repository.Exists(identifier);
+ var retVal = Repository.Exists(identifier);
+ sw.Stop();
+ AxoApplication.Current.Logger.Information($"Information about record '{identifier}' existence in '{this.Symbol}' retrieved in '{sw.ElapsedMilliseconds} ms'", this, AxoApplication.Current.ControllerIdentity);
+ return retVal;
}
///
public async Task RemoteCreateOrUpdate(string identifier)
{
+ sw.Restart();
await Operation.ReadAsync();
await DataEntity.DataEntityId.SetAsync(identifier);
@@ -258,6 +275,10 @@ public async Task RemoteCreateOrUpdate(string identifier)
{
Repository.Create(identifier, cloned);
}
+
+ sw.Stop();
+ AxoApplication.Current.Logger.Information($"Record '{identifier}' created in '{this.Symbol}' in '{sw.ElapsedMilliseconds} ms' using `Create or update` function.", this, AxoApplication.Current.ControllerIdentity);
+
return true;
}