Skip to content

Commit d9fac27

Browse files
authored
feat: End sessions with explicit status (#289)
This adds the `end_session_with_status` global and Hub functions that allow providing an explicit `SessionStatus`.
1 parent bb3b777 commit d9fac27

File tree

5 files changed

+52
-19
lines changed

5 files changed

+52
-19
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
- The `log` and `slog` integrations were re-designed, they now offer types that wrap a `log::Log` or `slog::Drain` and forward log events to the currently active sentry `Hub` based on an optional filter and an optional mapper.
1212
- The new `log` integration will not implicitly call `log::set_max_level_filter` anymore, and users need to do so manually.
1313

14+
**Features**:
15+
16+
- Add the new `end_session_with_status` global and Hub functions which allow ending a Release Health Session with an explicit `SessionStatus`.
17+
1418
**Deprecations**:
1519

1620
- The `error-chain` and `failure` integration was officially deprecated and will be removed soon.

sentry-core/src/api.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use sentry_types::protocol::v7::SessionStatus;
2+
13
use crate::protocol::{Event, Level};
24
use crate::types::Uuid;
35
use crate::{Hub, Integration, IntoBreadcrumbs, Scope};
@@ -283,5 +285,16 @@ pub fn start_session() {
283285

284286
/// End the current Release Health Session.
285287
pub fn end_session() {
286-
Hub::with_active(|hub| hub.end_session())
288+
end_session_with_status(SessionStatus::Exited)
289+
}
290+
291+
/// End the current Release Health Session with the given [`SessionStatus`].
292+
///
293+
/// By default, the SDK will only consider the `Exited` and `Crashed` status
294+
/// based on the type of events that were captured during the session.
295+
///
296+
/// When an `Abnormal` session should be captured, it has to be done explicitly
297+
/// using this function.
298+
pub fn end_session_with_status(status: SessionStatus) {
299+
Hub::with_active(|hub| hub.end_session_with_status(status))
287300
}

sentry-core/src/client.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,6 @@ impl Client {
279279
self.session_flusher.enqueue(session_update)
280280
}
281281

282-
pub(crate) fn capture_envelope(&self, envelope: Envelope) {
283-
if let Some(ref transport) = *self.transport.read().unwrap() {
284-
transport.send_envelope(envelope);
285-
}
286-
}
287-
288282
/// Drains all pending events and shuts down the transport behind the
289283
/// client. After shutting down the transport is removed.
290284
///

sentry-core/src/hub.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -331,21 +331,22 @@ impl Hub {
331331

332332
/// End the current Release Health Session.
333333
///
334-
/// See the global [`end_session`](fn.end_session.html)
334+
/// See the global [`end_session`](crate::end_session_with)
335335
/// for more documentation.
336336
pub fn end_session(&self) {
337+
self.end_session_with_status(SessionStatus::Exited)
338+
}
339+
/// End the current Release Health Session with the given [`SessionStatus`].
340+
///
341+
/// See the global [`end_session_with_status`](crate::end_session_with_status)
342+
/// for more documentation.
343+
pub fn end_session_with_status(&self, status: SessionStatus) {
337344
with_client_impl! {{
338345
self.inner.with_mut(|stack| {
339346
let top = stack.top_mut();
347+
// drop will close and enqueue the session
340348
if let Some(mut session) = top.scope.session.lock().unwrap().take() {
341-
session.close();
342-
if let Some(item) = session.create_envelope_item() {
343-
let mut envelope = Envelope::new();
344-
envelope.add_item(item);
345-
if let Some(ref client) = top.client {
346-
client.capture_envelope(envelope);
347-
}
348-
}
349+
session.close(status);
349350
}
350351
})
351352
}}

sentry-core/src/session.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub struct Session {
2424

2525
impl Drop for Session {
2626
fn drop(&mut self) {
27-
self.close();
27+
self.close(SessionStatus::Exited);
2828
if self.dirty {
2929
self.client.enqueue_session(self.session_update.clone());
3030
}
@@ -95,10 +95,14 @@ impl Session {
9595
}
9696
}
9797

98-
pub(crate) fn close(&mut self) {
98+
pub(crate) fn close(&mut self, status: SessionStatus) {
9999
if self.session_update.status == SessionStatus::Ok {
100+
let status = match status {
101+
SessionStatus::Ok => SessionStatus::Exited,
102+
s => s,
103+
};
100104
self.session_update.duration = Some(self.started.elapsed().as_secs_f64());
101-
self.session_update.status = SessionStatus::Exited;
105+
self.session_update.status = status;
102106
self.dirty = true;
103107
}
104108
}
@@ -329,6 +333,23 @@ mod tests {
329333
assert_eq!(items.next(), None);
330334
}
331335

336+
#[test]
337+
fn test_session_abnormal() {
338+
let envelopes = capture_envelopes(|| {
339+
sentry::start_session();
340+
sentry::end_session_with_status(SessionStatus::Abnormal);
341+
});
342+
assert_eq!(envelopes.len(), 1);
343+
344+
let mut items = envelopes[0].items();
345+
if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() {
346+
assert_eq!(session.status, SessionStatus::Abnormal);
347+
assert_eq!(session.init, true);
348+
} else {
349+
panic!("expected session");
350+
}
351+
assert_eq!(items.next(), None);
352+
}
332353
#[test]
333354
fn test_session_sampled_errors() {
334355
let mut envelopes = crate::test::with_captured_envelopes_options(

0 commit comments

Comments
 (0)