Skip to content

Commit 8034047

Browse files
authored
Update Analytics to use new API (#6221)
* Upgrade to the new analytics api.
1 parent b6abc45 commit 8034047

File tree

5 files changed

+75
-86
lines changed

5 files changed

+75
-86
lines changed

.github/workflows/pre-commit.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ on:
1212
jobs:
1313
pre-commit:
1414
runs-on: ubuntu-24.04
15+
env:
16+
DOTNET_NOLOGO: 1
1517
steps:
1618
- uses: actions/checkout@v4
1719
- uses: actions/setup-python@v5
@@ -26,6 +28,8 @@ jobs:
2628
- uses: actions/setup-dotnet@v4
2729
with:
2830
dotnet-version: '8.0.202'
31+
- name: Clean dotnet shared memory
32+
run: sudo rm -rf /tmp/.dotnet/shm
2933
- name: Install manual dependencies
3034
run: |
3135
python -m pip install pre-commit

com.unity.ml-agents/Runtime/Analytics/Events.cs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,28 @@
22
using System.Collections.Generic;
33
using Unity.MLAgents.Actuators;
44
using Unity.MLAgents.Sensors;
5+
using UnityEngine.Analytics;
56

67
namespace Unity.MLAgents.Analytics
78
{
8-
internal struct InferenceEvent
9+
internal static class AnalyticsConstants
10+
{
11+
public const string k_VendorKey = "unity.ml-agents";
12+
13+
/// <summary>
14+
/// Maximum number of events sent per hour.
15+
/// </summary>
16+
public const int k_MaxEventsPerHour = 1000;
17+
18+
/// <summary>
19+
/// Maximum number of items in an event.
20+
/// </summary>
21+
public const int k_MaxNumberOfElements = 1000;
22+
}
23+
24+
[Serializable]
25+
[AnalyticInfo(eventName: "ml_agents_inferencemodelset", version: 1, vendorKey: AnalyticsConstants.k_VendorKey, maxEventsPerHour: AnalyticsConstants.k_MaxEventsPerHour, maxNumberOfElements: AnalyticsConstants.k_MaxNumberOfElements)]
26+
internal class InferenceEvent : IAnalytic.IData, IAnalytic
927
{
1028
/// <summary>
1129
/// Hash of the BehaviorName.
@@ -25,6 +43,12 @@ internal struct InferenceEvent
2543
public int MemorySize;
2644
public long TotalWeightSizeBytes;
2745
public string ModelHash;
46+
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
47+
{
48+
data = this;
49+
error = null;
50+
return true;
51+
}
2852
}
2953

3054
/// <summary>
@@ -126,7 +150,9 @@ public static EventObservationSpec FromSensor(ISensor sensor)
126150
}
127151
}
128152

129-
internal struct RemotePolicyInitializedEvent
153+
[Serializable]
154+
[AnalyticInfo(eventName: "ml_agents_remote_policy_initialized", vendorKey: AnalyticsConstants.k_VendorKey, maxEventsPerHour: AnalyticsConstants.k_MaxEventsPerHour, maxNumberOfElements: AnalyticsConstants.k_MaxNumberOfElements)]
155+
internal class RemotePolicyInitializedEvent : IAnalytic.IData, IAnalytic
130156
{
131157
public string TrainingSessionGuid;
132158
/// <summary>
@@ -143,9 +169,18 @@ internal struct RemotePolicyInitializedEvent
143169
/// </summary>
144170
public string MLAgentsEnvsVersion;
145171
public string TrainerCommunicationVersion;
172+
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
173+
{
174+
data = this;
175+
error = null;
176+
return true;
177+
}
146178
}
147179

148-
internal struct TrainingEnvironmentInitializedEvent
180+
181+
[Serializable]
182+
[AnalyticInfo(eventName: "ml_agents_training_environment_initialized", vendorKey: AnalyticsConstants.k_VendorKey, maxEventsPerHour: AnalyticsConstants.k_MaxEventsPerHour, maxNumberOfElements: AnalyticsConstants.k_MaxNumberOfElements)]
183+
internal class TrainingEnvironmentInitializedEvent : IAnalytic.IData, IAnalytic
149184
{
150185
public string TrainingSessionGuid;
151186

@@ -157,6 +192,12 @@ internal struct TrainingEnvironmentInitializedEvent
157192
public int NumEnvironments;
158193
public int NumEnvironmentParameters;
159194
public string RunOptions;
195+
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
196+
{
197+
data = this;
198+
error = null;
199+
return true;
200+
}
160201
}
161202

162203
[Flags]
@@ -178,7 +219,9 @@ internal enum TrainingFeatures
178219
Curriculum = 1 << 4,
179220
}
180221

