Skip to content

Commit e3c20dc

Browse files
authored
feat: Sync attachments on Android, Windows, and Linux (#2609)
1 parent 416968d commit e3c20dc

File tree

8 files changed

+104
-12
lines changed

8 files changed

+104
-12
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
### Features
1010

11-
- The _Metrics_ APIs are now stable: removed `Experimental` from `SentrySdk` and `SentryOptions`. ([#2615](https://github.com/getsentry/sentry-unity/pull/2615))
11+
- The _Metrics_ APIs are now stable: removed `Experimental` from `SentrySdk` and `SentryOptions` ([#2615](https://github.com/getsentry/sentry-unity/pull/2615))
12+
- Attachments added to the scope are now included in native crash reports on Android, Windows, and Linux ([#2609](https://github.com/getsentry/sentry-unity/pull/2609))
1213

1314
### Dependencies
1415

src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ public override void UnsetUserImpl() =>
3737
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
3838
_sentryJava.SetTrace(traceId, spanId);
3939

40-
public override void AddAttachmentImpl(SentryAttachment attachment) { }
40+
public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType) =>
41+
_sentryJava.AddAttachment(filePath, fileName, contentType);
4142

42-
public override void ClearAttachmentsImpl() { }
43+
public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType) =>
44+
_sentryJava.AddAttachmentBytes(data, fileName, contentType);
45+
46+
public override void ClearAttachmentsImpl() =>
47+
_sentryJava.ClearAttachments();
4348
}

src/Sentry.Unity.Android/SentryJava.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public void WriteScope(
4242
public void SetUser(SentryUser user);
4343
public void UnsetUser();
4444
public void SetTrace(SentryId traceId, SpanId spanId);
45+
void AddAttachment(string path, string fileName, string? contentType);
46+
void AddAttachmentBytes(byte[] data, string fileName, string? contentType);
47+
void ClearAttachments();
4548
}
4649

4750
/// <summary>
@@ -361,6 +364,44 @@ public void SetTrace(SentryId traceId, SpanId spanId)
361364
});
362365
}
363366

367+
public void AddAttachment(string path, string fileName, string? contentType)
368+
{
369+
RunJniSafe(() =>
370+
{
371+
using var attachment = contentType is not null
372+
? new AndroidJavaObject("io.sentry.Attachment", path, fileName, contentType)
373+
: new AndroidJavaObject("io.sentry.Attachment", path, fileName);
374+
375+
using var sentry = GetSentryJava();
376+
sentry.CallStatic("configureScope", new ScopeCallback(scope =>
377+
scope.Call("addAttachment", attachment)));
378+
});
379+
}
380+
381+
public void AddAttachmentBytes(byte[] data, string fileName, string? contentType)
382+
{
383+
RunJniSafe(() =>
384+
{
385+
using var attachment = contentType is not null
386+
? new AndroidJavaObject("io.sentry.Attachment", data, fileName, contentType)
387+
: new AndroidJavaObject("io.sentry.Attachment", data, fileName);
388+
389+
using var sentry = GetSentryJava();
390+
sentry.CallStatic("configureScope", new ScopeCallback(scope =>
391+
scope.Call("addAttachment", attachment)));
392+
});
393+
}
394+
395+
public void ClearAttachments()
396+
{
397+
RunJniSafe(() =>
398+
{
399+
using var sentry = GetSentryJava();
400+
sentry.CallStatic("configureScope", new ScopeCallback(scope =>
401+
scope.Call("clearAttachments")));
402+
});
403+
}
404+
364405
// https://github.com/getsentry/sentry-java/blob/db4dfc92f202b1cefc48d019fdabe24d487db923/sentry/src/main/java/io/sentry/SentryLevel.java#L4-L9
365406
internal static string GetLevelString(SentryLevel level) => level switch
366407
{

src/Sentry.Unity.Native/CFunctions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,15 @@ internal static void SetValueIfNotNull(sentry_value_t obj, string key, long? val
165165
[DllImport(SentryLib)]
166166
internal static extern void sentry_set_trace(string traceId, string parentSpanId);
167167

168+
[DllImport(SentryLib)]
169+
internal static extern IntPtr sentry_attach_file(string path);
170+
171+
[DllImport(SentryLib)]
172+
internal static extern IntPtr sentry_attach_bytes(byte[] buf, UIntPtr buf_len, string filename);
173+
174+
[DllImport(SentryLib)]
175+
internal static extern void sentry_clear_attachments();
176+
168177
internal static readonly Lazy<IEnumerable<DebugImage>> DebugImages = new(LoadDebugImages);
169178

170179
private static IEnumerable<DebugImage> LoadDebugImages()

src/Sentry.Unity.Native/NativeScopeObserver.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@ public override void SetUserImpl(SentryUser user)
4343
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
4444
C.sentry_set_trace(traceId.ToString(), spanId.ToString());
4545

46-
public override void AddAttachmentImpl(SentryAttachment attachment) { }
46+
public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType) =>
47+
C.sentry_attach_file(filePath);
4748

48-
public override void ClearAttachmentsImpl() { }
49+
public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType) =>
50+
C.sentry_attach_bytes(data, (UIntPtr)data.Length, fileName);
51+
52+
public override void ClearAttachmentsImpl() =>
53+
C.sentry_clear_attachments();
4954

5055
private static string GetTimestamp(DateTimeOffset timestamp) =>
5156
// "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.

src/Sentry.Unity.iOS/NativeScopeObserver.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,26 @@ public override void SetUserImpl(SentryUser user) =>
2929
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
3030
SentryCocoaBridgeProxy.SetTrace(traceId.ToString(), spanId.ToString());
3131

32+
public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType)
33+
{
34+
// iOS/macOS attachment sync to sentry-cocoa is not yet supported.
35+
}
36+
37+
public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType)
38+
{
39+
// iOS/macOS attachment sync to sentry-cocoa is not yet supported.
40+
}
41+
42+
public override void ClearAttachmentsImpl()
43+
{
44+
// iOS/macOS attachment sync to sentry-cocoa is not yet supported.
45+
}
46+
3247
internal static string GetTimestamp(DateTimeOffset timestamp) =>
3348
// "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.
3449
// https://docs.microsoft.com/en-gb/dotnet/standard/base-types/standard-date-and-time-format-strings#Roundtrip
3550
timestamp.ToString("o");
3651

