Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

**Features**:

- Add Memory Info context to event schema. ([#5154](https://github.com/getsentry/relay/pull/5154))
- Add Thread Pool Info context to event schema. ([#5153](https://github.com/getsentry/relay/pull/5153))

## 25.9.0
Expand Down
168 changes: 168 additions & 0 deletions relay-event-schema/src/protocol/contexts/memory_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
use relay_protocol::{Annotated, Array, Empty, FromValue, IntoValue, Object, Value};

use crate::processor::ProcessValue;

/// Memory Info Context
#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)]
pub struct MemoryInfoContext {
/// Currently allocated memory in bytes.
pub allocated_bytes: Annotated<u64>,

/// Boolean indicating if memory was compacted.
pub compacted: Annotated<bool>,

/// Boolean indicating if concurrent garbage collection occurred.
pub concurrent: Annotated<bool>,

/// Number of objects awaiting finalization.
pub finalization_pending_count: Annotated<u64>,

/// Fragmented memory that cannot be used in bytes.
pub fragmented_bytes: Annotated<u64>,

/// Total heap size in bytes.
pub heap_size_bytes: Annotated<u64>,

/// Threshold for high memory load detection in bytes.
pub high_memory_load_threshold_bytes: Annotated<u64>,

/// GC generation index.
pub index: Annotated<u64>,

/// Current memory load in bytes.
pub memory_load_bytes: Annotated<u64>,

/// Array of GC pause durations in milliseconds.
pub pause_durations: Annotated<Array<u64>>,

/// Percentage of time spent in GC pauses.
pub pause_time_percentage: Annotated<f64>,

/// Number of pinned objects in memory.
pub pinned_objects_count: Annotated<u64>,

/// Bytes promoted to higher generation.
pub promoted_bytes: Annotated<u64>,

/// Total memory allocated since start in bytes.
pub total_allocated_bytes: Annotated<u64>,

/// Total memory available to the application in bytes.
pub total_available_memory_bytes: Annotated<u64>,

/// Total committed virtual memory in bytes.
pub total_committed_bytes: Annotated<u64>,

/// Additional arbitrary fields for forwards compatibility.
#[metastructure(additional_properties, retain = true, pii = "maybe")]
pub other: Object<Value>,
}

impl super::DefaultContext for MemoryInfoContext {
fn default_key() -> &'static str {
"memory_info"
}

fn from_context(context: super::Context) -> Option<Self> {
match context {
super::Context::MemoryInfo(c) => Some(*c),
_ => None,
}
}

fn cast(context: &super::Context) -> Option<&Self> {
match context {
super::Context::MemoryInfo(c) => Some(c),
_ => None,
}
}

fn cast_mut(context: &mut super::Context) -> Option<&mut Self> {
match context {
super::Context::MemoryInfo(c) => Some(c),
_ => None,
}
}

fn into_context(self) -> super::Context {
super::Context::MemoryInfo(Box::new(self))
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::protocol::Context;

#[test]
fn test_memory_info_context_roundtrip() {
let json = r#"{
"allocated_bytes": 1048576,
"compacted": true,
"concurrent": true,
"finalization_pending_count": 42,
"fragmented_bytes": 2048,
"heap_size_bytes": 3145728,
"high_memory_load_threshold_bytes": 8388608,
"index": 2,
"memory_load_bytes": 5242880,
"pause_durations": [
10,
5,
3
],
"pause_time_percentage": 25.5,
"pinned_objects_count": 150,
"promoted_bytes": 524288,
"total_allocated_bytes": 9437184,
"total_available_memory_bytes": 16777216,
"total_committed_bytes": 12582912,
"other": "value",
"type": "memory_info"
}"#;
let context = Annotated::new(Context::MemoryInfo(Box::new(MemoryInfoContext {
allocated_bytes: Annotated::new(1048576),
total_allocated_bytes: Annotated::new(9437184),
heap_size_bytes: Annotated::new(3145728),
pinned_objects_count: Annotated::new(150),
pause_time_percentage: Annotated::new(25.5),
compacted: Annotated::new(true),
concurrent: Annotated::new(true),
pause_durations: Annotated::new(vec![
Annotated::new(10),
Annotated::new(5),
Annotated::new(3),
]),
finalization_pending_count: Annotated::new(42),
fragmented_bytes: Annotated::new(2048),
high_memory_load_threshold_bytes: Annotated::new(8388608),
index: Annotated::new(2),
memory_load_bytes: Annotated::new(5242880),
promoted_bytes: Annotated::new(524288),
total_available_memory_bytes: Annotated::new(16777216),
total_committed_bytes: Annotated::new(12582912),
other: {
let mut map = Object::new();
map.insert(
"other".to_owned(),
Annotated::new(Value::String("value".to_owned())),
);
map
},
})));

assert_eq!(context, Annotated::from_json(json).unwrap());
assert_eq!(json, context.to_json_pretty().unwrap());
}

#[test]
fn test_memory_info_context_minimal() {
let json = r#"{
"type": "memory_info"
}"#;
let context = Annotated::new(Context::MemoryInfo(Box::default()));

assert_eq!(context, Annotated::from_json(json).unwrap());
assert_eq!(json, context.to_json_pretty().unwrap());
}
}
5 changes: 5 additions & 0 deletions relay-event-schema/src/protocol/contexts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod cloud_resource;
mod device;
mod flags;
mod gpu;
mod memory_info;
mod monitor;
mod nel;
mod os;
Expand All @@ -26,6 +27,7 @@ pub use chromium_stability_report::*;
pub use cloud_resource::*;
pub use device::*;
pub use gpu::*;
pub use memory_info::*;
pub use monitor::*;
pub use nel::*;
pub use os::*;
Expand Down Expand Up @@ -83,6 +85,9 @@ pub enum Context {
/// Information related to User Report V2. TODO:(jferg): rename to UserFeedbackContext
#[metastructure(tag = "feedback")]
UserReportV2(Box<UserReportV2Context>),
/// Information related to Memory usage and garbage collection metrics.
#[metastructure(tag = "memory_info")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried it without this, I think that is not necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I did but the tests were not passing because of the initial type

MemoryInfo(Box<MemoryInfoContext>),
/// Information related to Monitors feature.
Monitor(Box<MonitorContext>),
/// Auxilliary information for reprocessing.
Expand Down
Loading