The following is a description of features that are commonly expected in Sentry SDKs. Make sure to also have read the unified API design documentation which explains the common API design.
Events should be transmitted in a background thread or similar system. This queue must be flushed when the application shuts down with a specific timeout. This feature is typically user facing and explained as part of shutdown and draining.
Ability for the SDK to be set as a hook to record any uncaught exceptions. At the language level this is typically a global hook provided by the language itself. For framework integrations this might be part of middleware or some other system.
This behavior is typically provided by a default integration that can be disabled.
Scopes should be provided by SDKs to set common attributes and context data on events sent to Sentry emitted from the current scope. They should be inherited to lower scopes so that they can be set "globally" on startup. Note that some attributes can only be set in the client options (
environment) and not on scopes.
What scope means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single scope that represents the single user and their actions. Scoping can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. See the scopes page for more information.
Automatic addition of useful attributes such as
extra or specific
contexts. Typically means the SDK hooks into a framework so that it can set attributes that are known to be useful for most users. Please check Data Handling for considerations.
Manually record application events (into the current scope) during the lifecycle of an application. Implement a ring buffer so as not to grow indefinitely. The most recent breadcrumbs should be attached to events as they occur.
With deeper framework integration, the automatic recording of breadcrumbs is possible and recommended, for example:
- UI Events: button clicks, touch events, etc.
- System Events: low battery, low storage space, airplane mode started, memory warnings, device orientation changed, etc.
- Outgoing HTTP requests
Check out the complete breadcrumb documentation for more types.
SDKs should allow the user to configure what percentage of events are actually sent to the server (the rest should be silently ignored). For example:
sample_rate = options.get('sample_rate', 1.0) # assuming random() returns a value between 0.0 (inclusive) and 1.0 (exclusive) if random() < sample_rate: transport.capture_event(event)
Respect Sentry’s HTTP 429
Retry-After header, or, if the SDK supports multiple payload types (e.g. errors and transactions), the
X-Sentry-Rate-Limits header. Outgoing SDK requests should be dropped during the backoff period.
See Rate Limiting for details.
Stack parsing can tell which frames should be identified as part of the user’s application (as opposed to part of the language, a library, or a framework), either automatically or by user configuration at startup, often declared as a package/module prefix.
Lines of source code to provide context in stack traces. This is easier in interpreted languages, may be hard or impossible in compiled ones.
Local variable names and values for each stack frame, where possible. Restrictions apply on some platforms, for example it’s may only be possible to collect the values of parameters passed into each function, or it may be completely impossible to collect this information at all.
Turn compiled or obfuscated code/method names in stack traces back into the original. Desymbolication always requires Sentry backend support. Not necessary for many languages.
Ability to get the ID of the last event sent. Event IDs are useful for correlation, logging, customers rolling their own feedback forms, etc.
On user-facing platforms such as mobile, desktop, or browser this means first-class support for requesting User Feedback when an error or crash occurs. To see some examples of the API check out the user-facing docs for Apple and Java.
On mobile and desktop, it is common to prompt the user for feedback after a crash happened on the previous run of the application. Therefore the SDKs should
onCrashedLastRun callback on the options. This callback gets called shortly after the initialization of the SDK when the last program execution
terminated with a crash. The SDK should execute the callback only once during the entire run of the program to avoid multiple callbacks if there are multiple
crash events to send.
On backend platforms, SDKs should document how to use the last event ID to prompt the user for feedback themselves.
User Feedback class:
Attachments are files stored alongside an event. To send an attachment, add it as an envelope item to the corresponding event.
We recommend implementing two types of attachments, one with a path and another with a byte array. If the programming language allows it, create one class with multiple constructors to keep things simple and guess the content type of the attachment via the filename.
The overload that takes a
path should consider:
- The SDK should read the file when an event gets captured and not when the user adds an attachment to the scope.
- If reading the attachment fails, the SDK should not drop the whole envelope, but just the attachment's envelope item.
- If the SDK is in debug mode log (
debug=true) out errors to make debugging easier.
If the SDK supports transactions, the attachments should offer a flag
that specifies if SDK adds the attachment to every transaction or not. The default should be
Alongside the implementation of attachments, add
maxAttachmentSize to the options and set the default to 20 MiB. When converting an attachment to an
envelope item, the SDK must discard items larger than the
maxAttachmentSize. Especially on SDKs with offline caching, typical on mobile, this is
useful because attachments could quickly eat up the users' disk space. Furthermore, Relay has a
maximum size for attachments, and we want to reduce unnecessary requests.
This feature only applies to SDKs with a user interface, such as Mobile and Desktop.
In some environments such as native iOS, taking a screenshot requires the UI thread and in the event of a crash, that might not be available. So inherently this feature will be a best effort solution.
Also, some environments don't allow access to the UI or some features during a hard crash, iOS, for example, doesn't allow running Objective-C code after a signal break, therefore no hard crash screenshot capture will be possible.
It's advised to provide this feature through a single option called
attachScreenshot. That's the preferred way but in platforms such as Flutter, a wrapping widget is required so documentation can point users to that instead of the suggested option name.
The feature is achieved by adding an attachment with:
- File name
- Subsequent screenshots in the same event should be named
screenshot-n, where n is the screenshot number starting with 2
- Subsequent screenshots in the same event should be named
- Image size, if possible should stay below 2 MB but quality/size could be configurable
Whenever possible, avoid adding the attachment altogether if taking the screenshot fails. Alternatively, when streaming, it's possible the envelope header was already flushed through before the attempt to take the screenshot happens. In this case, a 0 byte attachment will be included. In that case, Sentry will not show a screenshot preview.
Hook called with the event (and on some platforms the hint) that allow the user to decide whether an event should be sent or not. This can also be used to further modify the event.
Hook called with the breadcrumb (and on some platforms the hint) that allow the user to decide whether and how a breadcrumb should be sent.
Include a list of loaded libraries (and versions) when sending an event.
This feature is also known as 'Offline Caching'.
Write events to disk before attempting to send, so that they can be retried in the event of a temporary network failure. Needs to implement a cap on the number of stored events. This is mostly useful on mobile and desktop(e.g: laptop) apps, where stable connectivity is often not available.
It's important to note that retry is only considered in the event of a network failure. For example:
- Connection timeout
- DSN resolution failure
- Connection reset by peer
Other failures, like those caused by processing the file in the SDK itself, the payload should be discarded since those are likely to end up on an endless retry.
If the event reached Sentry and a HTTP response status code was received, even in the event of a
500 response, the event should be discarded.
Consider having the SDK retry sending events once the device is back online, when such notification exists in the platform.
Once the device is back online, the SDK is likely going to empty its disk queue in a quick burst of requests. This can trigger different abuse filters in Sentry. To account for that, it's considered to add a small delay between cached event captures. A recommended value is 100 milliseconds.
If the SDK is being rate-limited, which causes the SDK to drop any event that reaches its HTTP transport, cosider stop consuming the disk cache until the
Retry-After timeout is reached or the app restarts.
Ability to use an HTTP proxy. Often easy to implement using the existing HTTP client. This should be picked up from the system config if possible or explicit config in the client options.
Every HTTP client integration must exclude HTTP requests that match the configured DSN in the Options to exclude HTTP requests to Sentry.
Add a breadcrumb for each outgoing HTTP request after the request finishes:
- data (all fields are optional but recommended):
url- The URL used in the HTTP request
method- uppercase HTTP method, i.e: GET, HEAD
status_code- Numeric status code such as
request_body_sizeSize in bytes
response_body_sizeSize in bytes
If Performance Monitoring is both supported by the SDK and enabled in the client application when the transaction is active a new
Span must be created around the HTTP request:
$METHOD $url(uppercase HTTP method), e.g.
- HTTP requests must be enhanced with a
sentry-traceHTTP header to support distributed tracing
- HTTP requests must be enhanced with a
baggageHTTP header to support dynamic sampling
- span status must match HTTP response status code (see Span status to HTTP status code mapping)
- when network error occurs, span status must be set to
Ability for the SDK to attach request body to events and triggered during the execution of request.
User should be able to set a configuration option
maxRequestBodySize to instruct SDK how big requests bodies should be attached.
SDK controls what is an actual size in bytes for each option:
Some logging frameworks provide an option to set logging context. In Java this is called MDC (Mapped Diagnostic Context).
Users should be able to set a list of logging context entries in a configuration option
contextTags to tell the SDK to convert the entries to Sentry tags.