37-
public override void AddAttachmentImpl(SentryAttachment attachment) { }
38-
39-
public override void ClearAttachmentsImpl() { }
40-
4152
internal static int GetBreadcrumbLevel(BreadcrumbLevel breadcrumbLevel) =>
4253
// https://github.com/getsentry/sentry-cocoa/blob/50f955aeb214601dd62b5dae7abdaddc8a1f24d9/Sources/Sentry/Public/SentryDefines.h#L99-L105
4354
breadcrumbLevel switch

src/Sentry.Unity/ScopeObserver.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,25 @@ public void SetTrace(SentryId traceId, SpanId spanId)
8989

9090
public void AddAttachment(SentryAttachment attachment)
9191
{
92-
_options.LogDebug("{0} Scope Sync - Adding attachment", _name);
93-
AddAttachmentImpl(attachment);
92+
if (attachment.Content is FileAttachmentContent fileContent)
93+
{
94+
_options.LogDebug("{0} Scope Sync - Adding file attachment \"{1}\"", _name, fileContent.FilePath);
95+
AddFileAttachmentImpl(fileContent.FilePath, attachment.FileName, attachment.ContentType);
96+
}
97+
else if (attachment.Content is ByteAttachmentContent byteContent)
98+
{
99+
_options.LogDebug("{0} Scope Sync - Adding byte attachment \"{1}\" ({2} bytes)", _name, attachment.FileName, byteContent.Bytes.Length);
100+
AddByteAttachmentImpl(byteContent.Bytes, attachment.FileName, attachment.ContentType);
101+
}
102+
else
103+
{
104+
_options.LogDebug("{0} Scope Sync - Skipping attachment \"{1}\" (unsupported content type for native sync)", _name, attachment.FileName);
105+
}
94106
}
95107

96-
public abstract void AddAttachmentImpl(SentryAttachment attachment);
108+
public abstract void AddFileAttachmentImpl(string filePath, string fileName, string? contentType);
109+
110+
public abstract void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType);
97111

98112
public void ClearAttachments()
99113
{

test/Sentry.Unity.Android.Tests/TestSentryJava.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,10 @@ public void SetUser(SentryUser user) { }
5454
public void UnsetUser() { }
5555

5656
public void SetTrace(SentryId traceId, SpanId spanId) { }
57+
58+
public void AddAttachment(string path, string fileName, string? contentType) { }
59+
60+
public void AddAttachmentBytes(byte[] data, string fileName, string? contentType) { }
61+
62+
public void ClearAttachments() { }
5763
}

0 commit comments

Comments
 (0)