Skip to content

Commit 34f060d

Browse files
authored
Version 3.2.5 (#53)
* Squashed commit of the following: commit c4d0f53 Author: konraddysput <konrad.dysput@gmail.com> Date: Mon Nov 30 17:29:08 2020 +0100 typo fixed commit 3b723e2 Author: konraddysput <konrad.dysput@gmail.com> Date: Mon Nov 30 17:27:23 2020 +0100 Reverted crashpad attributes commit 8f654b8 Author: konraddysput <konrad.dysput@gmail.com> Date: Thu Nov 26 12:47:12 2020 +0100 Meta fix * Squashed commit of the following: commit d2eecc1 Author: konraddysput <konrad.dysput@gmail.com> Date: Mon Nov 30 17:22:03 2020 +0100 Runtime initialization * Readme/Changelog update * Sampling support * Api improvements * Advanced configuration example * Code rewview suggestions * Readme/changelog update * Clarification in Unity tooltip
1 parent e686588 commit 34f060d

12 files changed

+187
-63
lines changed

Android/lib/x86/libbacktrace-native.so.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Backtrace Unity Release Notes
22

3+
## Version 3.2.5
4+
- Added `BacktraceClient` Initialization method that allows developer to intialize Backtrace integration without adding game object to game scene.
5+
- Fixed invalid `meta` file for iOS integration for Unity 2019.2.13f1.
6+
- HTTP communication messages improvements - right now Backtrace-Unity plugin will print only one error message when network failure happen. Backtrace-Unity will stop printing failures until next successfull report upload.
7+
- Sampling skip fraction - Enables a new random sampling mechanism for unhandled exceptions - by default sampling is equal to 0.01 - which means only 1% of randomply sampling reports will be send to Backtrace. If you would like to send all unhandled exceptions to Backtrace - please replace 0.01 value with 1.
8+
9+
**Be aware**
10+
11+
By default Backtrace library will send only 1% of your reports - please change this value if you would like to send more unhandled exceptions to server.
12+
13+
14+
315
## Version 3.2.4
416
- Fixed Backtrace-Unity NDK integration database path.
517

Editor/BacktraceConfigurationEditor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ public override void OnInspectorGUI()
7575
serializedObject.FindProperty("DestroyOnLoad"),
7676
new GUIContent(BacktraceConfigurationLabels.LABEL_DESTROY_CLIENT_ON_SCENE_LOAD));
7777

78+
EditorGUILayout.PropertyField(
79+
serializedObject.FindProperty("Sampling"),
80+
new GUIContent(BacktraceConfigurationLabels.LABEL_SAMPLING));
81+
7882
SerializedProperty gameObjectDepth = serializedObject.FindProperty("GameObjectDepth");
7983
EditorGUILayout.PropertyField(gameObjectDepth, new GUIContent(BacktraceConfigurationLabels.LABEL_GAME_OBJECT_DEPTH));
8084

Editor/BacktraceConfigurationLabels.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ internal static class BacktraceConfigurationLabels
88
internal static string LABEL_HANDLE_UNHANDLED_EXCEPTION = "Handle unhandled exceptions";
99

1010
internal static string LABEL_DESTROY_CLIENT_ON_SCENE_LOAD = "Destroy client on new scene load (false - Backtrace managed)";
11+
internal static string LABEL_SAMPLING = "Sampling skip fraction";
1112
internal static string LABEL_HANDLE_ANR = "Handle ANR (Application not responding)";
1213
internal static string CAPTURE_NATIVE_CRASHES = "Capture native crashes";
1314
internal static string LABEL_REPORT_FILTER = "Filter reports";

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,32 @@ List of steps necessary to setup full Backtrace Unity integration.
9797
- Provide valid Backtrace client configuration and start using library!
9898
![Full Backtrace configuration](./Documentation~/images/client-setup.PNG)
9999

