Skip to content

Commit 2ccdfa9

Browse files
authored
feat: Structured Logging (#2368)
1 parent 742f67f commit 2ccdfa9

File tree

14 files changed

+554
-120
lines changed

14 files changed

+554
-120
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
# Changelog
22

3-
## Unreleased
3+
## Unreleased
44

55
### Breaking Changes
66

77
- `sentry-native` is now built on Ubuntu 22.04 instead of Ubuntu 20.04, which reached EOL in May 2025. If you are running you game on a server on Ubuntu 20.04, you should update the OS before upgrading to this SDK version. ([#2355](https://github.com/getsentry/sentry-unity/pull/2355))
88

9+
### Features
10+
11+
- Added support for Structured Logging. The `SentrySdk.Logger` API is now exposed for Unity users, enabling structured log capture. The SDK can also automatically capture and send Debug logs based on the options configured. ([#2368](https://github.com/getsentry/sentry-unity/pull/2368))
12+
913
### Dependencies
1014

1115
- Bump CLI from v2.56.0 to v2.56.1 ([#2356](https://github.com/getsentry/sentry-unity/pull/2356))

samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@ MonoBehaviour:
3535
<MaxViewHierarchyRootObjects>k__BackingField: 100
3636
<MaxViewHierarchyObjectChildCount>k__BackingField: 20
3737
<MaxViewHierarchyDepth>k__BackingField: 10
38+
<EnableStructuredLogging>k__BackingField: 1
39+
<StructuredLogOnDebugLog>k__BackingField: 0
40+
<StructuredLogOnDebugLogWarning>k__BackingField: 1
41+
<StructuredLogOnDebugLogAssertion>k__BackingField: 1
42+
<StructuredLogOnDebugLogError>k__BackingField: 1
43+
<StructuredLogOnDebugLogException>k__BackingField: 1
44+
<AttachBreadcrumbsToEvents>k__BackingField: 0
3845
<BreadcrumbsForLogs>k__BackingField: 1
3946
<BreadcrumbsForWarnings>k__BackingField: 1
4047
<BreadcrumbsForAsserts>k__BackingField: 1
4148
<BreadcrumbsForErrors>k__BackingField: 1
42-
<BreadcrumbsForExceptions>k__BackingField: 1
4349
<CaptureLogErrorEvents>k__BackingField: 1
4450
<MaxBreadcrumbs>k__BackingField: 100
4551
<ReportAssembliesMode>k__BackingField: 1
@@ -51,7 +57,7 @@ MonoBehaviour:
5157
<SampleRate>k__BackingField: 1
5258
<ShutdownTimeout>k__BackingField: 2000
5359
<MaxQueueItems>k__BackingField: 30
54-
<AnrDetectionEnabled>k__BackingField: 1
60+
<AnrDetectionEnabled>k__BackingField: 0
5561
<AnrTimeout>k__BackingField: 5000
5662
<CaptureFailedRequests>k__BackingField: 1
5763
<FailedRequestStatusCodes>k__BackingField: f401000057020000

samples/unity-of-bugs/Assets/Scripts/BugFarmButtons.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void LogError()
7171
// Error logs get captured as messages and do not have a stacktrace attached by default. This is an opt-in feature.
7272
// Note: That stack traces generated for message events are provided without line numbers. See known limitations
7373
// https://docs.sentry.io/platforms/unity/troubleshooting/known-limitations/#line-numbers-missing-in-events-captured-through-debuglogerror-or-sentrysdkcapturemessage
74-
Debug.LogError("Debug.LogError() called");
74+
Debug.LogError("This is a 'Debug.LogError()' message.");
7575
}
7676
}
7777

samples/unity-of-bugs/Assets/Scripts/ThreadingSamples.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void LogError()
8181
// Error logs get captured as messages and do not have a stacktrace attached by default. This is an opt-in feature.
8282
// Note: That stack traces generated for message events are provided without line numbers. See known limitations
8383
// https://docs.sentry.io/platforms/unity/troubleshooting/known-limitations/#line-numbers-missing-in-events-captured-through-debuglogerror-or-sentrysdkcapturemessage
84-
Debug.LogError("Debug.LogError() called");
84+
Debug.LogError("This is a 'Debug.LogError()' message.");
8585
}
8686
});
8787
}

src/Sentry.Unity.Editor/ConfigurationWindow/LoggingTab.cs

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,35 @@ internal static class LoggingTab
99
internal static void Display(ScriptableSentryUnityOptions options)
1010
{
1111
{
12-
options.EnableLogDebouncing = EditorGUILayout.BeginToggleGroup(
13-
new GUIContent("Enable Log Debouncing", "The SDK debounces log messages of the " +
14-
"same type if they are more frequent than once per second."),
15-
options.EnableLogDebouncing);
12+
GUILayout.Label("Structured Logging - Experimental", EditorStyles.boldLabel);
13+
14+
options.EnableStructuredLogging = EditorGUILayout.BeginToggleGroup(
15+
new GUIContent("Send Logs for:", "Enables the SDK to forward log messages to Sentry " +
16+
"based on the log level."),
17+
options.EnableStructuredLogging);
1618

1719
EditorGUI.indentLevel++;
1820

19-
options.DebounceTimeLog = EditorGUILayout.IntField(
20-
new GUIContent("Log Debounce [ms]", "The time that has to pass between events of " +
21-
"LogType.Log before the SDK sends it again."),
22-
options.DebounceTimeLog);
23-
options.DebounceTimeLog = Math.Max(0, options.DebounceTimeLog);
24-
25-
options.DebounceTimeWarning = EditorGUILayout.IntField(
26-
new GUIContent("Warning Debounce [ms]", "The time that has to pass between events of " +
27-
"LogType.Warning before the SDK sends it again."),
28-
options.DebounceTimeWarning);
29-
options.DebounceTimeWarning = Math.Max(0, options.DebounceTimeWarning);
30-
31-
options.DebounceTimeError = EditorGUILayout.IntField(
32-
new GUIContent("Error Debounce [ms]", "The time that has to pass between events of " +
33-
"LogType.Assert, LogType.Exception and LogType.Error before " +
34-
"the SDK sends it again."),
35-
options.DebounceTimeError);
36-
options.DebounceTimeError = Math.Max(0, options.DebounceTimeError);
21+
options.StructuredLogOnDebugLog = EditorGUILayout.Toggle(
22+
new GUIContent("Debug.Log",
23+
"Whether the SDK should forward Debug.Log messages to Sentry structured logging"),
24+
options.StructuredLogOnDebugLog);
25+
options.StructuredLogOnDebugLogWarning = EditorGUILayout.Toggle(
26+
new GUIContent("Debug.LogWarning",
27+
"Whether the SDK should forward Debug.LogWarning messages to Sentry structured logging"),
28+
options.StructuredLogOnDebugLogWarning);
29+
options.StructuredLogOnDebugLogAssertion = EditorGUILayout.Toggle(
30+
new GUIContent("Debug.LogAssertion",
31+
"Whether the SDK should forward Debug.LogAssertion messages to Sentry structured logging"),
32+
options.StructuredLogOnDebugLogAssertion);
33+
options.StructuredLogOnDebugLogError = EditorGUILayout.Toggle(
34+
new GUIContent("Debug.LogError",
35+
"Whether the SDK should forward Debug.LogError messages to Sentry structured logging"),
36+
options.StructuredLogOnDebugLogError);
37+
options.StructuredLogOnDebugLogException = EditorGUILayout.Toggle(
38+
new GUIContent("Debug.LogException",
39+
"Whether the SDK should forward Debug.LogException messages to Sentry structured logging"),
40+
options.StructuredLogOnDebugLogException);
3741

3842
EditorGUI.indentLevel--;
3943
EditorGUILayout.EndToggleGroup();
@@ -44,65 +48,109 @@ internal static void Display(ScriptableSentryUnityOptions options)
4448
EditorGUILayout.Space();
4549

4650
{
47-
GUILayout.Label("Automatically capture and send events for:", EditorStyles.boldLabel);
48-
EditorGUI.indentLevel++;
51+
GUILayout.Label("Breadcrumbs", EditorStyles.boldLabel);
4952

50-
options.CaptureLogErrorEvents = EditorGUILayout.Toggle(
51-
new GUIContent("Debug.LogError", "Whether the SDK automatically captures events for 'Debug.LogError'."),
52-
options.CaptureLogErrorEvents);
53+
if (options.EnableStructuredLogging)
54+
{
55+
options.AttachBreadcrumbsToEvents = EditorGUILayout.BeginToggleGroup(
56+
new GUIContent("Attach logs as breadcrumbs in addition to sending them as structured logs", "Whether the SDK should attach breadcrumbs to events in addition to structured logging."),
57+
options.AttachBreadcrumbsToEvents);
5358

54-
EditorGUILayout.Space();
55-
GUILayout.Label("Automatically add breadcrumbs for:", EditorStyles.boldLabel);
59+
GUILayout.Label("Note: With sending structured logs enabled you have to opt-into adding breadcrumbs to events.", EditorStyles.boldLabel);
60+
}
61+
62+
EditorGUI.indentLevel++;
5663

5764
options.BreadcrumbsForLogs = EditorGUILayout.Toggle(
5865
new GUIContent("Debug.Log", "Whether the SDK automatically adds breadcrumbs 'Debug.Log'."),
5966
options.BreadcrumbsForLogs);
6067
options.BreadcrumbsForWarnings = EditorGUILayout.Toggle(
61-
new GUIContent("Debug.Warning", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogWarning'."),
68+
new GUIContent("Debug.LogWarning", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogWarning'."),
6269
options.BreadcrumbsForWarnings);
6370
options.BreadcrumbsForAsserts = EditorGUILayout.Toggle(
64-
new GUIContent("Debug.Assert", "Whether the SDK automatically adds breadcrumbs for 'Debug.Assert'."),
71+
new GUIContent("Debug.LogAssertion", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogAssertion'."),
6572
options.BreadcrumbsForAsserts);
6673
options.BreadcrumbsForErrors = EditorGUILayout.Toggle(
67-
new GUIContent("Debug.Error", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogError'."),
74+
new GUIContent("Debug.LogError", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogError'."),
6875
options.BreadcrumbsForErrors);
6976

70-
EditorGUI.indentLevel--;
71-
}
72-
73-
EditorGUILayout.Space();
74-
EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray);
75-
EditorGUILayout.Space();
77+
EditorGUILayout.Space();
7678

77-
{
7879
options.MaxBreadcrumbs = EditorGUILayout.IntField(
7980
new GUIContent("Max Breadcrumbs", "Maximum number of breadcrumbs that get captured." +
8081
"\nDefault: 100"),
8182
options.MaxBreadcrumbs);
8283
options.MaxBreadcrumbs = Math.Max(0, options.MaxBreadcrumbs);
84+
85+
EditorGUI.indentLevel--;
86+
if (options.EnableStructuredLogging)
87+
{
88+
EditorGUILayout.EndToggleGroup();
89+
}
8390
}
8491

8592
EditorGUILayout.Space();
8693
EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray);
8794
EditorGUILayout.Space();
8895

8996
{
90-
GUILayout.Label("Attach the stack trace when capturing log messages. NOTE: These will not contain line numbers.", EditorStyles.boldLabel);
97+
GUILayout.Label("CaptureMessage Settings", EditorStyles.boldLabel);
9198
EditorGUI.indentLevel++;
9299

100+
options.CaptureLogErrorEvents = EditorGUILayout.Toggle(
101+
new GUIContent("Capture LogError", "Whether the SDK automatically captures events for 'Debug.LogError'."),
102+
options.CaptureLogErrorEvents);
103+
93104
options.AttachStacktrace = EditorGUILayout.Toggle(
94-
new GUIContent("Attach Stack Trace", "Whether to include a stack trace for non " +
95-
"error events like logs. Even when Unity didn't include and no " +
96-
"exception was thrown. Refer to AttachStacktrace on sentry docs."),
105+
new GUIContent("Attach Stack Trace", "Whether the SDK should include a stack trace for CaptureMessage " +
106+
"events. Refer to AttachStacktrace on sentry docs."),
97107
options.AttachStacktrace);
98108

99-
EditorGUI.indentLevel--;
109+
GUILayout.Label("Note: The stack trace quality will depend on the IL2CPP line number setting and might not contain line numbers.", EditorStyles.boldLabel);
110+
100111
// Enhanced not supported on IL2CPP so not displaying this for the time being:
101112
// Options.StackTraceMode = (StackTraceMode) EditorGUILayout.EnumPopup(
102113
// new GUIContent("Stacktrace Mode", "Enhanced is the default." +
103114
// "\n - Enhanced: Include async, return type, args,..." +
104115
// "\n - Original - Default .NET stack trace format."),
105116
// Options.StackTraceMode);
117+
118+
EditorGUI.indentLevel--;
119+
}
120+
121+
EditorGUILayout.Space();
122+
EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray);
123+
EditorGUILayout.Space();
124+
125+
{
126+
options.EnableLogDebouncing = EditorGUILayout.BeginToggleGroup(
127+
new GUIContent("Enable Log Debouncing", "The SDK debounces log messages of the " +
128+
"same type if they are more frequent than once per second."),
129+
options.EnableLogDebouncing);
130+
131+
EditorGUI.indentLevel++;
132+
133+
options.DebounceTimeLog = EditorGUILayout.IntField(
134+
new GUIContent("Log Debounce [ms]", "The time that has to pass between events of " +
135+
"LogType.Log before the SDK sends it again."),
136+
options.DebounceTimeLog);
137+
options.DebounceTimeLog = Math.Max(0, options.DebounceTimeLog);
138+
139+
options.DebounceTimeWarning = EditorGUILayout.IntField(
140+
new GUIContent("Warning Debounce [ms]", "The time that has to pass between events of " +
141+
"LogType.Warning before the SDK sends it again."),
142+
options.DebounceTimeWarning);
143+
options.DebounceTimeWarning = Math.Max(0, options.DebounceTimeWarning);
144+
145+
options.DebounceTimeError = EditorGUILayout.IntField(
146+
new GUIContent("Error Debounce [ms]", "The time that has to pass between events of " +
147+
"LogType.Assert, LogType.Exception and LogType.Error before " +
148+
"the SDK sends it again."),
149+
options.DebounceTimeError);
150+
options.DebounceTimeError = Math.Max(0, options.DebounceTimeError);
151+
152+
EditorGUI.indentLevel--;
153+
EditorGUILayout.EndToggleGroup();
106154
}
107155
}
108156
}

0 commit comments

Comments
 (0)