Skip to content

Commit

Permalink
feat(profiling): Add optional js profile to Android profiles events (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
krystofwoldrich committed Nov 29, 2023
1 parent 6953ee0 commit 2f66866
Show file tree
Hide file tree
Showing 6 changed files with 22,254 additions and 156 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Partition and split metric buckets just before sending. Log outcomes for metrics. ([#2682](https://github.com/getsentry/relay/pull/2682))
- Return global config ready status to downstream relays. ([#2765](https://github.com/getsentry/relay/pull/2765))
- Add Mixed JS/Android Profiles events processing. ([#2706](https://github.com/getsentry/relay/pull/2706))

**Internal**:

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions relay-profiling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ publish = false
android_trace_log = { version = "0.3.0", features = ["serde"] }
chrono = { workspace = true }
data-encoding = "2.3.3"
itertools = { workspace = true }
relay-base-schema = { path = "../relay-base-schema" }
relay-event-schema = { path = "../relay-event-schema" }
relay-log = { path = "../relay-log" }
Expand Down
40 changes: 34 additions & 6 deletions relay-profiling/src/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use relay_event_schema::protocol::EventId;
use serde::{Deserialize, Serialize};

use crate::measurements::Measurement;
use crate::native_debug_image::NativeDebugImage;
use crate::sample::SampleProfile;
use crate::transaction_metadata::TransactionMetadata;
use crate::utils::{deserialize_number_from_string, is_zero};
use crate::{ProfileError, MAX_PROFILE_DURATION};
Expand Down Expand Up @@ -78,21 +80,32 @@ pub struct ProfileMetadata {

#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
transaction_tags: BTreeMap<String, String>,

#[serde(skip_serializing_if = "Option::is_none")]
debug_meta: Option<DebugMeta>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
struct AndroidProfile {
struct AndroidProfilingEvent {
#[serde(flatten)]
metadata: ProfileMetadata,

#[serde(default, skip_serializing)]
sampled_profile: String,

#[serde(default = "AndroidProfile::default")]
#[serde(default, skip_serializing_if = "Option::is_none")]
js_profile: Option<SampleProfile>,

#[serde(default = "AndroidProfilingEvent::default")]
profile: AndroidTraceLog,
}

impl AndroidProfile {
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
struct DebugMeta {
images: Vec<NativeDebugImage>,
}

impl AndroidProfilingEvent {
fn default() -> AndroidTraceLog {
AndroidTraceLog {
data_file_overflow: Default::default(),
Expand Down Expand Up @@ -127,9 +140,9 @@ impl AndroidProfile {
}
}

fn parse_profile(payload: &[u8]) -> Result<AndroidProfile, ProfileError> {
fn parse_profile(payload: &[u8]) -> Result<AndroidProfilingEvent, ProfileError> {
let d = &mut serde_json::Deserializer::from_slice(payload);
let mut profile: AndroidProfile =
let mut profile: AndroidProfilingEvent =
serde_path_to_error::deserialize(d).map_err(ProfileError::InvalidJson)?;

let transaction_opt = profile.metadata.transactions.drain(..).next();
Expand Down Expand Up @@ -158,6 +171,10 @@ fn parse_profile(payload: &[u8]) -> Result<AndroidProfile, ProfileError> {
return Err(ProfileError::NoTransactionAssociated);
}

if let Some(ref mut js_profile) = profile.js_profile {
js_profile.normalize(profile.metadata.platform.as_str(), "")?;
}

if !profile.sampled_profile.is_empty() {
profile.parse()?;
}
Expand Down Expand Up @@ -221,6 +238,17 @@ mod tests {
);
}

#[test]
fn test_roundtrip_react_native() {
let payload = include_bytes!("../tests/fixtures/profiles/android/roundtrip.rn.json");
let profile = parse_profile(payload);
assert!(profile.is_ok());
let data = serde_json::to_vec(&profile.unwrap());
assert!(
parse_android_profile(&(data.unwrap())[..], BTreeMap::new(), BTreeMap::new()).is_ok()
);
}

#[test]
fn test_no_transaction() {
let payload = include_bytes!("../tests/fixtures/profiles/android/no_transaction.json");
Expand Down Expand Up @@ -274,7 +302,7 @@ mod tests {

let payload = profile_json.unwrap();
let d = &mut serde_json::Deserializer::from_slice(&payload[..]);
let output: AndroidProfile = serde_path_to_error::deserialize(d)
let output: AndroidProfilingEvent = serde_path_to_error::deserialize(d)
.map_err(ProfileError::InvalidJson)
.unwrap();
assert_eq!(output.metadata.release, "some-random-release".to_string());
Expand Down
Loading

0 comments on commit 2f66866

Please sign in to comment.