Skip to main content

ckb_sentry_contexts/
utils.rs

1use sentry_core::protocol::{Context, DeviceContext, Map, OsContext, RuntimeContext};
2
3include!(concat!(env!("OUT_DIR"), "/constants.gen.rs"));
4
5#[cfg(target_os = "macos")]
6mod model_support {
7    use libc::c_void;
8    use regex::Regex;
9    use std::ptr;
10
11    lazy_static::lazy_static! {
12        static ref FAMILY_RE: Regex = Regex::new(r#"([a-zA-Z]+)\d"#).unwrap();
13    }
14
15    pub fn get_model() -> Option<String> {
16        unsafe {
17            let mut size = 0;
18            libc::sysctlbyname(
19                "hw.model\x00".as_ptr() as *const i8,
20                ptr::null_mut(),
21                &mut size,
22                ptr::null_mut(),
23                0,
24            );
25            let mut buf = vec![0u8; size as usize];
26            libc::sysctlbyname(
27                "hw.model\x00".as_ptr() as *const i8,
28                buf.as_mut_ptr() as *mut c_void,
29                &mut size,
30                ptr::null_mut(),
31                0,
32            );
33            Some(
34                String::from_utf8_lossy(if buf.ends_with(b"\x00") {
35                    &buf[..size - 1]
36                } else {
37                    &buf
38                })
39                .to_string(),
40            )
41        }
42    }
43
44    pub fn get_family() -> Option<String> {
45        get_model()
46            .as_ref()
47            .and_then(|model| FAMILY_RE.captures(model))
48            .and_then(|m| m.get(1))
49            .map(|group| group.as_str().to_string())
50    }
51}
52
53#[cfg(not(target_os = "macos"))]
54mod model_support {
55    pub fn get_model() -> Option<String> {
56        None
57    }
58
59    pub fn get_family() -> Option<String> {
60        None
61    }
62}
63
64/// Returns the server name (hostname) if available.
65pub fn server_name() -> Option<String> {
66    hostname::get().ok().and_then(|s| s.into_string().ok())
67}
68
69/// Returns the OS context
70pub fn os_context() -> Option<Context> {
71    #[cfg(not(windows))]
72    {
73        use uname::uname;
74        if let Ok(info) = uname() {
75            Some(
76                OsContext {
77                    name: Some(info.sysname),
78                    kernel_version: Some(info.version),
79                    version: Some(info.release),
80                    ..Default::default()
81                }
82                .into(),
83            )
84        } else {
85            None
86        }
87    }
88    #[cfg(windows)]
89    {
90        Some(
91            OsContext {
92                name: Some(PLATFORM.into()),
93                ..Default::default()
94            }
95            .into(),
96        )
97    }
98}
99
100/// Returns the rust info.
101pub fn rust_context() -> Context {
102    RuntimeContext {
103        name: Some("rustc".into()),
104        version: RUSTC_VERSION.map(|x| x.into()),
105        other: {
106            let mut map = Map::default();
107            if let Some(channel) = RUSTC_CHANNEL {
108                map.insert("channel".to_string(), channel.into());
109            }
110            map
111        },
112    }
113    .into()
114}
115
116/// Returns the device context.
117pub fn device_context() -> Context {
118    DeviceContext {
119        model: model_support::get_model(),
120        family: model_support::get_family(),
121        arch: Some(ARCH.into()),
122        ..Default::default()
123    }
124    .into()
125}