settings/inspect/
config_logger.rs1use crate::{clock, config};
6use fuchsia_inspect::{self as inspect, Node, NumericProperty, Property};
7use fuchsia_inspect_derive::Inspect;
8use settings_inspect_utils::managed_inspect_map::ManagedInspectMap;
9
10const CONFIG_INSPECT_NODE_NAME: &str = "config_loads";
11
12pub struct InspectConfigLogger {
13 config_load_values: ManagedInspectMap<ConfigInspectInfo>,
15}
16
17#[derive(Default, Inspect)]
22struct ConfigInspectInfo {
23 inspect_node: inspect::Node,
25
26 timestamp: inspect::StringProperty,
28
29 count: inspect::UintProperty,
31
32 value: inspect::StringProperty,
34
35 result_counts: ManagedInspectMap<inspect::UintProperty>,
37}
38
39impl InspectConfigLogger {
40 pub fn new(node: &Node) -> Self {
43 let config_inspect_node = node.create_child(CONFIG_INSPECT_NODE_NAME);
44 Self {
45 config_load_values: ManagedInspectMap::<ConfigInspectInfo>::with_node(
46 config_inspect_node,
47 ),
48 }
49 }
50
51 pub fn write_config_load_to_inspect(
52 &mut self,
53 path: String,
54 config_load_info: config::base::ConfigLoadInfo,
55 ) {
56 let timestamp = clock::inspect_format_now();
57 let config::base::ConfigLoadInfo { status, contents } = config_load_info;
58 let status_clone = status.clone();
59
60 let config_inspect_info =
61 self.config_load_values.get_or_insert_with(path, ConfigInspectInfo::default);
62
63 config_inspect_info.timestamp.set(×tamp);
64 config_inspect_info
65 .value
66 .set(&format!("{:#?}", config::base::ConfigLoadInfo { status, contents }));
67 let _ = config_inspect_info.count.add(1u64);
68 let _ = config_inspect_info
69 .result_counts
70 .get_or_insert_with(status_clone.into(), inspect::UintProperty::default)
71 .add(1u64);
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use crate::config::base::ConfigLoadStatus;
79 use diagnostics_assertions::assert_data_tree;
80 use fuchsia_inspect::component;
81 use zx::MonotonicInstant;
82
83 #[fuchsia::test]
84 fn test_listener_logger() {
85 clock::mock::set(MonotonicInstant::from_nanos(0));
87
88 let inspector = component::inspector();
89 let mut logger = InspectConfigLogger::new(inspector.root());
90
91 logger.write_config_load_to_inspect(
92 "test_path".to_string(),
93 config::base::ConfigLoadInfo {
94 status: ConfigLoadStatus::Success,
95 contents: Some("test".to_string()),
96 },
97 );
98
99 assert_data_tree!(inspector, root: {
100 config_loads: {
101 "test_path": {
102 "count": 1u64,
103 "result_counts": {
104 "Success": 1u64,
105 },
106 "timestamp": "0.000000000",
107 "value": "ConfigLoadInfo {\n status: Success,\n contents: Some(\n \"test\",\n ),\n}"
108 }
109 }
110 });
111 }
112
113 #[fuchsia::test]
114 fn test_response_counts() {
115 clock::mock::set(MonotonicInstant::from_nanos(0));
117
118 let inspector = component::inspector();
119 let mut logger = InspectConfigLogger::new(inspector.root());
120
121 logger.write_config_load_to_inspect(
122 "test_path".to_string(),
123 config::base::ConfigLoadInfo {
124 status: ConfigLoadStatus::Success,
125 contents: Some("test".to_string()),
126 },
127 );
128 logger.write_config_load_to_inspect(
129 "test_path".to_string(),
130 config::base::ConfigLoadInfo {
131 status: ConfigLoadStatus::ParseFailure("Fake parse failure".to_string()),
132 contents: Some("test".to_string()),
133 },
134 );
135 logger.write_config_load_to_inspect(
136 "test_path".to_string(),
137 config::base::ConfigLoadInfo {
138 status: ConfigLoadStatus::ParseFailure("Fake parse failure".to_string()),
139 contents: Some("test".to_string()),
140 },
141 );
142 logger.write_config_load_to_inspect(
143 "test_path".to_string(),
144 config::base::ConfigLoadInfo {
145 status: ConfigLoadStatus::UsingDefaults("default".to_string()),
146 contents: Some("test".to_string()),
147 },
148 );
149
150 assert_data_tree!(inspector, root: {
151 config_loads: {
152 "test_path": {
153 "count": 4u64,
154 "result_counts": {
155 "Success": 1u64,
156 "ParseFailure": 2u64,
157 "UsingDefaults": 1u64,
158 },
159 "timestamp": "0.000000000",
160 "value": "ConfigLoadInfo {\n status: UsingDefaults(\n \"default\",\n ),\n contents: Some(\n \"test\",\n ),\n}"
161 }
162 }
163 });
164 }
165}