cz.xprees.event-logging 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -6
- package/Samples~/EventLogManager/Scripts/EventLogManager.Api.cs +109 -0
- package/Samples~/EventLogManager/Scripts/EventLogManager.Api.cs.meta +3 -0
- package/Samples~/EventLogManager/Scripts/EventLogManager.cs +89 -0
- package/Samples~/EventLogManager/Scripts/EventLogManager.cs.meta +3 -0
- package/Samples~/EventLogManager/Scripts/EventUserManager.cs +55 -0
- package/Samples~/EventLogManager/Scripts/EventUserManager.cs.meta +3 -0
- package/Samples~/EventLogManager/Scripts/cz.xprees.event-logging.event-log-manager.asmdef +9 -0
- package/Samples~/EventLogManager/Scripts/cz.xprees.event-logging.event-log-manager.asmdef.meta +3 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -10,17 +10,30 @@ the [CF-Bucket - Log collector service](https://github.com/cyber-framework/cf-bu
|
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
|
-
Install the package using npm scoped registry in `Project Settings > Package Manager > Scoped Registries`
|
|
13
|
+
Install the package using npm scoped registry in `Project Settings > Package Manager > Scoped Registries` (For more details
|
|
14
|
+
see [Unity Docs - Use a scoped registry in your project](https://docs.unity3d.com/6000.2/Documentation/Manual/upm-scoped-use.html))
|
|
15
|
+
|
|
16
|
+
`Packages/manifest.json`
|
|
14
17
|
|
|
15
18
|
```json
|
|
16
19
|
{
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
"scopedRegistries": [
|
|
21
|
+
{
|
|
22
|
+
"name": "package.openupm.com",
|
|
23
|
+
"url": "https://package.openupm.com",
|
|
24
|
+
"scopes": [
|
|
25
|
+
"com.cysharp"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "NPM - xprees",
|
|
30
|
+
"url": "https://registry.npmjs.org",
|
|
31
|
+
"scopes": [
|
|
32
|
+
"cz.xprees"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
21
35
|
]
|
|
22
36
|
}
|
|
23
|
-
|
|
24
37
|
```
|
|
25
38
|
|
|
26
39
|
Then simply install the package using the Unity Package Manager using the _NPM - xprees_ scope or by the package name `cz.xprees.event-logging`.
|
|
@@ -30,4 +43,8 @@ Then simply install the package using the Unity Package Manager using the _NPM -
|
|
|
30
43
|
The package will automatically define the script define symbol `XPREES_EVENT_LOGGING` in the project settings. This is used to enable the event
|
|
31
44
|
logging functionality in your project and compatibility with other packages using event-logging capabilities.
|
|
32
45
|
|
|
46
|
+
## Quick Start
|
|
33
47
|
|
|
48
|
+
For a quick start, you can use the `EventLogManager` sample, that will give you a head start on how to log events in your project.
|
|
49
|
+
Import the sample via the Package Manager UI by selecting the package and clicking on the _Import Sample_ button.
|
|
50
|
+
Then you can use the `EventLogManager` component in your scene or just copy the script to your project and adjust to your need!
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Threading;
|
|
5
|
+
using Cysharp.Threading.Tasks;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
using Xprees.EventLogging.Api;
|
|
8
|
+
using Xprees.EventLogging.Api.Model;
|
|
9
|
+
|
|
10
|
+
namespace Xprees.EventLogging.Samples.Scripts
|
|
11
|
+
{
|
|
12
|
+
// Partial class to handle API related functionality of the Event Log Manager.
|
|
13
|
+
public partial class EventLogManager
|
|
14
|
+
{
|
|
15
|
+
[Header("API Settings")]
|
|
16
|
+
[Tooltip("Event logging API URL to send the events to.")]
|
|
17
|
+
[SerializeField] private string apiUrl = "https://cf-collector.xprees.com/";
|
|
18
|
+
|
|
19
|
+
[Tooltip("How often to send the events to the API in seconds.")]
|
|
20
|
+
[Range(1, 300)]
|
|
21
|
+
[SerializeField] private int sendInterval = 10;
|
|
22
|
+
|
|
23
|
+
[Tooltip("Whether to warm up the API connection on start with a dummy call, to wake up the service.")]
|
|
24
|
+
[SerializeField] private bool warmupApiOnStart = true;
|
|
25
|
+
|
|
26
|
+
[Tooltip("Whenever to upload remaining event logs on application quit.")]
|
|
27
|
+
[SerializeField] private bool uploadOnDisable = true;
|
|
28
|
+
|
|
29
|
+
[Tooltip("Whenever to upload remaining event logs on application quit.")]
|
|
30
|
+
[SerializeField] private bool uploadOnQuit = true;
|
|
31
|
+
|
|
32
|
+
[Tooltip("Whenever the logs should be upload from editor.")]
|
|
33
|
+
[SerializeField] private bool dontSendInEditor = false;
|
|
34
|
+
|
|
35
|
+
[Tooltip("Whenever the manager should log into the console.")]
|
|
36
|
+
[SerializeField] private bool logInConsole = true;
|
|
37
|
+
|
|
38
|
+
private EventLoggingApi _api;
|
|
39
|
+
|
|
40
|
+
private void CreateApiInstance()
|
|
41
|
+
{
|
|
42
|
+
if (IsInvalidUrl(apiUrl))
|
|
43
|
+
{
|
|
44
|
+
Debug.LogError(
|
|
45
|
+
$"{nameof(Xprees.EventLogging.Samples.Scripts.EventLogManager)} - Invalid API Url found!\n Using default one! {EventLoggingApi.DefaultEndpoint}",
|
|
46
|
+
this);
|
|
47
|
+
_api = new EventLoggingApi();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_api = new EventLoggingApi(apiUrl);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private void StartupApi(CancellationToken cancellationToken = default)
|
|
55
|
+
{
|
|
56
|
+
if (Application.isEditor && dontSendInEditor) return;
|
|
57
|
+
if (!warmupApiOnStart) return;
|
|
58
|
+
|
|
59
|
+
ConsoleLog("Warming up API...");
|
|
60
|
+
_api.Warmup(cancellationToken).Forget();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private bool IsInvalidUrl(string apiEndpoint) =>
|
|
64
|
+
string.IsNullOrEmpty(apiEndpoint) || !Uri.TryCreate(apiEndpoint, UriKind.Absolute, out _);
|
|
65
|
+
|
|
66
|
+
public async void Upload() => await UploadEvents(destroyCancellationToken);
|
|
67
|
+
|
|
68
|
+
public async UniTask<bool> UploadEvents(CancellationToken cancellationToken = default)
|
|
69
|
+
{
|
|
70
|
+
List<EventLog> logs;
|
|
71
|
+
lock (_collectedEventLogs)
|
|
72
|
+
{
|
|
73
|
+
logs = _collectedEventLogs.ToList();
|
|
74
|
+
ClearCollectedLogs();
|
|
75
|
+
TryToFixLogsUserWithCurrentIfMissing(logs);
|
|
76
|
+
if (logs.Count <= 0) return true; // nothing to upload skip it
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (Application.isEditor && dontSendInEditor)
|
|
80
|
+
{
|
|
81
|
+
ConsoleLog("Disabled upload in Editor, skipping upload.", this);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
ConsoleLog($"Uploading {logs.Count.ToString()} event logs...", this);
|
|
86
|
+
var result = await _api.SendEventLogsBatch(logs, cancellationToken);
|
|
87
|
+
|
|
88
|
+
if (!result) // if upload failed, add logs back to the queue
|
|
89
|
+
{
|
|
90
|
+
lock (_collectedEventLogs) logs.ForEach(l => _collectedEventLogs.Add(l));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
ConsoleLog($"Uploading {(result ? "Success" : "Failed")}.", this);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private void TryToFixLogsUserWithCurrentIfMissing(IEnumerable<EventLog> logs)
|
|
98
|
+
{
|
|
99
|
+
var currentUser = EventLoggingUser;
|
|
100
|
+
foreach (var log in logs)
|
|
101
|
+
{
|
|
102
|
+
if (log.user is null || string.IsNullOrEmpty(log.user.formId))
|
|
103
|
+
{
|
|
104
|
+
log.user = currentUser;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Concurrent;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
using Xprees.EventLogging.Api.Model;
|
|
5
|
+
using Xprees.EventLogging.Extensions;
|
|
6
|
+
using Xprees.EventLogging.ScriptableObjects;
|
|
7
|
+
using Object = UnityEngine.Object;
|
|
8
|
+
|
|
9
|
+
namespace Xprees.EventLogging.Samples.Scripts
|
|
10
|
+
{
|
|
11
|
+
/// Local event log manager for elevator that collects and sends events to the event log api server.
|
|
12
|
+
[DisallowMultipleComponent]
|
|
13
|
+
public partial class EventLogManager : MonoBehaviour, IEventSenderService
|
|
14
|
+
{
|
|
15
|
+
[Header("Event Logging")]
|
|
16
|
+
[Tooltip(
|
|
17
|
+
"This is unique URL-SAFE ID for your project logs. "
|
|
18
|
+
+ "Change it to your own project's ID, or you will mix logs with other projects using the same default ID. "
|
|
19
|
+
+ "aka. Scenario name.")]
|
|
20
|
+
[SerializeField] private string projectId = "vr-mp-elevator";
|
|
21
|
+
|
|
22
|
+
[Tooltip("Reference to the user manager that provides user data for the logs.")]
|
|
23
|
+
[SerializeField] private EventUserManager userManager;
|
|
24
|
+
|
|
25
|
+
private User EventLoggingUser => userManager.CurrentUser;
|
|
26
|
+
|
|
27
|
+
private readonly ConcurrentBag<EventLog> _collectedEventLogs = new();
|
|
28
|
+
|
|
29
|
+
private void Start()
|
|
30
|
+
{
|
|
31
|
+
StartupApi();
|
|
32
|
+
StartPeriodicUpload();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private void OnEnable() => CreateApiInstance();
|
|
36
|
+
|
|
37
|
+
private async void OnDisable()
|
|
38
|
+
{
|
|
39
|
+
StopPeriodicUpload();
|
|
40
|
+
if (uploadOnDisable) await UploadEvents(destroyCancellationToken);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private async void OnApplicationQuit()
|
|
44
|
+
{
|
|
45
|
+
if (uploadOnQuit) await UploadEvents(destroyCancellationToken);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public void StartPeriodicUpload() => InvokeRepeating(nameof(Upload), sendInterval, sendInterval);
|
|
49
|
+
|
|
50
|
+
public void StopPeriodicUpload() => CancelInvoke(nameof(Upload));
|
|
51
|
+
|
|
52
|
+
public void LogEvent(EventSO loggedEvent)
|
|
53
|
+
{
|
|
54
|
+
SetCurrentScenarioToLoggedEventIfMissing(loggedEvent);
|
|
55
|
+
var user = EventLoggingUser;
|
|
56
|
+
if (string.IsNullOrEmpty(user.formId))
|
|
57
|
+
{
|
|
58
|
+
Debug.LogError($"{nameof(EventLogManager)} - Current user formId is null or empty! Resulting corrupted logs.", this);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (loggedEvent == null || string.IsNullOrEmpty(loggedEvent.scenario))
|
|
62
|
+
{
|
|
63
|
+
ConsoleLog($"{nameof(EventLogManager)} - Scenario is null or empty! Throwing out the log. "
|
|
64
|
+
+ $"Event: \"{(loggedEvent != null ? loggedEvent.eventName : "None")}\"");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
var eventLog = loggedEvent.GenerateEventLog(user, DateTime.UtcNow);
|
|
69
|
+
lock (_collectedEventLogs) _collectedEventLogs.Add(eventLog);
|
|
70
|
+
|
|
71
|
+
ConsoleLog($"Logged event: {eventLog.@event}", this);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private void SetCurrentScenarioToLoggedEventIfMissing(EventSO loggedEvent)
|
|
75
|
+
{
|
|
76
|
+
if (!string.IsNullOrEmpty(loggedEvent.scenario)) return;
|
|
77
|
+
// Try to fill scenario from current scenario name
|
|
78
|
+
loggedEvent.scenario = projectId;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private void ClearCollectedLogs() => _collectedEventLogs.Clear();
|
|
82
|
+
|
|
83
|
+
private void ConsoleLog(string message, Object context = null)
|
|
84
|
+
{
|
|
85
|
+
if (!logInConsole) return;
|
|
86
|
+
Debug.Log(message, context);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
using Xprees.EventLogging.Api.Model;
|
|
4
|
+
|
|
5
|
+
namespace Xprees.EventLogging.Samples.Scripts
|
|
6
|
+
{
|
|
7
|
+
/// Event user manager for the elevator experience.
|
|
8
|
+
/// Provides user data for event logging.
|
|
9
|
+
[DisallowMultipleComponent]
|
|
10
|
+
public class EventUserManager : MonoBehaviour, IEventUserSetupService
|
|
11
|
+
{
|
|
12
|
+
// Changed default prefix of player GUIDs to easier separate event users from your project.
|
|
13
|
+
private const string defaultPrefix = "event-logging-sample";
|
|
14
|
+
|
|
15
|
+
[Header("Settings")]
|
|
16
|
+
[Tooltip("Prefix for the generated user GUIDs. Can be used to identify users from. e.g., event-logging-sample")]
|
|
17
|
+
[SerializeField] private string guidPrefix = "vr-mp-elevator";
|
|
18
|
+
|
|
19
|
+
[Tooltip("Name of the player that will be used in event logs user.")]
|
|
20
|
+
[SerializeField] public string playerName = "player";
|
|
21
|
+
|
|
22
|
+
public User CurrentUser { get; set; }
|
|
23
|
+
|
|
24
|
+
private void Awake() => SetupUserIfNeeded();
|
|
25
|
+
|
|
26
|
+
public void SetFormId(string actorId)
|
|
27
|
+
{
|
|
28
|
+
SetupUserIfNeeded();
|
|
29
|
+
CurrentUser.formId = actorId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public void SetName(string username)
|
|
33
|
+
{
|
|
34
|
+
SetupUserIfNeeded();
|
|
35
|
+
CurrentUser.name = username;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public void SetEmail(string email)
|
|
39
|
+
{
|
|
40
|
+
SetupUserIfNeeded();
|
|
41
|
+
CurrentUser.email = email;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private void SetupUserIfNeeded()
|
|
45
|
+
{
|
|
46
|
+
CurrentUser ??= new User
|
|
47
|
+
{
|
|
48
|
+
// Random unique user id
|
|
49
|
+
formId = $"{guidPrefix?.Trim() ?? defaultPrefix}-{Guid.NewGuid():D}",
|
|
50
|
+
name = playerName,
|
|
51
|
+
email = null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cz.xprees.event-logging",
|
|
3
3
|
"displayName": "Event Logging",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.18",
|
|
5
5
|
"unity": "2021.3",
|
|
6
6
|
"description": "This package provides a simple way to log events in your game.",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
"Event Logging",
|
|
16
16
|
"ScriptableObjects"
|
|
17
17
|
],
|
|
18
|
+
"samples": [
|
|
19
|
+
{
|
|
20
|
+
"displayName": "Event log Manager Example",
|
|
21
|
+
"description": "Basic script for collecting and sending events to API. Great for getting started quickly and as a starting point for your own implementations.",
|
|
22
|
+
"path": "Samples~/EventLogManager"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
18
25
|
"author": {
|
|
19
26
|
"name": "xprees",
|
|
20
27
|
"email": "xprees.developer@gmail.com",
|