Conversation
Adds GzipFileAttachmentContent, a FileAttachmentContent whose stream gzips the file as it is read, and an AddAttachment(filePath, compress) overload on Scope and SentryHint. The file is opened when the event is captured but only read and compressed when the envelope is serialized on the background worker, so a large log costs the capturing thread nothing. Scope observers that sync file attachments to native SDKs still receive the uncompressed path.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5619 +/- ##
==========================================
+ Coverage 74.87% 74.91% +0.04%
==========================================
Files 515 517 +2
Lines 18962 19029 +67
Branches 3694 3704 +10
==========================================
+ Hits 14197 14255 +58
- Misses 3888 3897 +9
Partials 877 877 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks for the contribution @lgarczyn. It's an intersting idea but we've got a number of concerns:
I'll close this PR for changes to the SDK. However, |
I mean, if the text file is gzipped when sent to sentry, and gzipped on the way back, maybe it should be gzipped in storage on sentry. I don't mind losing the preview. |
Did you look at implementing
That's probably something to take up in the core Sentry repo... we don't control that (directly) via the SDKs. Doing it via that route would also make it possible to implement without breaking the preview functionality and would mean consistent behaviour across all of the SDKs (vs carving out an exception for just the sentry-dotnet SDK). |
Adds
GzipFileAttachmentContent, aFileAttachmentContentwhose stream gzips the file as it is read, plus anAddAttachment(filePath, compress: true)overload onScopeandSentryHint.Ai-generated (Fable)
Why
We like to attach logs to crashes. But it's expensive as hell, even if the logs are the same thing over and over.
Compressing it on the capturing thread is not an option either, since
IAttachmentContent.GetStream()runs synchronously insideCaptureEvent. The SDK already buffers non-seekable payloads on its background worker when serializing the envelope, so a stream that compresses lazily onReadis entirely outside the main thread.What
GzipFileAttachmentContent : FileAttachmentContent. Opens the file when the event is captured (same as the base class, so a missing file logs and skips the attachment), reads and compresses only when the envelope is serialized. Because it is aFileAttachmentContent, scope observers that sync file attachments to native SDKs still receive the path of the uncompressed file.FileAttachmentContent.GetStream()becomesvirtual.Scope.AddAttachment(string filePath, bool compress, ...)andSentryHint.AddAttachment(string filePath, bool compress, ...). A compressed attachment is named<file>.gzwith content typeapplication/gzipunless one is given.GzipReadStream: read-only, non-seekable, pulls the source throughGZipStreamchunk by chunk.Tests
Round trip through gunzip for empty, small and multi-chunk inputs, small-buffer reads, no read at construction, file not locked, envelope round trip with the
lengthheader matching the compressed bytes, the scope observer receiving aFileAttachmentContentwith the raw path. API approval snapshots updated for all target frameworks.Changelog Entry
GzipFileAttachmentContentandScope/SentryHint.AddAttachment(filePath, compress: true)attach a file gzip-compressed, with the compression done on the background worker