#![allow(unused)]
use std::sync::{Arc, RwLock};
use crate::protocol::{Event, Level, Log, LogAttribute, LogLevel, Map, SessionStatus};
use crate::types::Uuid;
use crate::{Integration, IntoBreadcrumbs, Scope, ScopeGuard};
#[derive(Debug)]
pub struct Hub {
#[cfg(feature = "client")]
pub(crate) inner: crate::hub_impl::HubImpl,
pub(crate) last_event_id: RwLock<Option<Uuid>>,
}
impl Hub {
pub fn with_active<F, R>(f: F) -> R
where
F: FnOnce(&Arc<Hub>) -> R,
R: Default,
{
with_client_impl! {{
Hub::with(|hub| {
if hub.is_active_and_usage_safe() {
f(hub)
} else {
Default::default()
}
})
}}
}
pub fn with_integration<I, F, R>(&self, f: F) -> R
where
I: Integration,
F: FnOnce(&I) -> R,
R: Default,
{
with_client_impl! {{
if let Some(client) = self.client() {
if let Some(integration) = client.get_integration::<I>() {
return f(integration);
}
}
Default::default()
}}
}
pub fn last_event_id(&self) -> Option<Uuid> {
*self.last_event_id.read().unwrap()
}
pub fn capture_event(&self, event: Event<'static>) -> Uuid {
with_client_impl! {{
let top = self.inner.with(|stack| stack.top().clone());
let Some(ref client) = top.client else { return Default::default() };
let event_id = client.capture_event(event, Some(&top.scope));
*self.last_event_id.write().unwrap() = Some(event_id);
event_id
}}
}
pub fn capture_message(&self, msg: &str, level: Level) -> Uuid {
with_client_impl! {{
let event = Event {
message: Some(msg.to_string()),
level,
..Default::default()
};
self.capture_event(event)
}}
}
#[cfg(feature = "release-health")]
pub fn start_session(&self) {
with_client_impl! {{
self.inner.with_mut(|stack| {
let top = stack.top_mut();
if let Some(session) = crate::session::Session::from_stack(top) {
let mut scope = Arc::make_mut(&mut top.scope);
scope.session = Arc::new(std::sync::Mutex::new(Some(session)));
}
})
}}
}
#[cfg(feature = "release-health")]
pub fn end_session(&self) {
self.end_session_with_status(SessionStatus::Exited)
}
#[cfg(feature = "release-health")]
pub fn end_session_with_status(&self, status: SessionStatus) {
with_client_impl! {{
self.inner.with_mut(|stack| {
let top = stack.top_mut();
if let Some(mut session) = top.scope.session.lock().unwrap().take() {
session.close(status);
}
})
}}
}
pub fn push_scope(&self) -> ScopeGuard {
with_client_impl! {{
self.inner.with_mut(|stack| {
stack.push();
ScopeGuard(Some((self.inner.stack.clone(), stack.depth())))
})
}}
}
pub fn with_scope<C, F, R>(&self, scope_config: C, callback: F) -> R
where
C: FnOnce(&mut Scope),
F: FnOnce() -> R,
{
#[cfg(feature = "client")]
{
let _guard = self.push_scope();
self.configure_scope(scope_config);
callback()
}
#[cfg(not(feature = "client"))]
{
let _scope_config = scope_config;
callback()
}
}
pub fn configure_scope<F, R>(&self, f: F) -> R
where
R: Default,
F: FnOnce(&mut Scope) -> R,
{
with_client_impl! {{
let mut new_scope = self.with_current_scope(|scope| scope.clone());
let rv = f(&mut new_scope);
self.with_current_scope_mut(|ptr| *ptr = new_scope);
rv
}}
}
pub fn add_breadcrumb<B: IntoBreadcrumbs>(&self, breadcrumb: B) {
with_client_impl! {{
self.inner.with_mut(|stack| {
let top = stack.top_mut();
if let Some(ref client) = top.client {
let scope = Arc::make_mut(&mut top.scope);
let options = client.options();
let breadcrumbs = Arc::make_mut(&mut scope.breadcrumbs);
for breadcrumb in breadcrumb.into_breadcrumbs() {
let breadcrumb_opt = match options.before_breadcrumb {
Some(ref callback) => callback(breadcrumb),
None => Some(breadcrumb)
};
if let Some(breadcrumb) = breadcrumb_opt {
breadcrumbs.push_back(breadcrumb);
}
while breadcrumbs.len() > options.max_breadcrumbs {
breadcrumbs.pop_front();
}
}
}
})
}}
}
#[cfg(feature = "logs")]
pub fn capture_log(&self, log: Log) {
with_client_impl! {{
let top = self.inner.with(|stack| stack.top().clone());
let Some(ref client) = top.client else { return };
client.capture_log(log, &top.scope);
}}
}
}