100+
## Integrating into your project via code
101+
102+
One of the integration paths require to create game object in your game scene. If you would like to initialize Backtrace integration programatically, we recommend to use `Initialize` method available in `BacktraceClient` class.
103+
104+
```csharp
105+
var backtraceClient = BacktraceClient.Initialize(
106+
url: serverUrl,
107+
databasePath: "${Application.persistentDataPath}/sample/backtrace/path",
108+
gameObjectName: "game-object-name",
109+
attributes: attributes);
110+
```
111+
112+
If you need to use more advanced configuration, `Initialize` method accepts a `BacktraceConfiguration` scriptable object.
113+
```csharp
114+
var configuration = ScriptableObject.CreateInstance<BacktraceConfiguration>();
115+
configuration.ServerUrl = serverUrl;
116+
configuration.Enabled = true;
117+
configuration.DatabasePath = "${Application.persistentDataPath}/sample/backtrace/path";
118+
configuration.CreateDatabase = true;
119+
configuration.Sampling = 0.002;
120+
_backtraceClient = BacktraceClient.Initialize(
121+
configuration,
122+
gameObjectName: "game-object-name",
123+
attributes: attributes);
124+
```
125+
100126
## Plugin best practices
101127

102128
Plugin allows you to define maximum depth of game objects. By default its disabled (Game object depth is equal to -1). If you will use 0 as maximum depth of game object we will use default game object limit - 16. If you would like to specify game object depth size to n, please insert n in Backtrace configuration text box. If you require game obejct depth to be above 30, please contact support.
@@ -113,6 +139,7 @@ The following is a reference guide to the Backtrace Client fields:
113139
- Send unhandled native game crashes on startup: Try to find game native crashes and send them on Game startup.
114140
- Handle unhandled exceptions: Toggle this on or off to set the library to handle unhandled exceptions that are not captured by try-catch blocks.
115141
- Symbols upload token - If you want to upload Unity debug symbols for Android NDK Native Crash debugging, enter your Backtrace Symbol upload token here. This option is available only in Android build.
142+
- Sampling skip fraction - Enables a new random sampling mechanism for unhandled exceptions - **by default** sampling is equal to **0.01** - which means only **1%** of randomply sampling **reports will be send** to Backtrace. If you would like to send all unhandled exceptions to Backtrace - please replace 0.01 value with 1.
116143
- Game Object Depth Limit: Allows developer to filter number of game object childrens in Backtrace report.
117144
- Collect last n game logs: Collect last n number of logs generated by game.
118145
- Enabled performance statistics: Allows `BacktraceClient` to measure execution time and include performance information as report attributes.

