/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
usesuper::glean_metrics; use anyhow::Context; use glean::private::{
BooleanMetric, DatetimeMetric, ObjectMetric, QuantityMetric, StringListMetric, StringMetric,
TimespanMetric,
}; use glean::TestGetValue;
time::OffsetDateTime::new_in_offset(
time::Date::from_calendar_date(year, (month as u8).try_into().unwrap(), day as u8)
.unwrap(),
time::Time::from_hms_nano(hour as u8, minute as u8, second as u8, nanosecond).unwrap(),
time::UtcOffset::from_whole_seconds(offset_seconds).unwrap(),
)
.to_string()
.into()
}
}
fn convert_to_crash_windows_file_dialog_error_code(
metric: &StringMetric,
value: &str,
) -> anyhow::Result<()> {
metric.set(value.to_owned()); // Just assume it is an integer as expected
Ok(())
}
fn convert_to_crash_async_shutdown_timeout(
metric: &ObjectMetric<glean_metrics::crash::AsyncShutdownTimeoutObject>,
value: &str,
) -> anyhow::Result<()> { // The JSON value is stored as a string, so we need to deserialize it. letmut value: serde_json::Map<String, serde_json::Value> = serde_json::from_str(value)?;
metric.set(glean_metrics::crash::AsyncShutdownTimeoutObject {
broken_add_blockers: { iflet Some(broken_add_blockers) = value.remove("brokenAddBlockers") { let broken_add_blockers = broken_add_blockers
.as_array()
.context("expected array for brokenAddBlockers")?; letmut ret = Vec::with_capacity(broken_add_blockers.len()); for entry in broken_add_blockers {
ret.push(
entry
.as_str()
.context("expected brokenAddBlockers entry to be a string")?
.to_owned(),
);
}
ret
} else {
Default::default()
}
},
conditions: { iflet Some(conditions) = value.remove("conditions") {
Some(iflet Some(s) = conditions.as_str() {
s.to_owned()
} else {
serde_json::to_string(&conditions).context("failed to serialize conditions")?
})
} else {
None
}
},
phase: { iflet Some(phase) = value.remove("phase") {
Some(
phase
.as_str()
.context("expected phase to be a string")?
.to_owned(),
)
} else {
None
}
},
});
Ok(())
}
fn convert_to_crash_quota_manager_shutdown_timeout(
metric: &ObjectMetric<glean_metrics::crash::QuotaManagerShutdownTimeoutObject>,
value: &str,
) -> anyhow::Result<()> { // The Glean metric is an array of the lines.
metric.set(value.lines().map(|s| s.to_owned()).collect::<Vec<_>>());
Ok(())
}
fn convert_to_crash_stack_traces(
metric: &ObjectMetric<glean_metrics::crash::StackTracesObject>,
value: &str,
) -> anyhow::Result<()> { // The JSON value is stored as a string, so we need to deserialize it. let value: serde_json::Value = serde_json::from_str(value)?; let error = value["error"].as_str().map(|s| s.to_owned()); let crash_type = value["crash_type"].as_str().map(|s| s.to_owned()); let crash_address = value["crash_address"].as_str().map(|s| s.to_owned()); let crash_thread = value["crash_thread"].as_i64(); let main_module = value["main_module"].as_i64(); let modules = value["modules"]
.as_array()
.map(|modules| {
modules
.iter()
.map(|m| glean_metrics::crash::StackTracesObjectModulesItem {
base_address: m["base_address"].as_str().map(|s| s.to_owned()),
end_address: m["end_address"].as_str().map(|s| s.to_owned()),
code_id: m["code_id"].as_str().map(|s| s.to_owned()),
debug_file: m["debug_file"].as_str().map(|s| s.to_owned()),
debug_id: m["debug_id"].as_str().map(|s| s.to_owned()),
filename: m["filename"].as_str().map(|s| s.to_owned()),
version: m["version"].as_str().map(|s| s.to_owned()),
})
.collect::<Vec<_>>()
})
.unwrap_or_default(); let threads = value["threads"]
.as_array()
.map(|threads| {
threads
.iter()
.map(|t| glean_metrics::crash::StackTracesObjectThreadsItem {
frames: t["frames"]
.as_array()
.map(|frames| {
frames
.iter()
.map(|f| {
glean_metrics::crash::StackTracesObjectThreadsItemFramesItem {
module_index: f["module_index"].as_i64(),
ip: f["ip"].as_str().map(|s| s.to_owned()),
trust: f["trust"].as_str().map(|s| s.to_owned()),
}
})
.collect::<Vec<_>>()
})
.unwrap_or_default(),
})
.collect::<Vec<_>>()
})
.unwrap_or_default();
metric.set(glean_metrics::crash::StackTracesObject {
error,
crash_type,
crash_address,
crash_thread,
main_module,
modules,
threads,
});
Ok(())
}
// The format of the JSON value is defined in getStacktraceAsJsonString // (mobile/android/android-components/components/support/base/src/main/java/mozilla/components/support/base/ext/Throwable.kt). fn convert_to_crash_java_exception(
metric: &ObjectMetric<glean_metrics::crash::JavaExceptionObject>,
value: &str,
) -> anyhow::Result<()> { // The JSON value is stored as a string, so we need to deserialize it. let value: serde_json::Map<String, serde_json::Value> = serde_json::from_str(value)?; let throwables = value["exception"]["values"]
.as_array()
.context("expected throwables array")?
.iter() // The format stores throwables in reverse order (deepest cause first), but we define the // glean format to be by top cause first.
.rev()
.map(|throwable| &throwable["stacktrace"])
.map(
|throwable| glean_metrics::crash::JavaExceptionObjectThrowablesItem {
message: throwable["value"].as_str().map(ToOwned::to_owned),
type_name: throwable["module"]
.as_str()
.zip(throwable["type"].as_str())
.map(|(m, t)| format!("{m}.{t}")),
stack: throwable["frames"]
.as_array()
.map(|frames| {
frames
.iter()
.map(|frame| {
glean_metrics::crash::JavaExceptionObjectThrowablesItemStackItem {
class_name: frame["module"].as_str().map(ToOwned::to_owned),
method_name: frame["function"].as_str().map(ToOwned::to_owned),
is_native: frame["in_app"].as_bool().map(|b| !b),
line: frame["lineno"].as_i64(),
file: frame["filename"].as_str().map(ToOwned::to_owned),
}
})
.collect()
})
.unwrap_or_default(),
},
)
.collect();
fn glean_datetime(datetime: time::OffsetDateTime) -> glean::Datetime {
glean::Datetime {
year: datetime.year(),
month: datetime.month() as _,
day: datetime.day() as _,
hour: datetime.hour() as _,
minute: datetime.minute() as _,
second: datetime.second() as _,
nanosecond: datetime.nanosecond(),
offset_seconds: datetime.offset().whole_seconds(),
}
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.9Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.