From 5ca683416290cca6e58a21224325f54ae81bc6f0 Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Wed, 23 Nov 2022 10:50:43 +0100 Subject: [PATCH 1/7] Updated DRES results logging to include stage index for staged queries. --- .../VitrivrVR/Submission/DresClientManager.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs index 152808a..5b7d758 100644 --- a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs +++ b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs @@ -18,7 +18,7 @@ namespace VitrivrVR.Submission { public class DresClientManager : MonoBehaviour { - public static DresClient Instance; + private static DresClient _instance; private static readonly List InteractionEvents = new(); private static float _interactionEventTimer; @@ -33,16 +33,16 @@ private async void Start() if (ConfigManager.Config.allowInvalidCertificate) { - ServicePointManager.ServerCertificateValidationCallback += - (sender, certificate, chain, sslPolicyErrors) => true; + ServicePointManager.ServerCertificateValidationCallback += (_, _, _, _) => true; + // (sender, certificate, chain, sslPolicyErrors) => true; } - Instance = new DresClient(); - await Instance.Login(); + _instance = new DresClient(); + await _instance.Login(); var logDir = ConfigManager.Config.logFileLocation; var startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - var username = Instance.UserDetails.Username; - var session = Instance.UserDetails.SessionId; + var username = _instance.UserDetails.Username; + var session = _instance.UserDetails.SessionId; _interactionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_interaction.txt"); _resultsLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_results.txt"); _submissionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_submission.txt"); @@ -78,7 +78,7 @@ public static async void SubmitResult(string mediaObjectId, int? frame = null) try { - var result = await Instance.SubmitResult(mediaObjectId, frame); + var result = await _instance.SubmitResult(mediaObjectId, frame); NotificationController.Notify($"Submission: {result.Submission}"); } catch (Exception e) @@ -167,7 +167,7 @@ public static async void LogResults(string sortType, List<(ScoredSegment segment var queryEventsList = queryEvents.ToList(); try { - var success = await Instance.LogResults(timestamp, sortType, "top", queryResultsList, queryEventsList); + var success = await _instance.LogResults(timestamp, sortType, "top", queryResultsList, queryEventsList); if (!success.Status) { @@ -183,7 +183,7 @@ public static async void LogResults(string sortType, List<(ScoredSegment segment { try { - using var file = new StreamWriter(_resultsLogPath, true); + await using var file = new StreamWriter(_resultsLogPath, true); var jsonResults = string.Join(",", queryResultsList.Select(q => q.ToJson().Replace("\n", ""))); var jsonEvents = string.Join(",", queryEventsList.Select(q => q.ToJson().Replace("\n", ""))); var resultLog = $"{timestamp},{sortType},top,[{jsonResults}],[{jsonEvents}]"; @@ -220,7 +220,7 @@ public static void LogResults(string sortType, IEnumerable result { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - var queryEvents = query.Stages.SelectMany(stage => stage.Terms.Select(term => + var queryEvents = query.Stages.SelectMany((stage, si) => stage.Terms.Select(term => { // Convert term type to Dres category var category = TermTypeToDresCategory(term.Type); @@ -228,7 +228,8 @@ public static void LogResults(string sortType, IEnumerable result var type = string.Join(",", term.Categories.Select(CategoryToType)); var value = term.Data; - return new QueryEvent(timestamp, category, type, value); + // Also provide stage index in type + return new QueryEvent(timestamp, category, $"{si}:{type}", value); })); var rankedResults = results.Select((segment, rank) => (segment, rank)).ToList(); @@ -274,7 +275,7 @@ private static async void LogInteraction() // Submit to DRES try { - var success = await Instance.LogQueryEvents(timestamp, InteractionEvents); + var success = await _instance.LogQueryEvents(timestamp, InteractionEvents); if (!success.Status) { From 15d716dbc560d4092c931ec48b490214e006cffb Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Wed, 23 Nov 2022 11:33:56 +0100 Subject: [PATCH 2/7] Fixed bug logging object as segment query results. --- .../VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs index 17aa41d..c1a51c1 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs @@ -110,11 +110,11 @@ protected override void Initialize() { if (queryData.Query != null) { - DresClientManager.LogResults("segment", _results, queryData.Query); + DresClientManager.LogResults("object", _results, queryData.Query); } else { - DresClientManager.LogResults("segment", _results, queryData.StagedQuery); + DresClientManager.LogResults("object", _results, queryData.StagedQuery); } } } From 3bbc6deace9cb0bb0d10702210f8c84cbe9839b5 Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Thu, 1 Dec 2022 11:15:06 +0100 Subject: [PATCH 3/7] Refactored results logging from DresClientManager to a new logging class separating file and DRES logging. --- Assets/Scripts/VitrivrVR/Logging.meta | 8 + .../VitrivrVR/Logging/LoggingController.cs | 155 ++++++++++++++++++ .../Logging/LoggingController.cs.meta | 3 + .../Display/CylinderObjectQueryDisplay.cs | 17 +- .../Query/Display/CylinderQueryDisplay.cs | 13 +- .../Display/CylinderTemporalQueryDisplay.cs | 8 +- .../VitrivrVR/Submission/DresClientManager.cs | 40 ++--- 7 files changed, 186 insertions(+), 58 deletions(-) create mode 100644 Assets/Scripts/VitrivrVR/Logging.meta create mode 100644 Assets/Scripts/VitrivrVR/Logging/LoggingController.cs create mode 100644 Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta diff --git a/Assets/Scripts/VitrivrVR/Logging.meta b/Assets/Scripts/VitrivrVR/Logging.meta new file mode 100644 index 0000000..4d675af --- /dev/null +++ b/Assets/Scripts/VitrivrVR/Logging.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b037eb8c67aa944928d91bb3b60e1885 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs new file mode 100644 index 0000000..4a928be --- /dev/null +++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using Org.Vitrivr.CineastApi.Model; +using Vitrivr.UnityInterface.CineastApi.Model.Data; +using VitrivrVR.Config; +using VitrivrVR.Notification; +using VitrivrVR.Submission; + +namespace VitrivrVR.Logging +{ + /// + /// Static class for all interaction and usage logs. + /// + /// The goal of this class is to separate the log sources from different kinds of loggers, such as file and + /// competition loggers. + /// + public static class LoggingController + { + private static readonly string StartDate = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); + private static readonly string LogDir = Path.Combine(ConfigManager.Config.logFileLocation, StartDate); + private static readonly string ResultLogLocation = Path.Combine(LogDir, "results.txt"); + + /// + /// Logs ranked results lists for similarity and staged similarity queries. + /// + /// The order in which the ranked results are displayed (e.g. by segment or object). + /// List of ranked results. + /// Query response containing the source query. + public static void LogQueryResults(string sortOrder, List results, QueryResponse queryResponse) + { + var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + + // Log to DRES + if (ConfigManager.Config.dresEnabled) + { + // Similarity query + if (queryResponse.Query != null) + { + DresClientManager.LogResults(timestamp, sortOrder, results, queryResponse.Query); + } + + // Staged query + if (queryResponse.StagedQuery != null) + { + DresClientManager.LogResults(timestamp, sortOrder, results, queryResponse.StagedQuery); + } + } + + // Log to file + if (ConfigManager.Config.writeLogsToFile) + { + LogQueryResultsToFile(timestamp, sortOrder, results, queryResponse); + } + } + + /// + /// Logs ranked results lists for temporal similarity queries. + /// + public static void LogQueryResults(string sortOrder, List results, + TemporalQueryResponse queryResponse) + { + var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + + // Log to DRES + if (ConfigManager.Config.dresEnabled) + { + DresClientManager.LogResults(timestamp, sortOrder, results, queryResponse.Query); + } + + // Log to file + if (ConfigManager.Config.writeLogsToFile) + { + LogQueryResultsToFile(timestamp, sortOrder, results, queryResponse); + } + } + + // TODO: Log submission + + // TODO: Log interaction + + #region FileLogger + + private static void EnsureDirectoryExists() + { + Directory.CreateDirectory(LogDir); + } + + private static async void LogQueryResultsToFile(long timestamp, string sortOrder, + IEnumerable results, + QueryResponse queryResponse) + { + EnsureDirectoryExists(); + try + { + await using var file = new StreamWriter(ResultLogLocation, true); + var serializableResults = results.Select(segment => new Dictionary + { + { "id", segment.segment.Id }, + { "score", segment.score.ToString(CultureInfo.InvariantCulture) } + }); + var jsonResults = JsonConvert.SerializeObject(serializableResults, Formatting.None); + var jsonQuery = QueryToJson(queryResponse); + + var resultLog = + $"{{\"timestamp\":{timestamp},\"sortOrder\":\"{sortOrder}\",\"query\":{jsonQuery},\"results\":{jsonResults}}}"; + await file.WriteLineAsync(resultLog); + } + catch (Exception e) + { + NotificationController.NotifyError($"Error logging to file: {e.Message}", e); + } + } + + private static async void LogQueryResultsToFile(long timestamp, string sortOrder, List results, + TemporalQueryResponse queryResponse) + { + EnsureDirectoryExists(); + try + { + await using var file = new StreamWriter(ResultLogLocation, true); + var jsonResults = JsonConvert.SerializeObject(results, Formatting.None); + var jsonQuery = JsonConvert.SerializeObject(queryResponse.Query, Formatting.None); + + var resultLog = + $"{{\"timestamp\":{timestamp},\"sortOrder\":\"{sortOrder}\",\"query\":{jsonQuery},\"results\":{jsonResults}}}"; + await file.WriteLineAsync(resultLog); + } + catch (Exception e) + { + NotificationController.NotifyError($"Error logging to file: {e.Message}", e); + } + } + + private static string QueryToJson(QueryResponse queryResponse) + { + if (queryResponse.Query != null) + { + return JsonConvert.SerializeObject(queryResponse.Query, Formatting.None); + } + + if (queryResponse.StagedQuery != null) + { + return JsonConvert.SerializeObject(queryResponse.StagedQuery, Formatting.None); + } + + throw new Exception("Query response contains neither similarity nor staged similarity query."); + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta new file mode 100644 index 0000000..34df72e --- /dev/null +++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 413dc264b46c4f46b6df685d1208687a +timeCreated: 1666274469 \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs index c1a51c1..c3ed505 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs @@ -6,6 +6,7 @@ using UnityEngine; using UnityEngine.InputSystem; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; using VitrivrVR.Submission; @@ -106,17 +107,7 @@ protected override void Initialize() _enqueued++; } - if (ConfigManager.Config.dresEnabled) - { - if (queryData.Query != null) - { - DresClientManager.LogResults("object", _results, queryData.Query); - } - else - { - DresClientManager.LogResults("object", _results, queryData.StagedQuery); - } - } + LoggingController.LogQueryResults("object", _results, queryData); } /// @@ -156,6 +147,8 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; + + DresClientManager.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}"); } } @@ -181,7 +174,7 @@ private async Task CreateResultObject(ScoredSegment result) else { _objectMap[objectId] = _mediaObjectSegmentDisplays.Count; - _mediaObjectSegmentDisplays.Add(new List {itemDisplay}); + _mediaObjectSegmentDisplays.Add(new List { itemDisplay }); } var index = _objectMap[objectId]; diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs index e6f9471..b8e83d2 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs @@ -5,6 +5,7 @@ using UnityEngine; using UnityEngine.InputSystem; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; using VitrivrVR.Submission; @@ -90,17 +91,7 @@ protected override void Initialize() _instantiationQueue.Enqueue(segment); } - if (ConfigManager.Config.dresEnabled) - { - if (queryData.Query != null) - { - DresClientManager.LogResults("segment", _results, queryData.Query); - } - else - { - DresClientManager.LogResults("segment", _results, queryData.StagedQuery); - } - } + LoggingController.LogQueryResults("segment", _results, queryData); } /// diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs index 0deab95..fb2d71e 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs @@ -5,6 +5,7 @@ using UnityEngine; using UnityEngine.InputSystem; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; using VitrivrVR.Submission; @@ -74,7 +75,7 @@ private void Update() protected override void Initialize() { _results = temporalQueryData.Results.Content; - + if (_results.Count == 0) { NotificationController.Notify("No results returned from query!"); @@ -86,10 +87,7 @@ protected override void Initialize() _instantiationQueue.Enqueue(temporalObject); } - if (ConfigManager.Config.dresEnabled) - { - DresClientManager.LogResults("temporal", _results, temporalQueryData.Query); - } + LoggingController.LogQueryResults("temporal", _results, temporalQueryData); } /// diff --git a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs index 5b7d758..d8940b4 100644 --- a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs +++ b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs @@ -24,7 +24,6 @@ public class DresClientManager : MonoBehaviour private static float _interactionEventTimer; private static string _interactionLogPath; - private static string _resultsLogPath; private static string _submissionLogPath; private async void Start() @@ -44,7 +43,6 @@ private async void Start() var username = _instance.UserDetails.Username; var session = _instance.UserDetails.SessionId; _interactionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_interaction.txt"); - _resultsLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_results.txt"); _submissionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_submission.txt"); NotificationController.Notify($"Dres connected: {username}"); @@ -144,8 +142,9 @@ private static async void LogSubmissionToFile(string mediaObjectId, int? frame) /// The query that lead to these results represented as enumerable of query events. /// Timestamp of result log. /// Skips trying to batch fetch segment data if true. - public static async void LogResults(string sortType, List<(ScoredSegment segment, int rank)> results, - IEnumerable queryEvents, long timestamp, bool assumeFullyFetched = false) + private static async void LogResults(string sortType, + IReadOnlyCollection<(ScoredSegment segment, int rank)> results, IEnumerable queryEvents, + long timestamp, bool assumeFullyFetched = false) { if (!assumeFullyFetched) { @@ -178,28 +177,11 @@ public static async void LogResults(string sortType, List<(ScoredSegment segment { NotificationController.Notify(e.Message); } - - if (ConfigManager.Config.writeLogsToFile) - { - try - { - await using var file = new StreamWriter(_resultsLogPath, true); - var jsonResults = string.Join(",", queryResultsList.Select(q => q.ToJson().Replace("\n", ""))); - var jsonEvents = string.Join(",", queryEventsList.Select(q => q.ToJson().Replace("\n", ""))); - var resultLog = $"{timestamp},{sortType},top,[{jsonResults}],[{jsonEvents}]"; - await file.WriteLineAsync(resultLog); - } - catch (Exception e) - { - NotificationController.NotifyError($"Error logging to file: {e.Message}", e); - } - } } - public static void LogResults(string sortType, IEnumerable results, SimilarityQuery query) + public static void LogResults(long timestamp, string sortType, IEnumerable results, + SimilarityQuery query) { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - var queryEvents = query.Terms.Select(term => { // Convert term type to Dres category @@ -216,10 +198,9 @@ public static void LogResults(string sortType, IEnumerable result LogResults(sortType, rankedResults, queryEvents, timestamp); } - public static void LogResults(string sortType, IEnumerable results, StagedSimilarityQuery query) + public static void LogResults(long timestamp, string sortType, IEnumerable results, + StagedSimilarityQuery query) { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - var queryEvents = query.Stages.SelectMany((stage, si) => stage.Terms.Select(term => { // Convert term type to Dres category @@ -237,10 +218,9 @@ public static void LogResults(string sortType, IEnumerable result LogResults(sortType, rankedResults, queryEvents, timestamp); } - public static void LogResults(string sortType, IEnumerable results, TemporalQuery query) + public static void LogResults(long timestamp, string sortType, IEnumerable results, + TemporalQuery query) { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - var queryEvents = query.Queries.SelectMany( (temporal, ti) => temporal.Stages.SelectMany( (stage, si) => stage.Terms.Select(term => @@ -363,7 +343,7 @@ private static QueryEvent.CategoryEnum TermTypeToDresCategory(QueryTerm.TypeEnum private static string RemovePrefix(string id) { var prefixLength = ConfigManager.Config.submissionIdPrefixLength; - return prefixLength > 0 ? id.Substring(prefixLength) : id; + return prefixLength > 0 ? id[prefixLength..] : id; } } } \ No newline at end of file From 7625e6f05d8712069477e463107c2bdb7e48c6d0 Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Thu, 1 Dec 2022 12:54:49 +0100 Subject: [PATCH 4/7] Refactored submission logging and fixed fast file logging through semaphores. --- .../VitrivrVR/Logging/LoggingController.cs | 54 ++++++++++++++++++- .../VitrivrVR/Submission/DresClientManager.cs | 25 +-------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs index 4a928be..37d3144 100644 --- a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs +++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Threading; using Newtonsoft.Json; using Org.Vitrivr.CineastApi.Model; using Vitrivr.UnityInterface.CineastApi.Model.Data; @@ -23,6 +24,10 @@ public static class LoggingController private static readonly string StartDate = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); private static readonly string LogDir = Path.Combine(ConfigManager.Config.logFileLocation, StartDate); private static readonly string ResultLogLocation = Path.Combine(LogDir, "results.txt"); + private static readonly string SubmissionLogLocation = Path.Combine(LogDir, "submission.txt"); + + private static readonly SemaphoreSlim SubmissionLogLock = new SemaphoreSlim(1, 1); + private static readonly SemaphoreSlim ResultLogLock = new SemaphoreSlim(1, 1); /// /// Logs ranked results lists for similarity and staged similarity queries. @@ -78,7 +83,15 @@ public static void LogQueryResults(string sortOrder, List result } } - // TODO: Log submission + public static void LogSubmission(string mediaObjectId, int? frame) + { + var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + // Log to file + if (ConfigManager.Config.writeLogsToFile) + { + LogSubmissionToFile(timestamp, mediaObjectId, frame); + } + } // TODO: Log interaction @@ -94,6 +107,7 @@ private static async void LogQueryResultsToFile(long timestamp, string sortOrder QueryResponse queryResponse) { EnsureDirectoryExists(); + await ResultLogLock.WaitAsync(); try { await using var file = new StreamWriter(ResultLogLocation, true); @@ -113,12 +127,17 @@ private static async void LogQueryResultsToFile(long timestamp, string sortOrder { NotificationController.NotifyError($"Error logging to file: {e.Message}", e); } + finally + { + ResultLogLock.Release(); + } } private static async void LogQueryResultsToFile(long timestamp, string sortOrder, List results, TemporalQueryResponse queryResponse) { EnsureDirectoryExists(); + await ResultLogLock.WaitAsync(); try { await using var file = new StreamWriter(ResultLogLocation, true); @@ -133,6 +152,10 @@ private static async void LogQueryResultsToFile(long timestamp, string sortOrder { NotificationController.NotifyError($"Error logging to file: {e.Message}", e); } + finally + { + ResultLogLock.Release(); + } } private static string QueryToJson(QueryResponse queryResponse) @@ -150,6 +173,35 @@ private static string QueryToJson(QueryResponse queryResponse) throw new Exception("Query response contains neither similarity nor staged similarity query."); } + private static async void LogSubmissionToFile(long timestamp, string mediaObjectId, int? frame) + { + EnsureDirectoryExists(); + await SubmissionLogLock.WaitAsync(); + try + { + await using var file = new StreamWriter(SubmissionLogLocation, true); + var dict = new Dictionary + { + { "timestamp", timestamp.ToString() }, + { "mediaObjectId", mediaObjectId } + }; + if (frame.HasValue) + dict["frame"] = frame.ToString(); + + var json = JsonConvert.SerializeObject(dict, Formatting.None); + + await file.WriteLineAsync(json); + } + catch (Exception e) + { + NotificationController.NotifyError($"Error logging to file: {e.Message}"); + } + finally + { + SubmissionLogLock.Release(); + } + } + #endregion } } \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs index d8940b4..e863322 100644 --- a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs +++ b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs @@ -12,6 +12,7 @@ using Vitrivr.UnityInterface.CineastApi.Model.Data; using Vitrivr.UnityInterface.CineastApi.Model.Registries; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Notification; namespace VitrivrVR.Submission @@ -24,7 +25,6 @@ public class DresClientManager : MonoBehaviour private static float _interactionEventTimer; private static string _interactionLogPath; - private static string _submissionLogPath; private async void Start() { @@ -43,7 +43,6 @@ private async void Start() var username = _instance.UserDetails.Username; var session = _instance.UserDetails.SessionId; _interactionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_interaction.txt"); - _submissionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_submission.txt"); NotificationController.Notify($"Dres connected: {username}"); if (ConfigManager.Config.writeLogsToFile) @@ -84,10 +83,7 @@ public static async void SubmitResult(string mediaObjectId, int? frame = null) NotificationController.Notify(e.Message); } - if (ConfigManager.Config.writeLogsToFile) - { - LogSubmissionToFile(mediaObjectId, frame); - } + LoggingController.LogSubmission(mediaObjectId, frame); } /// @@ -117,23 +113,6 @@ public static async void QuickSubmitSegment(SegmentData segment) } } - private static async void LogSubmissionToFile(string mediaObjectId, int? frame) - { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - try - { - await using var file = new StreamWriter(_submissionLogPath, true); - var row = $"{timestamp},{mediaObjectId}"; - if (frame != null) - row += $",{frame}"; - await file.WriteLineAsync(row); - } - catch (Exception e) - { - NotificationController.Notify($"Error logging to file: {e.Message}"); - } - } - /// /// Logs results to the connected Dres instance. /// From 43c24904b223e935dc58cad89406e74ab2b806a8 Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Thu, 1 Dec 2022 16:36:55 +0100 Subject: [PATCH 5/7] Refactored interaction logging. Moved interaction logging functions to LoggingController. Removed all file logging from DresClientManager. --- .../Input/Text/SceneTextInputController.cs | 16 ++--- .../VitrivrVR/Logging/LoggingController.cs | 61 +++++++++++++++++-- .../Media/Display/CanvasImageDisplay.cs | 14 +++-- .../Display/CanvasImageSequenceDisplay.cs | 26 +++++--- .../Media/Display/CanvasVideoDisplay.cs | 45 ++++++++------ .../Media/Display/MediaObjectSegmentView.cs | 21 ++++--- .../Display/CylinderObjectQueryDisplay.cs | 7 ++- .../Query/Display/CylinderQueryDisplay.cs | 4 +- .../Display/CylinderTemporalQueryDisplay.cs | 5 +- .../VitrivrVR/Query/QueryController.cs | 15 ++--- .../VitrivrVR/Submission/DresClientManager.cs | 43 ++----------- 11 files changed, 152 insertions(+), 105 deletions(-) diff --git a/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs b/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs index e927458..37bc451 100644 --- a/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs +++ b/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs @@ -1,7 +1,7 @@ using UnityEngine; using VitrivrVR.Config; using Dev.Dres.ClientApi.Model; -using VitrivrVR.Submission; +using VitrivrVR.Logging; namespace VitrivrVR.Input.Text { @@ -13,36 +13,36 @@ public class SceneTextInputController : MonoBehaviour public void InputText(string text) { TextInputManager.InputText(text); - DresClientManager.LogInteraction("keyboard", $"input {text}", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", $"input {text}", QueryEvent.CategoryEnum.TEXT); } public void InputBackspace() { TextInputManager.InputBackspace(); - DresClientManager.LogInteraction("keyboard", "backspace", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "backspace", QueryEvent.CategoryEnum.TEXT); } public void InputReturn() { TextInputManager.InputReturn(); - DresClientManager.LogInteraction("keyboard", "return", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "return", QueryEvent.CategoryEnum.TEXT); } public void InputLeftArrow() { TextInputManager.InputLeftArrow(); - DresClientManager.LogInteraction("keyboard", "ArrowLeft", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "ArrowLeft", QueryEvent.CategoryEnum.TEXT); } public void InputRightArrow() { TextInputManager.InputRightArrow(); - DresClientManager.LogInteraction("keyboard", "ArrowRight", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "ArrowRight", QueryEvent.CategoryEnum.TEXT); } public void InputTabulator() { TextInputManager.InputTabulator(); - DresClientManager.LogInteraction("keyboard", "Tabulator", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "Tabulator", QueryEvent.CategoryEnum.TEXT); } public void ReceiveDictationResult(string text) @@ -50,7 +50,7 @@ public void ReceiveDictationResult(string text) InputText(text); if (ConfigManager.Config.dresEnabled) { - DresClientManager.LogInteraction("speechToText", $"input {text} DeepSpeech", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("speechToText", $"input {text} DeepSpeech", QueryEvent.CategoryEnum.TEXT); } } } diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs index 37d3144..4d52709 100644 --- a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs +++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Threading; +using Dev.Dres.ClientApi.Model; using Newtonsoft.Json; using Org.Vitrivr.CineastApi.Model; using Vitrivr.UnityInterface.CineastApi.Model.Data; @@ -25,9 +26,13 @@ public static class LoggingController private static readonly string LogDir = Path.Combine(ConfigManager.Config.logFileLocation, StartDate); private static readonly string ResultLogLocation = Path.Combine(LogDir, "results.txt"); private static readonly string SubmissionLogLocation = Path.Combine(LogDir, "submission.txt"); + private static readonly string InteractionLogLocation = Path.Combine(LogDir, "interactions.txt"); - private static readonly SemaphoreSlim SubmissionLogLock = new SemaphoreSlim(1, 1); - private static readonly SemaphoreSlim ResultLogLock = new SemaphoreSlim(1, 1); + private static readonly SemaphoreSlim SubmissionLogLock = new(1, 1); + private static readonly SemaphoreSlim ResultLogLock = new(1, 1); + private static readonly SemaphoreSlim InteractionLogLock = new(1, 1); + + private static long CurrentTimestamp => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); /// /// Logs ranked results lists for similarity and staged similarity queries. @@ -37,7 +42,7 @@ public static class LoggingController /// Query response containing the source query. public static void LogQueryResults(string sortOrder, List results, QueryResponse queryResponse) { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + var timestamp = CurrentTimestamp; // Log to DRES if (ConfigManager.Config.dresEnabled) @@ -68,7 +73,7 @@ public static void LogQueryResults(string sortOrder, List results public static void LogQueryResults(string sortOrder, List results, TemporalQueryResponse queryResponse) { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + var timestamp = CurrentTimestamp; // Log to DRES if (ConfigManager.Config.dresEnabled) @@ -85,7 +90,7 @@ public static void LogQueryResults(string sortOrder, List result public static void LogSubmission(string mediaObjectId, int? frame) { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + var timestamp = CurrentTimestamp; // Log to file if (ConfigManager.Config.writeLogsToFile) { @@ -93,7 +98,22 @@ public static void LogSubmission(string mediaObjectId, int? frame) } } - // TODO: Log interaction + public static void LogInteraction(string type, string value, QueryEvent.CategoryEnum category) + { + var timestamp = CurrentTimestamp; + + // Log to DRES + if (ConfigManager.Config.dresEnabled) + { + DresClientManager.LogInteraction(timestamp, type, value, category); + } + + // Log to file + if (ConfigManager.Config.writeLogsToFile) + { + LogInteractionToFile(timestamp, type, value, category.ToString()); + } + } #region FileLogger @@ -202,6 +222,35 @@ private static async void LogSubmissionToFile(long timestamp, string mediaObject } } + private static async void LogInteractionToFile(long timestamp, string type, string value, string category) + { + EnsureDirectoryExists(); + await InteractionLogLock.WaitAsync(); + try + { + await using var file = new StreamWriter(InteractionLogLocation, true); + var dict = new Dictionary + { + { "timestamp", timestamp.ToString() }, + { "type", type }, + { "value", value }, + { "category", category } + }; + + var json = JsonConvert.SerializeObject(dict, Formatting.None); + + await file.WriteLineAsync(json); + } + catch (Exception e) + { + NotificationController.NotifyError($"Error logging to file: {e.Message}"); + } + finally + { + InteractionLogLock.Release(); + } + } + #endregion } } \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs index 714cdba..3328092 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using TMPro; using UnityEngine; @@ -8,6 +9,7 @@ using Vitrivr.UnityInterface.CineastApi.Model.Data; using Vitrivr.UnityInterface.CineastApi.Model.Registries; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Notification; using VitrivrVR.Submission; using VitrivrVR.UI; @@ -67,7 +69,7 @@ public override async void Initialize(ScoredSegment scoredSegment, Action onClos if (ConfigManager.Config.dresEnabled) { submitButton.SetActive(true); - DresClientManager.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}"); + LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}", QueryEvent.CategoryEnum.BROWSING); } } @@ -79,7 +81,7 @@ public void Close() private void OnDestroy() { - DresClientManager.LogInteraction("imageDisplay", $"closed {_mediaObject.Id} {Segment.Id}"); + LoggingController.LogInteraction("imageDisplay", $"closed {_mediaObject.Id} {Segment.Id}", QueryEvent.CategoryEnum.BROWSING); } public async void ToggleMetadata() @@ -88,7 +90,7 @@ public async void ToggleMetadata() { Destroy(_metadataTable); _metadataShown = false; - DresClientManager.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); return; } @@ -123,7 +125,7 @@ public async void ToggleMetadata() var uiTableTransform = _metadataTable.GetComponent(); uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto - DresClientManager.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}"); + LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); } public async void ToggleTagList() @@ -132,7 +134,7 @@ public async void ToggleTagList() { Destroy(_tagList.gameObject); _tagListShown = false; - DresClientManager.LogInteraction("segmentTags", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); return; } @@ -157,7 +159,7 @@ public async void ToggleTagList() tagItem.GetComponentInChildren().text = tagData.Name; } - DresClientManager.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}"); + LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", QueryEvent.CategoryEnum.BROWSING); } public void Submit() diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs index c79d276..4a3beb3 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using TMPro; using UnityEngine; @@ -8,6 +9,7 @@ using Vitrivr.UnityInterface.CineastApi.Model.Data; using Vitrivr.UnityInterface.CineastApi.Model.Registries; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Notification; using VitrivrVR.Submission; using VitrivrVR.UI; @@ -31,7 +33,7 @@ public class CanvasImageSequenceDisplay : MediaDisplay /// /// The number of neighbors to show in the segment view. /// - private const int MAXNeighbors = 200; + private const int MaxNeighbors = 200; private ScoredSegment _scoredSegment; private SegmentData Segment => _scoredSegment.segment; @@ -76,8 +78,10 @@ public override async void Initialize(ScoredSegment scoredSegment, Action onClos if (ConfigManager.Config.dresEnabled) { submitButton.SetActive(true); - DresClientManager.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}"); } + + LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}", + QueryEvent.CategoryEnum.BROWSING); } public void Close() @@ -93,7 +97,8 @@ private void OnDestroy() Destroy(_objectSegmentView); } - DresClientManager.LogInteraction("imageSequenceDisplay", $"closed {_mediaObject.Id} {Segment.Id}"); + LoggingController.LogInteraction("imageSequenceDisplay", $"closed {_mediaObject.Id} {Segment.Id}", + QueryEvent.CategoryEnum.BROWSING); } public async void ToggleMetadata() @@ -102,7 +107,8 @@ public async void ToggleMetadata() { Destroy(_metadataTable); _metadataShown = false; - DresClientManager.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); return; } @@ -137,7 +143,8 @@ public async void ToggleMetadata() var uiTableTransform = _metadataTable.GetComponent(); uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto - DresClientManager.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}"); + LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); } public async void ToggleTagList() @@ -146,7 +153,7 @@ public async void ToggleTagList() { Destroy(_tagList.gameObject); _tagListShown = false; - DresClientManager.LogInteraction("segmentTags", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); return; } @@ -171,7 +178,8 @@ public async void ToggleTagList() tagItem.GetComponentInChildren().text = tagData.Name; } - DresClientManager.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}"); + LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", + QueryEvent.CategoryEnum.BROWSING); } public async void ShowObjectSegmentView() @@ -183,8 +191,8 @@ public async void ShowObjectSegmentView() else { var index = await Segment.GetSequenceNumber(); - var min = index - MAXNeighbors; - var max = index + MAXNeighbors; + var min = index - MaxNeighbors; + var max = index + MaxNeighbors; var t = transform; _objectSegmentView = Instantiate(mediaObjectSegmentViewPrefab, t.position - 0.2f * t.forward, t.rotation); _objectSegmentView.GetComponentInChildren() diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs index 6e72a50..7ae0e42 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using TMPro; using UnityEngine; @@ -15,6 +16,7 @@ using Vitrivr.UnityInterface.CineastApi.Model.Registries; using Vitrivr.UnityInterface.CineastApi.Utils; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Media.Controller; using VitrivrVR.Notification; using VitrivrVR.Query; @@ -116,7 +118,8 @@ public override async void Initialize(ScoredSegment segment, Action onClose) if (ConfigManager.Config.dresEnabled) { submitButton.SetActive(true); - DresClientManager.LogInteraction("videoPlayer", $"initialized {_mediaObject.Id} {_segment.Id}"); + LoggingController.LogInteraction("videoPlayer", $"initialized {_mediaObject.Id} {_segment.Id}", + QueryEvent.CategoryEnum.BROWSING); } } @@ -133,7 +136,8 @@ private void OnDestroy() Destroy(_objectSegmentView); } - DresClientManager.LogInteraction("videoPlayer", $"closed {_mediaObject.Id} {_segment.Id}"); + LoggingController.LogInteraction("videoPlayer", $"closed {_mediaObject.Id} {_segment.Id}", + QueryEvent.CategoryEnum.BROWSING); } public void ShowObjectSegmentView() @@ -157,7 +161,8 @@ public async void ToggleMetadata() { Destroy(_metadataTable); _metadataShown = false; - DresClientManager.LogInteraction("mediaObjectMetadata", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("mediaObjectMetadata", $"closed {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); return; } @@ -194,7 +199,8 @@ public async void ToggleMetadata() var uiTableTransform = _metadataTable.GetComponent(); uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto - DresClientManager.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}"); + LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); } public async void ToggleTagList() @@ -203,7 +209,7 @@ public async void ToggleTagList() { Destroy(_tagList.gameObject); _tagListShown = false; - DresClientManager.LogInteraction("segmentTags", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); return; } @@ -231,7 +237,8 @@ public async void ToggleTagList() tagItem.GetComponentInChildren().text = tagData.Name; } - DresClientManager.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {segment.Id}"); + LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {segment.Id}", + QueryEvent.CategoryEnum.BROWSING); } public void SubmitCurrentFrame() @@ -244,7 +251,7 @@ public void SubmitCurrentFrame() var frame = _videoPlayerController.Frame; - DresClientManager.SubmitResult(_mediaObject.Id, (int) frame); + DresClientManager.SubmitResult(_mediaObject.Id, (int)frame); } public void SetVolume(float volume) @@ -256,7 +263,7 @@ public void QueryByCurrentFrame() { var frame = _videoPlayerController.GetCurrentFrame(); var term = QueryTermBuilder.BuildImageTermForCategories(frame, ConfigManager.Config.defaultImageCategories); - QueryController.Instance.RunQuery(new List {term}); + QueryController.Instance.RunQuery(new List { term }); } private void Awake() @@ -306,12 +313,13 @@ private void Skip(InputAction.CallbackContext context) UpdateText(time); } - DresClientManager.LogInteraction("videoPlayer", $"skipped {_mediaObject.Id} {time} {sign}"); + LoggingController.LogInteraction("videoPlayer", $"skipped {_mediaObject.Id} {time} {sign}", + QueryEvent.CategoryEnum.BROWSING); } private void Update() { - if (_videoPlayerController is {IsPlaying: true}) + if (_videoPlayerController is { IsPlaying: true }) { var time = _videoPlayerController.ClockTime; UpdateProgressIndicator(time); @@ -324,12 +332,14 @@ public void OnClick(PointerEventData pointerEventData) if (_videoPlayerController.IsPlaying) { _videoPlayerController.Pause(); - DresClientManager.LogInteraction("videoPlayer", $"pause {_mediaObject.Id} {_videoPlayerController.ClockTime}"); + LoggingController.LogInteraction("videoPlayer", $"pause {_mediaObject.Id} {_videoPlayerController.ClockTime}", + QueryEvent.CategoryEnum.BROWSING); } else { _videoPlayerController.Play(); - DresClientManager.LogInteraction("videoPlayer", $"play {_mediaObject.Id} {_videoPlayerController.ClockTime}"); + LoggingController.LogInteraction("videoPlayer", $"play {_mediaObject.Id} {_videoPlayerController.ClockTime}", + QueryEvent.CategoryEnum.BROWSING); } } @@ -348,7 +358,8 @@ private void OnClickProgressBar(PointerEventData pointerEventData) UpdateProgressIndicator(newTime); UpdateText(newTime); - DresClientManager.LogInteraction("videoPlayer", $"jump {_mediaObject.Id} {newTime}"); + LoggingController.LogInteraction("videoPlayer", $"jump {_mediaObject.Id} {newTime}", + QueryEvent.CategoryEnum.BROWSING); } private void SetVideoTime(double time) @@ -420,7 +431,7 @@ private IEnumerator InstantiateSegmentIndicators(IEnumerable segmentStart var i = 0; foreach (var segStart in segmentStarts) { - progressTexture.SetPixel((int) (999 * (segStart / _videoPlayerController.Length)), 0, Color.black); + progressTexture.SetPixel((int)(999 * (segStart / _videoPlayerController.Length)), 0, Color.black); i++; if (i == InstantiationBatch) { @@ -442,7 +453,7 @@ private void ErrorEncountered(VideoPlayer videoPlayer, string error) private void UpdateProgressIndicator(double time) { progressIndicator.anchoredPosition = - new Vector2((float) (progressBar.rect.width * time / _videoPlayerController.Length), 0); + new Vector2((float)(progressBar.rect.width * time / _videoPlayerController.Length), 0); } private async void UpdateText(double time) @@ -476,8 +487,8 @@ private async Task GetCurrentSegment(double time) private void SetSegmentIndicator(double start, double end, double length, RectTransform rt) { var rect = progressBar.rect; - rt.anchoredPosition = new Vector2((float) (rect.width * start / length), 0); - rt.sizeDelta = new Vector2((float) (rect.width * (end - start) / length), 0); + rt.anchoredPosition = new Vector2((float)(rect.width * start / length), 0); + rt.sizeDelta = new Vector2((float)(rect.width * (end - start) / length), 0); } } } \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs b/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs index 61e29df..34bd328 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs @@ -3,13 +3,14 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Dev.Dres.ClientApi.Model; using UnityEngine; using Vitrivr.UnityInterface.CineastApi; using Vitrivr.UnityInterface.CineastApi.Model.Data; using VitrivrVR.Interaction.System; using VitrivrVR.Interaction.System.Grab; +using VitrivrVR.Logging; using VitrivrVR.Media.Controller; -using VitrivrVR.Submission; namespace VitrivrVR.Media.Display { @@ -42,7 +43,8 @@ private void OnTriggerEnter(Collider other) if (other.TryGetComponent(out var interactor)) { _enteredInteractors.Add(interactor, -1); - DresClientManager.LogInteraction("videoSummary", $"browse started {_mediaObject.Id}"); + LoggingController.LogInteraction("videoSummary", $"browse started {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); } } @@ -57,7 +59,8 @@ private void OnTriggerExit(Collider other) } _enteredInteractors.Remove(interactor); - DresClientManager.LogInteraction("videoSummary", $"browse stopped {_mediaObject.Id}"); + LoggingController.LogInteraction("videoSummary", $"browse stopped {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); } } @@ -87,7 +90,7 @@ private void OnTriggerExit(Collider other) private void OnDestroy() { - DresClientManager.LogInteraction("videoSummary", $"closed {_mediaObject.Id}"); + LoggingController.LogInteraction("videoSummary", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); } public async void Initialize(ObjectData mediaObject, Action onSegmentSelection, int min = 0, @@ -116,7 +119,8 @@ await Task.WhenAll(segments.Select(async segment => StartCoroutine(InstantiateSegmentIndicators(segmentInfo, segmentInfo.Length)); // TODO: Translate type in DresClientManager to support other media object types - DresClientManager.LogInteraction("videoSummary", $"initialized {_mediaObject.Id}"); + LoggingController.LogInteraction("videoSummary", $"initialized {_mediaObject.Id}", + QueryEvent.CategoryEnum.BROWSING); } public override void OnInteraction(Transform interactor, bool start) @@ -125,7 +129,8 @@ public override void OnInteraction(Transform interactor, bool start) var rawIndex = GetSegmentIndex(interactor); var segmentIndex = rawIndex + _minIndex - 1; _onSegmentSelection(segmentIndex, interactor.position); - DresClientManager.LogInteraction("videoSummary", $"selected {_mediaObject.Id} {segmentIndex}"); + LoggingController.LogInteraction("videoSummary", $"selected {_mediaObject.Id} {segmentIndex}", + QueryEvent.CategoryEnum.BROWSING); } private IEnumerator InstantiateSegmentIndicators(IEnumerable<(SegmentData segment, int seqNum)> segmentInfo, @@ -139,7 +144,7 @@ private IEnumerator InstantiateSegmentIndicators(IEnumerable<(SegmentData segmen var thumbnail = Instantiate(thumbnailPrefab, transform); thumbnail.url = thumbnailUrl; - thumbnail.transform.localPosition = Vector3.forward * ((float) (seqNum - _minIndex) / numSegments - 0.5f); + thumbnail.transform.localPosition = Vector3.forward * ((float)(seqNum - _minIndex) / numSegments - 0.5f); _thumbnails[seqNum - _minIndex] = thumbnail; @@ -192,7 +197,7 @@ private void SetThumbnailHeight(int index, bool selected) private int GetSegmentIndex(Transform other) { var otherTransform = transform.InverseTransformPoint(other.position); - return (int) Mathf.Min(Mathf.Max((otherTransform.z + 0.5f) * _thumbnails.Length, 0), _thumbnails.Length - 1); + return (int)Mathf.Min(Mathf.Max((otherTransform.z + 0.5f) * _thumbnails.Length, 0), _thumbnails.Length - 1); } } } \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs index c3ed505..0c7f8b3 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Dev.Dres.ClientApi.Model; using Vitrivr.UnityInterface.CineastApi.Model.Data; using UnityEngine; using UnityEngine.InputSystem; @@ -9,7 +10,6 @@ using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; -using VitrivrVR.Submission; namespace VitrivrVR.Query.Display { @@ -147,8 +147,9 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; - - DresClientManager.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}"); + + LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", + QueryEvent.CategoryEnum.BROWSING); } } diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs index b8e83d2..9dd80be 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Dev.Dres.ClientApi.Model; using Vitrivr.UnityInterface.CineastApi.Model.Data; using UnityEngine; using UnityEngine.InputSystem; @@ -8,7 +9,6 @@ using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; -using VitrivrVR.Submission; namespace VitrivrVR.Query.Display { @@ -131,7 +131,7 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; - DresClientManager.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}"); + LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", QueryEvent.CategoryEnum.BROWSING); } } diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs index fb2d71e..c7b1e52 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using UnityEngine; using UnityEngine.InputSystem; @@ -8,7 +9,6 @@ using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; -using VitrivrVR.Submission; namespace VitrivrVR.Query.Display { @@ -127,7 +127,8 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; - DresClientManager.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}"); + LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", + QueryEvent.CategoryEnum.BROWSING); } } diff --git a/Assets/Scripts/VitrivrVR/Query/QueryController.cs b/Assets/Scripts/VitrivrVR/Query/QueryController.cs index 95c4b4b..0f3bd5a 100644 --- a/Assets/Scripts/VitrivrVR/Query/QueryController.cs +++ b/Assets/Scripts/VitrivrVR/Query/QueryController.cs @@ -8,10 +8,11 @@ using UnityEngine.Events; using Vitrivr.UnityInterface.CineastApi.Model.Data; using VitrivrVR.Config; +using VitrivrVR.Logging; using VitrivrVR.Notification; using VitrivrVR.Query.Display; using VitrivrVR.Query.Term; -using VitrivrVR.Submission; +using static Dev.Dres.ClientApi.Model.QueryEvent; namespace VitrivrVR.Query { @@ -97,7 +98,7 @@ public void RunQuery(QueryTermManager queryTermManager) RunQuery(stages.First()); return; } - + // With stages RunQuery(stages); return; @@ -184,7 +185,7 @@ public async void RunQuery(List> stages) timer.transform.localRotation = Quaternion.identity; timer.SetActive(false); } - + public async void RunQuery(List>> temporalTerms) { var localGuid = Guid.NewGuid(); @@ -242,7 +243,7 @@ public void SelectQuery(int index) queryFocusEvent.Invoke(CurrentQuery, index); CurrentQuery = index; - DresClientManager.LogInteraction("queryManagement", $"select {index}"); + LoggingController.LogInteraction("queryManagement", $"select {index}", CategoryEnum.BROWSING); } /// @@ -279,7 +280,7 @@ public void RemoveQuery(int index) queryRemovedEvent.Invoke(index); Destroy(queries[index].gameObject); queries.RemoveAt(index); - DresClientManager.LogInteraction("queryManagement", $"delete {index}"); + LoggingController.LogInteraction("queryManagement", $"delete {index}", CategoryEnum.BROWSING); } public void RemoveAllQueries() @@ -296,7 +297,7 @@ public void ClearQuery() SetQueryActive(CurrentQuery, false); queryFocusEvent.Invoke(CurrentQuery, -1); CurrentQuery = -1; - DresClientManager.LogInteraction("queryManagement", "clear"); + LoggingController.LogInteraction("queryManagement", "clear", CategoryEnum.BROWSING); } /// @@ -342,7 +343,7 @@ private void InstantiateQueryDisplay(QueryResponse queryData) queryFocusEvent.Invoke(CurrentQuery, queryIndex); CurrentQuery = queryIndex; } - + private void InstantiateQueryDisplay(TemporalQueryResponse queryData) { if (CurrentQuery != -1) diff --git a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs index e863322..9d65cd4 100644 --- a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs +++ b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; @@ -24,8 +23,6 @@ public class DresClientManager : MonoBehaviour private static readonly List InteractionEvents = new(); private static float _interactionEventTimer; - private static string _interactionLogPath; - private async void Start() { if (!ConfigManager.Config.dresEnabled) return; @@ -38,17 +35,8 @@ private async void Start() _instance = new DresClient(); await _instance.Login(); - var logDir = ConfigManager.Config.logFileLocation; - var startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var username = _instance.UserDetails.Username; - var session = _instance.UserDetails.SessionId; - _interactionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_interaction.txt"); - NotificationController.Notify($"Dres connected: {username}"); - - if (ConfigManager.Config.writeLogsToFile) - { - Directory.CreateDirectory(ConfigManager.Config.logFileLocation); - } + NotificationController.Notify($"DRES connected: {username}"); } private void Update() @@ -114,7 +102,7 @@ public static async void QuickSubmitSegment(SegmentData segment) } /// - /// Logs results to the connected Dres instance. + /// Logs results to the connected DRES instance. /// /// The sorting of the results display. /// The results as list of scored segments. @@ -163,7 +151,7 @@ public static void LogResults(long timestamp, string sortType, IEnumerable { - // Convert term type to Dres category + // Convert term type to DRES category var category = TermTypeToDresCategory(term.Type); var type = string.Join(",", term.Categories.Select(CategoryToType)); @@ -182,7 +170,7 @@ public static void LogResults(long timestamp, string sortType, IEnumerable stage.Terms.Select(term => { - // Convert term type to Dres category + // Convert term type to DRES category var category = TermTypeToDresCategory(term.Type); var type = string.Join(",", term.Categories.Select(CategoryToType)); @@ -204,7 +192,7 @@ public static void LogResults(long timestamp, string sortType, IEnumerable temporal.Stages.SelectMany( (stage, si) => stage.Terms.Select(term => { - // Convert term type to Dres category + // Convert term type to DRES category var category = TermTypeToDresCategory(term.Type); var type = string.Join(",", term.Categories.Select(CategoryToType)); @@ -246,33 +234,14 @@ private static async void LogInteraction() NotificationController.NotifyError($"Error logging interaction: {e.Message}", e); } - var events = InteractionEvents.ToArray(); InteractionEvents.Clear(); - - // Write to file - if (ConfigManager.Config.writeLogsToFile) - { - try - { - using var file = new StreamWriter(_interactionLogPath, true); - foreach (var interactionEvent in events) - { - await file.WriteLineAsync(interactionEvent.ToJson().Replace("\n", "")); - } - } - catch (Exception e) - { - NotificationController.NotifyError($"Error logging to file: {e.Message}", e); - } - } } - public static void LogInteraction(string type, string value, + public static void LogInteraction(long timestamp, string type, string value, QueryEvent.CategoryEnum category = QueryEvent.CategoryEnum.BROWSING) { if (!ConfigManager.Config.dresEnabled) return; - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var queryEvent = new QueryEvent(timestamp, category, type, value); InteractionEvents.Add(queryEvent); } From 1721a378e5591d9309f1e9a6753049bcbe1ae8e3 Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Fri, 2 Dec 2022 11:23:33 +0100 Subject: [PATCH 6/7] Implemented more fine grained custom interaction logging category enum. --- .../Input/Text/SceneTextInputController.cs | 26 +++++------ .../Scripts/VitrivrVR/Logging/Interaction.cs | 14 ++++++ .../VitrivrVR/Logging/Interaction.cs.meta | 3 ++ .../VitrivrVR/Logging/LoggingController.cs | 3 +- .../Media/Display/CanvasImageDisplay.cs | 16 ++++--- .../Display/CanvasImageSequenceDisplay.cs | 18 +++----- .../Media/Display/CanvasVideoDisplay.cs | 29 +++++------- .../Media/Display/MediaObjectSegmentView.cs | 19 ++++---- .../Display/CylinderObjectQueryDisplay.cs | 7 ++- .../Query/Display/CylinderQueryDisplay.cs | 6 +-- .../Display/CylinderTemporalQueryDisplay.cs | 5 +- .../VitrivrVR/Query/QueryController.cs | 12 ++--- .../VitrivrVR/Submission/DresClientManager.cs | 46 +++++++++++++------ 13 files changed, 111 insertions(+), 93 deletions(-) create mode 100644 Assets/Scripts/VitrivrVR/Logging/Interaction.cs create mode 100644 Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta diff --git a/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs b/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs index 37bc451..8a0972d 100644 --- a/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs +++ b/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs @@ -1,6 +1,4 @@ using UnityEngine; -using VitrivrVR.Config; -using Dev.Dres.ClientApi.Model; using VitrivrVR.Logging; namespace VitrivrVR.Input.Text @@ -13,45 +11,43 @@ public class SceneTextInputController : MonoBehaviour public void InputText(string text) { TextInputManager.InputText(text); - LoggingController.LogInteraction("keyboard", $"input {text}", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", $"input {text}", Logging.Interaction.TextInput); } public void InputBackspace() { TextInputManager.InputBackspace(); - LoggingController.LogInteraction("keyboard", "backspace", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "backspace", Logging.Interaction.TextInput); } - + public void InputReturn() { TextInputManager.InputReturn(); - LoggingController.LogInteraction("keyboard", "return", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "return", Logging.Interaction.TextInput); } - + public void InputLeftArrow() { TextInputManager.InputLeftArrow(); - LoggingController.LogInteraction("keyboard", "ArrowLeft", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "ArrowLeft", Logging.Interaction.TextInput); } - + public void InputRightArrow() { TextInputManager.InputRightArrow(); - LoggingController.LogInteraction("keyboard", "ArrowRight", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "ArrowRight", Logging.Interaction.TextInput); } + public void InputTabulator() { TextInputManager.InputTabulator(); - LoggingController.LogInteraction("keyboard", "Tabulator", QueryEvent.CategoryEnum.TEXT); + LoggingController.LogInteraction("keyboard", "Tabulator", Logging.Interaction.TextInput); } public void ReceiveDictationResult(string text) { InputText(text); - if (ConfigManager.Config.dresEnabled) - { - LoggingController.LogInteraction("speechToText", $"input {text} DeepSpeech", QueryEvent.CategoryEnum.TEXT); - } + LoggingController.LogInteraction("speechToText", $"input {text} DeepSpeech", Logging.Interaction.TextInput); } } } \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Logging/Interaction.cs b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs new file mode 100644 index 0000000..b6635ce --- /dev/null +++ b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs @@ -0,0 +1,14 @@ +namespace VitrivrVR.Logging +{ + public enum Interaction + { + TextInput, + QueryFormulation, + Query, + QueryManagement, + Browsing, + Filter, + ResultExpansion, + Other + } +} \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta new file mode 100644 index 0000000..12607da --- /dev/null +++ b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 003cde0f439d406e8414b0f6020035d4 +timeCreated: 1669973631 \ No newline at end of file diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs index 4d52709..c6d1ca0 100644 --- a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs +++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading; -using Dev.Dres.ClientApi.Model; using Newtonsoft.Json; using Org.Vitrivr.CineastApi.Model; using Vitrivr.UnityInterface.CineastApi.Model.Data; @@ -98,7 +97,7 @@ public static void LogSubmission(string mediaObjectId, int? frame) } } - public static void LogInteraction(string type, string value, QueryEvent.CategoryEnum category) + public static void LogInteraction(string type, string value, Interaction category) { var timestamp = CurrentTimestamp; diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs index 3328092..f82f19c 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using TMPro; using UnityEngine; @@ -14,6 +13,7 @@ using VitrivrVR.Submission; using VitrivrVR.UI; using VitrivrVR.Util; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Media.Display { @@ -69,8 +69,10 @@ public override async void Initialize(ScoredSegment scoredSegment, Action onClos if (ConfigManager.Config.dresEnabled) { submitButton.SetActive(true); - LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}", QueryEvent.CategoryEnum.BROWSING); } + + LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}", + ResultExpansion); } public void Close() @@ -81,7 +83,7 @@ public void Close() private void OnDestroy() { - LoggingController.LogInteraction("imageDisplay", $"closed {_mediaObject.Id} {Segment.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("imageDisplay", $"closed {_mediaObject.Id} {Segment.Id}", Other); } public async void ToggleMetadata() @@ -90,7 +92,7 @@ public async void ToggleMetadata() { Destroy(_metadataTable); _metadataShown = false; - LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", Other); return; } @@ -125,7 +127,7 @@ public async void ToggleMetadata() var uiTableTransform = _metadataTable.GetComponent(); uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto - LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", ResultExpansion); } public async void ToggleTagList() @@ -134,7 +136,7 @@ public async void ToggleTagList() { Destroy(_tagList.gameObject); _tagListShown = false; - LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", Other); return; } @@ -159,7 +161,7 @@ public async void ToggleTagList() tagItem.GetComponentInChildren().text = tagData.Name; } - LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", ResultExpansion); } public void Submit() diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs index 4a3beb3..5eee4d6 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using TMPro; using UnityEngine; @@ -14,6 +13,7 @@ using VitrivrVR.Submission; using VitrivrVR.UI; using VitrivrVR.Util; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Media.Display { @@ -81,7 +81,7 @@ public override async void Initialize(ScoredSegment scoredSegment, Action onClos } LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}", - QueryEvent.CategoryEnum.BROWSING); + ResultExpansion); } public void Close() @@ -97,8 +97,7 @@ private void OnDestroy() Destroy(_objectSegmentView); } - LoggingController.LogInteraction("imageSequenceDisplay", $"closed {_mediaObject.Id} {Segment.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("imageSequenceDisplay", $"closed {_mediaObject.Id} {Segment.Id}", Other); } public async void ToggleMetadata() @@ -107,8 +106,7 @@ public async void ToggleMetadata() { Destroy(_metadataTable); _metadataShown = false; - LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", Other); return; } @@ -143,8 +141,7 @@ public async void ToggleMetadata() var uiTableTransform = _metadataTable.GetComponent(); uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto - LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", ResultExpansion); } public async void ToggleTagList() @@ -153,7 +150,7 @@ public async void ToggleTagList() { Destroy(_tagList.gameObject); _tagListShown = false; - LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", Other); return; } @@ -178,8 +175,7 @@ public async void ToggleTagList() tagItem.GetComponentInChildren().text = tagData.Name; } - LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", ResultExpansion); } public async void ShowObjectSegmentView() diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs index 7ae0e42..4448191 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using TMPro; using UnityEngine; @@ -23,6 +22,7 @@ using VitrivrVR.Submission; using VitrivrVR.UI; using VitrivrVR.Util; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Media.Display { @@ -118,9 +118,9 @@ public override async void Initialize(ScoredSegment segment, Action onClose) if (ConfigManager.Config.dresEnabled) { submitButton.SetActive(true); - LoggingController.LogInteraction("videoPlayer", $"initialized {_mediaObject.Id} {_segment.Id}", - QueryEvent.CategoryEnum.BROWSING); } + + LoggingController.LogInteraction("videoPlayer", $"initialized {_mediaObject.Id} {_segment.Id}", ResultExpansion); } public void Close() @@ -136,8 +136,7 @@ private void OnDestroy() Destroy(_objectSegmentView); } - LoggingController.LogInteraction("videoPlayer", $"closed {_mediaObject.Id} {_segment.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoPlayer", $"closed {_mediaObject.Id} {_segment.Id}", Other); } public void ShowObjectSegmentView() @@ -161,8 +160,7 @@ public async void ToggleMetadata() { Destroy(_metadataTable); _metadataShown = false; - LoggingController.LogInteraction("mediaObjectMetadata", $"closed {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("mediaObjectMetadata", $"closed {_mediaObject.Id}", Other); return; } @@ -199,8 +197,7 @@ public async void ToggleMetadata() var uiTableTransform = _metadataTable.GetComponent(); uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto - LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", ResultExpansion); } public async void ToggleTagList() @@ -209,7 +206,7 @@ public async void ToggleTagList() { Destroy(_tagList.gameObject); _tagListShown = false; - LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", Other); return; } @@ -237,8 +234,7 @@ public async void ToggleTagList() tagItem.GetComponentInChildren().text = tagData.Name; } - LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {segment.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {segment.Id}", ResultExpansion); } public void SubmitCurrentFrame() @@ -313,8 +309,7 @@ private void Skip(InputAction.CallbackContext context) UpdateText(time); } - LoggingController.LogInteraction("videoPlayer", $"skipped {_mediaObject.Id} {time} {sign}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoPlayer", $"skipped {_mediaObject.Id} {time} {sign}", Browsing); } private void Update() @@ -333,13 +328,13 @@ public void OnClick(PointerEventData pointerEventData) { _videoPlayerController.Pause(); LoggingController.LogInteraction("videoPlayer", $"pause {_mediaObject.Id} {_videoPlayerController.ClockTime}", - QueryEvent.CategoryEnum.BROWSING); + Browsing); } else { _videoPlayerController.Play(); LoggingController.LogInteraction("videoPlayer", $"play {_mediaObject.Id} {_videoPlayerController.ClockTime}", - QueryEvent.CategoryEnum.BROWSING); + Browsing); } } @@ -359,7 +354,7 @@ private void OnClickProgressBar(PointerEventData pointerEventData) UpdateProgressIndicator(newTime); UpdateText(newTime); LoggingController.LogInteraction("videoPlayer", $"jump {_mediaObject.Id} {newTime}", - QueryEvent.CategoryEnum.BROWSING); + Browsing); } private void SetVideoTime(double time) diff --git a/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs b/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs index 34bd328..9e801a3 100644 --- a/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs +++ b/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Dev.Dres.ClientApi.Model; using UnityEngine; using Vitrivr.UnityInterface.CineastApi; using Vitrivr.UnityInterface.CineastApi.Model.Data; @@ -11,6 +10,7 @@ using VitrivrVR.Interaction.System.Grab; using VitrivrVR.Logging; using VitrivrVR.Media.Controller; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Media.Display { @@ -43,8 +43,8 @@ private void OnTriggerEnter(Collider other) if (other.TryGetComponent(out var interactor)) { _enteredInteractors.Add(interactor, -1); - LoggingController.LogInteraction("videoSummary", $"browse started {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoSummary", $"browse started {_mediaObject.Id} {interactor.name}", + Browsing); } } @@ -59,8 +59,8 @@ private void OnTriggerExit(Collider other) } _enteredInteractors.Remove(interactor); - LoggingController.LogInteraction("videoSummary", $"browse stopped {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoSummary", $"browse stopped {_mediaObject.Id} {interactor.name}", + Browsing); } } @@ -90,7 +90,7 @@ private void OnTriggerExit(Collider other) private void OnDestroy() { - LoggingController.LogInteraction("videoSummary", $"closed {_mediaObject.Id}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoSummary", $"closed {_mediaObject.Id}", Other); } public async void Initialize(ObjectData mediaObject, Action onSegmentSelection, int min = 0, @@ -119,8 +119,7 @@ await Task.WhenAll(segments.Select(async segment => StartCoroutine(InstantiateSegmentIndicators(segmentInfo, segmentInfo.Length)); // TODO: Translate type in DresClientManager to support other media object types - LoggingController.LogInteraction("videoSummary", $"initialized {_mediaObject.Id}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoSummary", $"initialized {_mediaObject.Id}", ResultExpansion); } public override void OnInteraction(Transform interactor, bool start) @@ -129,8 +128,8 @@ public override void OnInteraction(Transform interactor, bool start) var rawIndex = GetSegmentIndex(interactor); var segmentIndex = rawIndex + _minIndex - 1; _onSegmentSelection(segmentIndex, interactor.position); - LoggingController.LogInteraction("videoSummary", $"selected {_mediaObject.Id} {segmentIndex}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("videoSummary", $"selected {_mediaObject.Id} {segmentIndex} {interactor.name}", + ResultExpansion); } private IEnumerator InstantiateSegmentIndicators(IEnumerable<(SegmentData segment, int seqNum)> segmentInfo, diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs index 0c7f8b3..3700a80 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs @@ -2,14 +2,14 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Dev.Dres.ClientApi.Model; -using Vitrivr.UnityInterface.CineastApi.Model.Data; using UnityEngine; using UnityEngine.InputSystem; +using Vitrivr.UnityInterface.CineastApi.Model.Data; using VitrivrVR.Config; using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Query.Display { @@ -148,8 +148,7 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; - LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", Browsing); } } diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs index 9dd80be..af88232 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; -using Dev.Dres.ClientApi.Model; -using Vitrivr.UnityInterface.CineastApi.Model.Data; using UnityEngine; using UnityEngine.InputSystem; +using Vitrivr.UnityInterface.CineastApi.Model.Data; using VitrivrVR.Config; using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Query.Display { @@ -131,7 +131,7 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; - LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", Browsing); } } diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs index c7b1e52..aa6dc7e 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Dev.Dres.ClientApi.Model; using Org.Vitrivr.CineastApi.Model; using UnityEngine; using UnityEngine.InputSystem; @@ -9,6 +8,7 @@ using VitrivrVR.Logging; using VitrivrVR.Media.Display; using VitrivrVR.Notification; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Query.Display { @@ -127,8 +127,7 @@ private void Rotate(float degrees) _currentStart = enabledStart; _currentEnd = enabledEnd; - LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", - QueryEvent.CategoryEnum.BROWSING); + LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", Browsing); } } diff --git a/Assets/Scripts/VitrivrVR/Query/QueryController.cs b/Assets/Scripts/VitrivrVR/Query/QueryController.cs index 0f3bd5a..782850c 100644 --- a/Assets/Scripts/VitrivrVR/Query/QueryController.cs +++ b/Assets/Scripts/VitrivrVR/Query/QueryController.cs @@ -1,18 +1,18 @@ using System; using System.Collections.Generic; using System.Linq; -using Vitrivr.UnityInterface.CineastApi; -using Vitrivr.UnityInterface.CineastApi.Utils; using Org.Vitrivr.CineastApi.Model; using UnityEngine; using UnityEngine.Events; +using Vitrivr.UnityInterface.CineastApi; using Vitrivr.UnityInterface.CineastApi.Model.Data; +using Vitrivr.UnityInterface.CineastApi.Utils; using VitrivrVR.Config; using VitrivrVR.Logging; using VitrivrVR.Notification; using VitrivrVR.Query.Display; using VitrivrVR.Query.Term; -using static Dev.Dres.ClientApi.Model.QueryEvent; +using static VitrivrVR.Logging.Interaction; namespace VitrivrVR.Query { @@ -243,7 +243,7 @@ public void SelectQuery(int index) queryFocusEvent.Invoke(CurrentQuery, index); CurrentQuery = index; - LoggingController.LogInteraction("queryManagement", $"select {index}", CategoryEnum.BROWSING); + LoggingController.LogInteraction("queryManagement", $"select {index}", QueryManagement); } /// @@ -280,7 +280,7 @@ public void RemoveQuery(int index) queryRemovedEvent.Invoke(index); Destroy(queries[index].gameObject); queries.RemoveAt(index); - LoggingController.LogInteraction("queryManagement", $"delete {index}", CategoryEnum.BROWSING); + LoggingController.LogInteraction("queryManagement", $"delete {index}", QueryManagement); } public void RemoveAllQueries() @@ -297,7 +297,7 @@ public void ClearQuery() SetQueryActive(CurrentQuery, false); queryFocusEvent.Invoke(CurrentQuery, -1); CurrentQuery = -1; - LoggingController.LogInteraction("queryManagement", "clear", CategoryEnum.BROWSING); + LoggingController.LogInteraction("queryManagement", "clear", QueryManagement); } /// diff --git a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs index 9d65cd4..d398a05 100644 --- a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs +++ b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs @@ -13,6 +13,7 @@ using VitrivrVR.Config; using VitrivrVR.Logging; using VitrivrVR.Notification; +using static Dev.Dres.ClientApi.Model.QueryEvent; namespace VitrivrVR.Submission { @@ -237,12 +238,11 @@ private static async void LogInteraction() InteractionEvents.Clear(); } - public static void LogInteraction(long timestamp, string type, string value, - QueryEvent.CategoryEnum category = QueryEvent.CategoryEnum.BROWSING) + public static void LogInteraction(long timestamp, string type, string value, Logging.Interaction category) { if (!ConfigManager.Config.dresEnabled) return; - var queryEvent = new QueryEvent(timestamp, category, type, value); + var queryEvent = new QueryEvent(timestamp, InteractionToDresCategory(category), type, value); InteractionEvents.Add(queryEvent); } @@ -267,21 +267,37 @@ private static string CategoryToType(string category) }; } - private static QueryEvent.CategoryEnum TermTypeToDresCategory(QueryTerm.TypeEnum? type) + private static CategoryEnum TermTypeToDresCategory(QueryTerm.TypeEnum? type) { return type switch { - QueryTerm.TypeEnum.IMAGE => QueryEvent.CategoryEnum.IMAGE, - QueryTerm.TypeEnum.AUDIO => QueryEvent.CategoryEnum.OTHER, - QueryTerm.TypeEnum.MODEL3D => QueryEvent.CategoryEnum.OTHER, - QueryTerm.TypeEnum.LOCATION => QueryEvent.CategoryEnum.OTHER, - QueryTerm.TypeEnum.TIME => QueryEvent.CategoryEnum.OTHER, - QueryTerm.TypeEnum.TEXT => QueryEvent.CategoryEnum.TEXT, - QueryTerm.TypeEnum.TAG => QueryEvent.CategoryEnum.TEXT, - QueryTerm.TypeEnum.SEMANTIC => QueryEvent.CategoryEnum.SKETCH, - QueryTerm.TypeEnum.ID => QueryEvent.CategoryEnum.OTHER, - QueryTerm.TypeEnum.BOOLEAN => QueryEvent.CategoryEnum.FILTER, - _ => QueryEvent.CategoryEnum.OTHER + QueryTerm.TypeEnum.IMAGE => CategoryEnum.IMAGE, + QueryTerm.TypeEnum.AUDIO => CategoryEnum.OTHER, + QueryTerm.TypeEnum.MODEL3D => CategoryEnum.OTHER, + QueryTerm.TypeEnum.LOCATION => CategoryEnum.OTHER, + QueryTerm.TypeEnum.TIME => CategoryEnum.OTHER, + QueryTerm.TypeEnum.TEXT => CategoryEnum.TEXT, + QueryTerm.TypeEnum.TAG => CategoryEnum.TEXT, + QueryTerm.TypeEnum.SEMANTIC => CategoryEnum.SKETCH, + QueryTerm.TypeEnum.ID => CategoryEnum.OTHER, + QueryTerm.TypeEnum.BOOLEAN => CategoryEnum.FILTER, + _ => CategoryEnum.OTHER + }; + } + + private static CategoryEnum InteractionToDresCategory(Logging.Interaction category) + { + return category switch + { + Logging.Interaction.TextInput => CategoryEnum.TEXT, + Logging.Interaction.Browsing => CategoryEnum.BROWSING, + Logging.Interaction.ResultExpansion => CategoryEnum.BROWSING, + Logging.Interaction.QueryFormulation => CategoryEnum.OTHER, + Logging.Interaction.Query => CategoryEnum.OTHER, + Logging.Interaction.Filter => CategoryEnum.FILTER, + Logging.Interaction.Other => CategoryEnum.OTHER, + Logging.Interaction.QueryManagement => CategoryEnum.BROWSING, + _ => throw new ArgumentOutOfRangeException(nameof(category), category, null) }; } From 362479ef8de3a179e62b451ded0c2bd6c5c579f1 Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Fri, 2 Dec 2022 16:24:11 +0100 Subject: [PATCH 7/7] Implemented logging to file of source calling class. --- Assets/Scripts/VitrivrVR/Logging/LoggingController.cs | 8 ++++++-- .../VitrivrVR/Query/Display/CylinderQueryDisplay.cs | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs index c6d1ca0..dde3976 100644 --- a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs +++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -100,6 +101,7 @@ public static void LogSubmission(string mediaObjectId, int? frame) public static void LogInteraction(string type, string value, Interaction category) { var timestamp = CurrentTimestamp; + var source = new StackTrace().GetFrame(1).GetMethod().ReflectedType?.Name; // Log to DRES if (ConfigManager.Config.dresEnabled) @@ -110,7 +112,7 @@ public static void LogInteraction(string type, string value, Interaction categor // Log to file if (ConfigManager.Config.writeLogsToFile) { - LogInteractionToFile(timestamp, type, value, category.ToString()); + LogInteractionToFile(timestamp, source, type, value, category.ToString()); } } @@ -221,7 +223,8 @@ private static async void LogSubmissionToFile(long timestamp, string mediaObject } } - private static async void LogInteractionToFile(long timestamp, string type, string value, string category) + private static async void LogInteractionToFile(long timestamp, string source, string type, string value, + string category) { EnsureDirectoryExists(); await InteractionLogLock.WaitAsync(); @@ -231,6 +234,7 @@ private static async void LogInteractionToFile(long timestamp, string type, stri var dict = new Dictionary { { "timestamp", timestamp.ToString() }, + { "source", source }, { "type", type }, { "value", value }, { "category", category } diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs index af88232..ddc6534 100644 --- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs +++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs @@ -28,9 +28,9 @@ public class CylinderQueryDisplay : QueryDisplay public override int NumberOfResults => _nResults; - private readonly List _mediaDisplays = new List(); + private readonly List _mediaDisplays = new(); - private readonly Queue _instantiationQueue = new Queue(); + private readonly Queue _instantiationQueue = new(); private List _results;