Runtime/BacktraceClient.cs

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class BacktraceClient : MonoBehaviour, IBacktraceClient
2020
{
2121
public BacktraceConfiguration Configuration;
2222

23-
public const string VERSION = "3.2.4";
23+
public const string VERSION = "3.2.5";
2424
public bool Enabled { get; private set; }
2525

2626
/// <summary>
@@ -53,6 +53,10 @@ public string this[string index]
5353
/// <param name="attributes">attributes dictionary</param>
5454
public void SetAttributes(Dictionary<string, string> attributes)
5555
{
56+
if (attributes == null)
57+
{
58+
return;
59+
}
5660
foreach (var attribute in attributes)
5761
{
5862
this[attribute.Key] = attribute.Value;
@@ -258,6 +262,76 @@ internal ReportLimitWatcher ReportLimitWatcher
258262

259263
private BacktraceLogManager _backtraceLogManager;
260264

265+
266+
/// <summary>
267+
/// Initialize new Backtrace integration
268+
/// </summary>
269+
/// <param name="configuration">Backtrace configuration scriptable object</param>
270+
/// <param name="attributes">Client side attributes</param>
271+
/// <param name="gameObjectName">game object name</param>
272+
/// <returns>Backtrace client</returns>
273+
public static BacktraceClient Initialize(BacktraceConfiguration configuration, Dictionary<string, string> attributes = null, string gameObjectName = "BacktraceClient")
274+
{
275+
if (string.IsNullOrEmpty(gameObjectName))
276+
{
277+
throw new ArgumentException("Missing game object name");
278+
}
279+
280+
if (configuration == null || string.IsNullOrEmpty(configuration.ServerUrl))
281+
{
282+
throw new ArgumentException("Missing valid configuration");
283+
}
284+
285+
if (Instance != null)
286+
{
287+
return Instance;
288+
}
289+
var backtrackGameObject = new GameObject(gameObjectName, typeof(BacktraceClient), typeof(BacktraceDatabase));
290+
BacktraceClient backtraceClient = backtrackGameObject.GetComponent<BacktraceClient>();
291+
BacktraceDatabase backtraceDatabase = backtrackGameObject.GetComponent<BacktraceDatabase>();
292+
293+
backtraceDatabase.Configuration = configuration;
294+
backtraceClient.Configuration = configuration;
295+
backtrackGameObject.SetActive(true);
296+
backtraceClient.Refresh();
297+
backtraceClient.SetAttributes(attributes);
298+
299+
return backtraceClient;
300+
}
301+
302+
/// <summary>
303+
/// Initialize new Backtrace integration with database path. Note - database path will be auto created by Backtrace Unity plugin
304+
/// </summary>
305+
/// <param name="url">Server url</param>
306+
/// <param name="databasePath">Database path</param>
307+
/// <param name="attributes">Client side attributes</param>
308+
/// <param name="gameObjectName">game object name</param>
309+
/// <returns>Backtrace client</returns>
310+
public static BacktraceClient Initialize(string url, string databasePath, Dictionary<string, string> attributes = null, string gameObjectName = "BacktraceClient")
311+
{
312+
var configuration = ScriptableObject.CreateInstance<BacktraceConfiguration>();
313+
configuration.ServerUrl = url;
314+
configuration.Enabled = true;
315+
configuration.DatabasePath = databasePath;
316+
configuration.CreateDatabase = true;
317+
return Initialize(configuration, attributes, gameObjectName);
318+
}
319+
320+
/// <summary>
321+
/// Initialize new Backtrace integration
322+
/// </summary>
323+
/// <param name="url">Server url</param>
324+
/// <param name="attributes">Client side attributes</param>
325+
/// <param name="gameObjectName">game object name</param>
326+
/// <returns>Backtrace client</returns>
327+
public static BacktraceClient Initialize(string url, Dictionary<string, string> attributes = null, string gameObjectName = "BacktraceClient")
328+
{
329+
var configuration = ScriptableObject.CreateInstance<BacktraceConfiguration>();
330+
configuration.ServerUrl = url;
331+
configuration.Enabled = false;
332+
return Initialize(configuration, attributes, gameObjectName);
333+
}
334+
261335
public void OnDisable()
262336
{
263337
Enabled = false;
@@ -468,6 +542,7 @@ record = Database.Add(data);
468542

469543
if (record.Duplicated)
470544
{
545+
record.Dispose();
471546
yield break;
472547
}
473548
}
@@ -582,7 +657,7 @@ internal void OnAnrDetected(string stackTrace)
582657
#endif
583658

584659
/// <summary>
585-
/// Handle Untiy unhandled exceptions
660+
/// Handle Unity unhandled exceptions
586661
/// </summary>
587662
private void CaptureUnityMessages()
588663
{
@@ -601,15 +676,38 @@ private void CaptureUnityMessages()
601676
/// <param name="type">log type</param>
602677
internal void HandleUnityMessage(string message, string stackTrace, LogType type)
603678
{
679+
if (!Enabled)
680+
{
681+
return;
682+
}
604683
var unityMessage = new BacktraceUnityMessage(message, stackTrace, type);
605684
_backtraceLogManager.Enqueue(unityMessage);
606-
if (Configuration.HandleUnhandledExceptions && unityMessage.IsUnhandledException())
685+
if (Configuration.HandleUnhandledExceptions && unityMessage.IsUnhandledException() && !SamplingShouldSkip())
607686
{
608687
var exception = new BacktraceUnhandledException(unityMessage.Message, unityMessage.StackTrace);
609688
SendUnhandledException(exception);
610689
}
611690
}
612691

692+
/// <summary>
693+
/// Skip sending report when sampling hit. This feature is enabled only for unhandled exception handler
694+
/// </summary>
695+
/// <returns>True, when client should skip report, otherwise false.</returns>
696+
private bool SamplingShouldSkip()
697+
{
698+
// Sampling won't work in Editor mode - from editor we're allowing to send all type
699+
// of possible errors.
700+
#if UNITY_EDITOR
701+
return false;
702+
#else
703+
if (!Configuration || Configuration.Sampling == 1)
704+
{
705+
return false;
706+
}
707+
return UnityEngine.Random.Range(0f, 1f) > Configuration.Sampling;
708+
#endif
709+
}
710+
613711
private void SendUnhandledException(BacktraceUnhandledException exception)
614712
{
615713
if (OnUnhandledApplicationException != null)

Runtime/BacktraceDatabase.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,13 @@ private void SendData(BacktraceDatabaseRecord record)
399399
StartCoroutine(
400400
BacktraceApi.Send(backtraceData, record.Attachments, queryAttributes, (BacktraceResult sendResult) =>
401401
{
402+
record.Dispose();
402403
if (sendResult.Status != BacktraceResultStatus.ServerError && sendResult.Status != BacktraceResultStatus.NetworkError)
403404
{
404405
Delete(record);
405406
}
406407
else
407408
{
408-
record.Dispose();
409409
BacktraceDatabaseContext.IncrementBatchRetry();
410410
return;
411411
}
@@ -478,7 +478,7 @@ protected virtual bool InitializeDatabasePaths()
478478
databaseDirExists = dirInfo.Exists;
479479
}
480480

481-
if(!databaseDirExists)
481+
if (!databaseDirExists)
482482
{
483483
Debug.LogWarning(string.Format("Backtrace database path doesn't exist. Database path: {0}", DatabasePath));
484484

@@ -534,8 +534,9 @@ private bool ValidateDatabaseSize()
534534
//check how many records are stored in database
535535
//remove in case when we want to store one more than expected number
536536
//If record count == 0 then we ignore this condition
537-
if (BacktraceDatabaseContext.Count() + 1 > DatabaseSettings.MaxRecordCount && DatabaseSettings.MaxRecordCount != 0 && !BacktraceDatabaseContext.RemoveLastRecord())
538-
{
537+
var noMoreSpaceForReport = BacktraceDatabaseContext.Count() + 1 > DatabaseSettings.MaxRecordCount && DatabaseSettings.MaxRecordCount != 0;
538+
if (noMoreSpaceForReport)
539+
{
539540
return false;
540541
}
541542

Runtime/Model/BacktraceConfiguration.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ public class BacktraceConfiguration : ScriptableObject
4646
[Tooltip("Backtrace-client by default will be available on each scene. Once you initialize Backtrace integration, you can fetch Backtrace game object from every scene. In case if you don't want to have Backtrace-unity integration available by default in each scene, please set this value to true.")]
4747
public bool DestroyOnLoad = false;
4848

49+
/// <summary>
50+
/// Sampling configuration - fractional sampling allows to drop some % of unhandled exception.
51+
/// </summary>
52+
[Tooltip("Sampling skip fraction - Enables a random sampling mechanism for unhandled exceptions - by default sampling is equal to 0.01 - which means only 1% of randomply sampling reports will be send to Backtrace. \n" +
53+
"* 1 - means 100% of unhandled exception reports will be reported by library,\n" +
54+
"* 0.1 - means 10% of unhandled exception reports will be reported by library,\n" +
55+
"* 0 - means library is going to drop all unhandled exception.")]
56+
[Range(0, 1)]
57+
public double Sampling = 0.01d;
58+
4959
/// <summary>
5060
/// Backtrace report filter type
5161
/// </summary>

Runtime/Services/BacktraceApi.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ internal class BacktraceApi : IBacktraceApi
2323
[Obsolete("RequestHandler is obsolete. BacktraceApi won't be able to provide BacktraceData in every situation")]
2424
public Func<string, BacktraceData, BacktraceResult> RequestHandler { get; set; }
2525

26+
/// <summary>
27+
/// Determine if BacktraceApi should display failure message on HTTP failure.
28+
/// </summary>
29+
private bool _shouldDisplayFailureMessage = true;
30+
2631
/// <summary>
2732
/// Event triggered when server is unvailable
2833
/// </summary>
@@ -127,6 +132,12 @@ public IEnumerator SendMinidump(string minidumpPath, IEnumerable<string> attachm
127132
var boundaryIdBytes = UnityWebRequest.GenerateBoundary();
128133
using (var request = UnityWebRequest.Post(_minidumpUrl, formData, boundaryIdBytes))
129134
{
135+
#if UNITY_2018_4_OR_NEWER
136+
if (_ignoreSslValidation)
137+
{
138+
request.certificateHandler = new BacktraceSelfSSLCertificateHandler();
139+
}
140+
#endif
130141
request.SetRequestHeader("Content-Type", string.Format("multipart/form-data; boundary={0}", Encoding.UTF8.GetString(boundaryIdBytes)));
131142
request.timeout = 15000;
132143
yield return request.SendWebRequest();
@@ -229,6 +240,12 @@ public IEnumerator Send(string json, List<string> attachments, Dictionary<string
229240
var boundaryIdBytes = UnityWebRequest.GenerateBoundary();
230241
using (var request = UnityWebRequest.Post(requestUrl, formData, boundaryIdBytes))
231242
{
243+
#if UNITY_2018_4_OR_NEWER
244+
if (_ignoreSslValidation)
245+
{
246+
request.certificateHandler = new BacktraceSelfSSLCertificateHandler();
247+
}
248+
#endif
232249
request.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + Encoding.UTF8.GetString(boundaryIdBytes));
233250
request.timeout = 15000;
234251
yield return request.SendWebRequest();
@@ -249,6 +266,7 @@ public IEnumerator Send(string json, List<string> attachments, Dictionary<string
249266
else if (request.responseCode == 200 && (!request.isNetworkError || !request.isHttpError))
250267
{
251268
result = BacktraceResult.FromJson(request.downloadHandler.text);
269+
_shouldDisplayFailureMessage = true;
252270

253271
if (OnServerResponse != null)
254272
{
@@ -282,9 +300,14 @@ public IEnumerator Send(string json, List<string> attachments, Dictionary<string
282300

283301
private void PrintLog(UnityWebRequest request)
284302
{
303+
if(!_shouldDisplayFailureMessage)
304+
{
305+
return;
306+
}
307+
_shouldDisplayFailureMessage = false;
285308
Debug.LogWarning(string.Format("{0}{1}", string.Format("[Backtrace]::Reponse code: {0}, Response text: {1}",
286309
request.responseCode,
287-
request.downloadHandler.text),
310+
request.error),
288311
"\n Please check provided url to Backtrace service or learn more from our integration guide: https://support.backtrace.io/hc/en-us/articles/360040515991-Unity-Integration-Guide"));
289312
}
290313

Runtime/Services/BacktraceDatabaseContext.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ public void Delete(BacktraceDatabaseRecord record)
236236
}
237237
//decrement total size of database
238238
TotalSize -= value.Size;
239-
System.Diagnostics.Debug.WriteLine(string.Format("[Delete] :: Total Size = {0}", TotalSize));
240239
return;
241240
}
242241
}
@@ -261,16 +260,7 @@ public bool RemoveLastRecord()
261260
var record = LastOrDefault();
262261
if (record != null)
263262
{
264-
record.Delete();
265-
if (record.Count > 0)
266-
{
267-
TotalRecords = TotalRecords - record.Count;
268-
}
269-
else
270-
{
271-
TotalRecords--;
272-
}
273-
TotalSize -= record.Size;
263+
Delete(record);
274264
return true;
275265
}
276266
return false;

0 commit comments

Comments
 (0)