181-
internal struct TrainingBehaviorInitializedEvent
222+
[Serializable]
223+
[AnalyticInfo(eventName: "ml_agents_training_behavior_initialized", vendorKey: AnalyticsConstants.k_VendorKey, maxEventsPerHour: AnalyticsConstants.k_MaxEventsPerHour, maxNumberOfElements: AnalyticsConstants.k_MaxNumberOfElements)]
224+
internal class TrainingBehaviorInitializedEvent : IAnalytic.IData, IAnalytic
182225
{
183226
public string TrainingSessionGuid;
184227

@@ -190,5 +233,12 @@ internal struct TrainingBehaviorInitializedEvent
190233
public int NumNetworkLayers;
191234
public int NumNetworkHiddenUnits;
192235
public string Config;
236+
237+
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
238+
{
239+
data = this;
240+
error = null;
241+
return true;
242+
}
193243
}
194244
}

com.unity.ml-agents/Runtime/Analytics/InferenceAnalytics.cs

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,6 @@ namespace Unity.MLAgents.Analytics
2424
{
2525
internal class InferenceAnalytics
2626
{
27-
const string k_VendorKey = "unity.ml-agents";
28-
const string k_EventName = "ml_agents_inferencemodelset";
29-
const int k_EventVersion = 1;
30-
31-
/// <summary>
32-
/// Whether or not we've registered this particular event yet
33-
/// </summary>
34-
static bool s_EventRegistered;
35-
36-
/// <summary>
37-
/// Hourly limit for this event name
38-
/// </summary>
39-
const int k_MaxEventsPerHour = 1000;
40-
41-
/// <summary>
42-
/// Maximum number of items in this event.
43-
/// </summary>
44-
const int k_MaxNumberOfElements = 1000;
4527

4628

4729
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
@@ -54,25 +36,17 @@ internal class InferenceAnalytics
5436
static bool EnableAnalytics()
5537
{
5638
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
57-
if (s_EventRegistered)
58-
{
59-
return true;
60-
}
6139

62-
AnalyticsResult result = EditorAnalytics.RegisterEventWithLimit(k_EventName, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey, k_EventVersion);
63-
if (result == AnalyticsResult.Ok)
64-
{
65-
s_EventRegistered = true;
66-
}
67-
if (s_EventRegistered && s_SentModels == null)
40+
if (s_SentModels == null)
6841
{
6942
s_SentModels = new HashSet<ModelAsset>();
7043
}
7144

45+
return true;
46+
7247
#else // no editor, no analytics
73-
s_EventRegistered = false;
48+
return false;
7449
#endif
75-
return s_EventRegistered;
7650
}
7751

7852
public static bool IsAnalyticsEnabled()
@@ -127,7 +101,7 @@ IList<IActuator> actuators
127101
// Debug.Log(JsonUtility.ToJson(data, true));
128102
if (AnalyticsUtils.s_SendEditorAnalytics)
129103
{
130-
EditorAnalytics.SendEventWithLimit(k_EventName, data, k_EventVersion);
104+
EditorAnalytics.SendAnalytic(data);
131105
}
132106
#endif
133107
}
@@ -156,7 +130,7 @@ IList<IActuator> actuators
156130
var inferenceEvent = new InferenceEvent();
157131

158132
// Hash the behavior name so that there's no concern about PII or "secret" data being leaked.
159-
inferenceEvent.BehaviorName = AnalyticsUtils.Hash(k_VendorKey, behaviorName);
133+
inferenceEvent.BehaviorName = AnalyticsUtils.Hash(AnalyticsConstants.k_VendorKey, behaviorName);
160134

161135
inferenceEvent.SentisModelVersion = sentisModelInfo.Version;
162136
inferenceEvent.SentisModelProducer = sentisModel.ProducerName;

com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs

Lines changed: 9 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,9 @@ namespace Unity.MLAgents.Analytics
2323
{
2424
internal static class TrainingAnalytics
2525
{
26-
const string k_VendorKey = "unity.ml-agents";
27-
const string k_TrainingEnvironmentInitializedEventName = "ml_agents_training_environment_initialized";
28-
const string k_TrainingBehaviorInitializedEventName = "ml_agents_training_behavior_initialized";
29-
const string k_RemotePolicyInitializedEventName = "ml_agents_remote_policy_initialized";
30-
31-
private static readonly string[] s_EventNames =
32-
{
33-
k_TrainingEnvironmentInitializedEventName,
34-
k_TrainingBehaviorInitializedEventName,
35-
k_RemotePolicyInitializedEventName
36-
};
37-
38-
/// <summary>
39-
/// Hourly limit for this event name
40-
/// </summary>
41-
const int k_MaxEventsPerHour = 1000;
42-
43-
/// <summary>
44-
/// Maximum number of items in this event.
45-
/// </summary>
46-
const int k_MaxNumberOfElements = 1000;
47-
4826
private static bool s_SentEnvironmentInitialized;
4927

5028
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
51-
/// <summary>
52-
/// Whether or not we've registered this particular event yet
53-
/// </summary>
54-
static bool s_EventsRegistered;
5529

5630
/// <summary>
5731
/// Behaviors that we've already sent events for.
@@ -69,19 +43,6 @@ internal static class TrainingAnalytics
6943
internal static bool EnableAnalytics()
7044
{
7145
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
72-
if (s_EventsRegistered)
73-
{
74-
return true;
75-
}
76-
foreach (var eventName in s_EventNames)
77-
{
78-
AnalyticsResult result = EditorAnalytics.RegisterEventWithLimit(eventName, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey);
79-
if (result != AnalyticsResult.Ok)
80-
{
81-
return false;
82-
}
83-
}
84-
s_EventsRegistered = true;
8546

8647
if (s_SentRemotePolicyInitialized == null)
8748
{
@@ -90,7 +51,7 @@ internal static bool EnableAnalytics()
9051
s_TrainingSessionGuid = Guid.NewGuid();
9152
}
9253

93-
return s_EventsRegistered;
54+
return true;
9455
#else
9556
return false;
9657
#endif // MLA_UNITY_ANALYTICS_MODULE
@@ -137,12 +98,12 @@ public static void TrainingEnvironmentInitialized(TrainingEnvironmentInitialized
13798

13899
// Note - to debug, use JsonUtility.ToJson on the event.
139100
// Debug.Log(
140-
// $"Would send event {k_TrainingEnvironmentInitializedEventName} with body {JsonUtility.ToJson(tbiEvent, true)}"
101+
// $"Would send event ml_agents_training_environment_initialized with body {JsonUtility.ToJson(tbiEvent, true)}"
141102
// );
142103
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
143104
if (AnalyticsUtils.s_SendEditorAnalytics)
144105
{
145-
EditorAnalytics.SendEventWithLimit(k_TrainingEnvironmentInitializedEventName, tbiEvent);
106+
EditorAnalytics.SendAnalytic(tbiEvent);
146107
}
147108
#endif
148109
}
@@ -175,11 +136,11 @@ IList<IActuator> actuators
175136
var data = GetEventForRemotePolicy(behaviorName, sensors, actionSpec, actuators);
176137
// Note - to debug, use JsonUtility.ToJson on the event.
177138
// Debug.Log(
178-
// $"Would send event {k_RemotePolicyInitializedEventName} with body {JsonUtility.ToJson(data, true)}"
139+
// $"Would send event ml_agents_remote_policy_initialized with body {JsonUtility.ToJson(data, true)}"
179140
// );
180141
if (AnalyticsUtils.s_SendEditorAnalytics)
181142
{
182-
EditorAnalytics.SendEventWithLimit(k_RemotePolicyInitializedEventName, data);
143+
EditorAnalytics.SendAnalytic(data);
183144
}
184145
#endif
185146
}
@@ -203,7 +164,7 @@ internal static TrainingBehaviorInitializedEvent SanitizeTrainingBehaviorInitial
203164
// Context: The config field was added at the same time as trainer side hashing, so messages including it should already be hashed.
204165
if (tbiEvent.Config.Length == 0 || tbiEvent.BehaviorName.Length != 64)
205166
{
206-
tbiEvent.BehaviorName = AnalyticsUtils.Hash(k_VendorKey, tbiEvent.BehaviorName);
167+
tbiEvent.BehaviorName = AnalyticsUtils.Hash(AnalyticsConstants.k_VendorKey, tbiEvent.BehaviorName);
207168
}
208169

209170
return tbiEvent;
@@ -233,11 +194,11 @@ public static void TrainingBehaviorInitialized(TrainingBehaviorInitializedEvent
233194

234195
// Note - to debug, use JsonUtility.ToJson on the event.
235196
// Debug.Log(
236-
// $"Would send event {k_TrainingBehaviorInitializedEventName} with body {JsonUtility.ToJson(tbiEvent, true)}"
197+
// $"Would send event ml_agents_training_behavior_initialized with body {JsonUtility.ToJson(tbiEvent, true)}"
237198
// );
238199
if (AnalyticsUtils.s_SendEditorAnalytics)
239200
{
240-
EditorAnalytics.SendEventWithLimit(k_TrainingBehaviorInitializedEventName, tbiEvent);
201+
EditorAnalytics.SendAnalytic(tbiEvent);
241202
}
242203
#endif
243204
}
@@ -252,7 +213,7 @@ IList<IActuator> actuators
252213
var remotePolicyEvent = new RemotePolicyInitializedEvent();
253214

254215
// Hash the behavior name so that there's no concern about PII or "secret" data being leaked.
255-
remotePolicyEvent.BehaviorName = AnalyticsUtils.Hash(k_VendorKey, behaviorName);
216+
remotePolicyEvent.BehaviorName = AnalyticsUtils.Hash(AnalyticsConstants.k_VendorKey, behaviorName);
256217

257218
remotePolicyEvent.TrainingSessionGuid = s_TrainingSessionGuid.ToString();
258219
remotePolicyEvent.ActionSpec = EventActionSpec.FromActionSpec(actionSpec);

com.unity.ml-agents/Tests/Editor/Analytics/TrainingAnalyticsTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ public string TestTrainingBehaviorInitialized(string stringToMaybeHash)
8686
[Test]
8787
public void TestEnableAnalytics()
8888
{
89-
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
90-
Assert.IsTrue(EditorAnalytics.enabled == TrainingAnalytics.EnableAnalytics());
89+
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
90+
Assert.IsTrue(TrainingAnalytics.EnableAnalytics());
9191
#else
9292
Assert.IsFalse(TrainingAnalytics.EnableAnalytics());
9393
#endif

0 commit comments

Comments
 (0)