settings/inspect/
config_logger.rsuse crate::{clock, config};
use fuchsia_inspect::{self as inspect, Node, NumericProperty, Property};
use fuchsia_inspect_derive::Inspect;
use settings_inspect_utils::managed_inspect_map::ManagedInspectMap;
const CONFIG_INSPECT_NODE_NAME: &str = "config_loads";
pub struct InspectConfigLogger {
config_load_values: ManagedInspectMap<ConfigInspectInfo>,
}
#[derive(Default, Inspect)]
struct ConfigInspectInfo {
inspect_node: inspect::Node,
timestamp: inspect::StringProperty,
count: inspect::UintProperty,
value: inspect::StringProperty,
result_counts: ManagedInspectMap<inspect::UintProperty>,
}
impl InspectConfigLogger {
pub fn new(node: &Node) -> Self {
let config_inspect_node = node.create_child(CONFIG_INSPECT_NODE_NAME);
Self {
config_load_values: ManagedInspectMap::<ConfigInspectInfo>::with_node(
config_inspect_node,
),
}
}
pub fn write_config_load_to_inspect(
&mut self,
path: String,
config_load_info: config::base::ConfigLoadInfo,
) {
let timestamp = clock::inspect_format_now();
let config::base::ConfigLoadInfo { status, contents } = config_load_info;
let status_clone = status.clone();
let config_inspect_info =
self.config_load_values.get_or_insert_with(path, ConfigInspectInfo::default);
config_inspect_info.timestamp.set(×tamp);
config_inspect_info
.value
.set(&format!("{:#?}", config::base::ConfigLoadInfo { status, contents }));
let _ = config_inspect_info.count.add(1u64);
let _ = config_inspect_info
.result_counts
.get_or_insert_with(status_clone.into(), inspect::UintProperty::default)
.add(1u64);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::base::ConfigLoadStatus;
use diagnostics_assertions::assert_data_tree;
use fuchsia_inspect::component;
use zx::MonotonicInstant;
#[fuchsia::test]
fn test_listener_logger() {
clock::mock::set(MonotonicInstant::from_nanos(0));
let inspector = component::inspector();
let mut logger = InspectConfigLogger::new(inspector.root());
logger.write_config_load_to_inspect(
"test_path".to_string(),
config::base::ConfigLoadInfo {
status: ConfigLoadStatus::Success,
contents: Some("test".to_string()),
},
);
assert_data_tree!(inspector, root: {
config_loads: {
"test_path": {
"count": 1u64,
"result_counts": {
"Success": 1u64,
},
"timestamp": "0.000000000",
"value": "ConfigLoadInfo {\n status: Success,\n contents: Some(\n \"test\",\n ),\n}"
}
}
});
}
#[fuchsia::test]
fn test_response_counts() {
clock::mock::set(MonotonicInstant::from_nanos(0));
let inspector = component::inspector();
let mut logger = InspectConfigLogger::new(inspector.root());
logger.write_config_load_to_inspect(
"test_path".to_string(),
config::base::ConfigLoadInfo {
status: ConfigLoadStatus::Success,
contents: Some("test".to_string()),
},
);
logger.write_config_load_to_inspect(
"test_path".to_string(),
config::base::ConfigLoadInfo {
status: ConfigLoadStatus::ParseFailure("Fake parse failure".to_string()),
contents: Some("test".to_string()),
},
);
logger.write_config_load_to_inspect(
"test_path".to_string(),
config::base::ConfigLoadInfo {
status: ConfigLoadStatus::ParseFailure("Fake parse failure".to_string()),
contents: Some("test".to_string()),
},
);
logger.write_config_load_to_inspect(
"test_path".to_string(),
config::base::ConfigLoadInfo {
status: ConfigLoadStatus::UsingDefaults("default".to_string()),
contents: Some("test".to_string()),
},
);
assert_data_tree!(inspector, root: {
config_loads: {
"test_path": {
"count": 4u64,
"result_counts": {
"Success": 1u64,
"ParseFailure": 2u64,
"UsingDefaults": 1u64,
},
"timestamp": "0.000000000",
"value": "ConfigLoadInfo {\n status: UsingDefaults(\n \"default\",\n ),\n contents: Some(\n \"test\",\n ),\n}"
}
}
});
}
}