Skip to content

Add global BugSplat instance #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions Editor/BugSplatMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using UnityEditor;
using UnityEngine;
using BugSplatUnity.Runtime.Client;

namespace BugSplatUnity.Editor
{
public static class BugSplatMenu
{
private const string AssetPath = "Assets/BugSplat/Resources/BugSplatOptions.asset";

[MenuItem("Tools/BugSplat/Options", priority = 100)]
public static void OpenOptions()
{
var options = AssetDatabase.LoadAssetAtPath<BugSplatOptions>(AssetPath);
if (options == null)
{
CreateOptionsAsset();
options = AssetDatabase.LoadAssetAtPath<BugSplatOptions>(AssetPath);
}

Selection.activeObject = options;
EditorGUIUtility.PingObject(options);
}

private static void CreateOptionsAsset()
{
var dir = System.IO.Path.GetDirectoryName(AssetPath);
if (!AssetDatabase.IsValidFolder("Assets/BugSplat"))
{
AssetDatabase.CreateFolder("Assets", "BugSplat");
}
if (!AssetDatabase.IsValidFolder("Assets/BugSplat/Resources"))
{
AssetDatabase.CreateFolder("Assets/BugSplat", "Resources");
}

var options = ScriptableObject.CreateInstance<BugSplatOptions>();
AssetDatabase.CreateAsset(options, AssetPath);
AssetDatabase.SaveAssets();
}
}
}
11 changes: 11 additions & 0 deletions Editor/BugSplatMenu.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ To import the sample, click the carrot next to **Samples** to reveal the **my-un

In the Project Assets browser, open the **Sample** scene from `Samples > BugSplat > Version > my-unity-crasher > Scenes`.

Next, select `Samples > BugSplat > Version > my-unity-crasher` to reveal the **BugSplatOptions** object. Click BugSplatOptions and replace the database value with your BugSplat database.
Next, open **Tools > BugSplat > Options** and replace the database value with your BugSplat database.

![Finding the Sample](https://github.com/BugSplat-Git/bugsplat-unity/assets/2646053/ba9aa64a-1d85-45a8-b11f-565520c30bcf)

Expand All @@ -72,28 +72,28 @@ BugSplat's Unity integration is flexible and can be used in various ways. The ea

![BugSplat Manager](https://github.com/BugSplat-Git/bugsplat-unity/assets/2646053/ef5240a6-9676-43c6-a482-51216cb34401)

`BugSplatManager` needs to be initialized with a `BugSplatOptions` serialized object. A new instance of `BugSplatOptions` can be created through the Asset Create menu.
`BugSplatManager` will automatically use the options configured via **Tools > BugSplat > Options**.

![BugSplat Create Options](https://github.com/BugSplat-Git/bugsplat-unity/assets/2646053/9ec402d1-4b8a-49cf-96e9-00d951717771)

Configure fields as appropriate. Note that if Application or Version are left empty, `BugSplat` will default these values to `Application.productName` and `Application.version`, respectively.

![BugSplat Options](https://github.com/BugSplat-Git/bugsplat-unity/assets/2646053/be7ee217-9170-48b4-b780-fcb47e221f77)

Finally, provide a valid `BugSplatOptions` to `BugSplatManager`.

![BugSplat Manager Configured](https://github.com/BugSplat-Git/bugsplat-unity/assets/2646053/67bed7b5-e2a9-4f52-b5bb-bdc8eebd35a0)

## ⌨️ Usage

If you're using `BugSplatOptions` and `BugSplatManager`, BugSplat automatically configures an `Application.logMessageReceived` handler that will post reports when it encounters a log message of type `Exception`. You can also extend your BugSplat integration and [customize report metadata](#adding-metadata), [report exceptions in try/catch blocks](#trycatch-reporting), [prevent repeated reports](#preventing-repeated-reports), and [upload windows minidumps](#windows) from native crashes.
If you're using `BugSplatManager`, BugSplat automatically configures an `Application.logMessageReceived` handler that will post reports when it encounters a log message of type `Exception`. You can also extend your BugSplat integration and [customize report metadata](#adding-metadata), [report exceptions in try/catch blocks](#trycatch-reporting), [prevent repeated reports](#preventing-repeated-reports), and [upload windows minidumps](#windows) from native crashes.

The options set in **Tools > BugSplat > Options** are loaded automatically at startup and used to create the global `BugSplat.Instance`.

### Adding Metadata

First, find your instance of `BugSplat`. The following is an example of how to find an instance of `BugSplat` via `BugSplatManager`:
First, access the global `BugSplat` instance:

```cs
var bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
var bugsplat = BugSplat.Instance;
```

You can extend `BugSplat` by setting the following properties:
Expand All @@ -115,7 +115,7 @@ You can use the `Notes` field to capture arbitrary data such as system informati
```cs
void Start()
{
bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
bugsplat = BugSplat.Instance;
bugsplat.Notes = GetSystemInfo();
}

Expand Down Expand Up @@ -205,7 +205,7 @@ The methods `PostCrash`, `PostMostRecentCrash`, and `PostAllCrashes` can be used
```cs
void Start()
{
bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
bugsplat = BugSplat.Instance;
StartCoroutine(bugsplat.PostAllCrashes());
}

Expand All @@ -224,7 +224,7 @@ Utils.ForceCrash(ForcedCrashCategory.PureVirtualFunction);

### Windows Symbols

To enable the uploading of plugin symbols, generate an OAuth2 Client ID and Client Secret on the BugSplat [Integrations](https://app.bugsplat.com/v2/settings/database/integrations) page. Add your Client ID and Client Secret to the `BugSplatOptions` object you generated in the [Configuration](#⚙️-configuration) section. If your game contains Native Windows C++ plugins, `.dll` and `.pdb` files in the `Assets/Plugins/x86` and `Assets/Plugins/x86_64` folders will be uploaded by BugSplat's PostBuild script and used in symbolication.
To enable the uploading of plugin symbols, generate an OAuth2 Client ID and Client Secret on the BugSplat [Integrations](https://app.bugsplat.com/v2/settings/database/integrations) page. Add your Client ID and Client Secret via **Tools > BugSplat > Options**. If your game contains Native Windows C++ plugins, `.dll` and `.pdb` files in the `Assets/Plugins/x86` and `Assets/Plugins/x86_64` folders will be uploaded by BugSplat's PostBuild script and used in symbolication.

### Support Response

Expand Down
13 changes: 11 additions & 2 deletions Runtime/BugSplat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace BugSplatUnity
/// </summary>
public class BugSplat
{
/// <summary>
/// Global instance of BugSplat.
/// </summary>
public static BugSplat Instance { get; internal set; }

/// <summary>
/// A list of files to be uploaded every time Post is called
/// </summary>
Expand Down Expand Up @@ -250,6 +255,8 @@ bool useNativeLibAndroid
#else
UseDotNetHandler(database, application, version);
#endif

Instance = this;
}

private void UseDotNetHandler(string database, string application, string version)
Expand Down Expand Up @@ -298,16 +305,18 @@ public static BugSplat CreateFromOptions(BugSplatOptions options)
};

if (options.PersistentDataFileAttachmentPaths != null)
{
{
foreach (var filePath in options.PersistentDataFileAttachmentPaths)
{
var trimmedFilePath = filePath.TrimStart('/', '\\');
var fullFilePath = Path.Combine(Application.persistentDataPath, trimmedFilePath);
var fullFilePath = Path.Combine(Application.persistentDataPath, trimmedFilePath);
var fileInfo = new FileInfo(fullFilePath);
bugSplat.Attachments.Add(fileInfo);
}
}

Instance = bugSplat;

return bugSplat;
}

Expand Down
26 changes: 26 additions & 0 deletions Runtime/Manager/BugSplatInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using BugSplatUnity.Runtime.Client;
using UnityEngine;

namespace BugSplatUnity.Runtime.Manager
{
/// <summary>
/// Loads BugSplat configuration and creates the global instance at startup.
/// </summary>
internal static class BugSplatInitializer
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialize()
{
if (BugSplat.Instance != null)
{
return;
}

var options = Resources.Load<BugSplatOptions>("BugSplatOptions");
if (options != null)
{
BugSplat.Instance = BugSplat.CreateFromOptions(options);
}
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Manager/BugSplatInitializer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Runtime/Manager/BugSplatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ private void Awake()
throw new ArgumentException("BugSplat error: BugSplatOptions is null! BugSplat will not be initialized.");
}

var bugsplat = BugSplat.CreateFromOptions(bugSplatOptions);
bugsplatRef = new BugSplatRef(bugsplat);
var bugsplat = BugSplat.CreateFromOptions(bugSplatOptions);
BugSplat.Instance = bugsplat;
bugsplatRef = new BugSplatRef(bugsplat);

if (registerLogMessageReceived)
{
Expand Down
3 changes: 1 addition & 2 deletions Samples~/my-unity-crasher/Scripts/BugSplatSettings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using BugSplatUnity;
using BugSplatUnity.Runtime.Manager;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -12,7 +11,7 @@ public class BugSplatSettings : MonoBehaviour
// Start is called before the first frame update
void Start()
{
bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
bugsplat = BugSplat.Instance;
bugsplat.Attributes.Add("OS", SystemInfo.operatingSystem);
bugsplat.Attributes.Add("CPU", SystemInfo.processorType);
bugsplat.Attributes.Add("MEMORY", $"{SystemInfo.systemMemorySize} MB");
Expand Down
3 changes: 1 addition & 2 deletions Samples~/my-unity-crasher/Scripts/ErrorGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using UnityEngine;
using UnityEngine.Diagnostics;
using BugSplat = BugSplatUnity.BugSplat;
using BugSplatUnity.Runtime.Manager;
using BugSplatUnity;
using BugSplatUnity.Runtime.Reporter;
using System.Diagnostics;
Expand All @@ -19,7 +18,7 @@ public class ErrorGenerator : MonoBehaviour

void Start()
{
bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
bugsplat = BugSplat.Instance;
Application.SetStackTraceLogType(LogType.Warning, StackTraceLogType.Full);
#if UNITY_STANDALONE_WIN
StartCoroutine(bugsplat.PostMostRecentCrash());
Expand Down
16 changes: 16 additions & 0 deletions Tests/Runtime/Manager/BugSplatInstanceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using BugSplatUnity;
using NUnit.Framework;

namespace BugSplatUnity.RuntimeTests.Manager
{
public class BugSplatInstanceTests
{
[Test]
public void Constructor_ShouldSetInstance()
{
BugSplat.Instance = null;
var bugsplat = new BugSplat("database", "application", "version", false, false);
Assert.AreEqual(bugsplat, BugSplat.Instance);
}
}
}
12 changes: 12 additions & 0 deletions Tests/Runtime/Manager/BugSplatInstanceTests.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.