diagnostics_data/
logs_legacy.rs1use crate::{Data, Logs};
6#[cfg(fuchsia_api_level_at_least = "PLATFORM")]
7use fidl_fuchsia_logger::LogMessage;
8use std::collections::HashSet;
9use std::fmt::Write;
10
11#[cfg(fuchsia_api_level_at_least = "PLATFORM")]
13impl From<&Data<Logs>> for LogMessage {
14 fn from(data: &Data<Logs>) -> LogMessage {
15 let mut msg = data.msg().unwrap_or("").to_string();
16
17 if let Some(payload) = data.payload_keys() {
18 for property in payload.properties.iter() {
19 write!(&mut msg, " {property}").expect("allocations have to fail for this to fail");
20 }
21 }
22 let file = data.metadata.file.as_ref();
23 let line = data.metadata.line.as_ref();
24 if let (Some(file), Some(line)) = (file, line) {
25 msg = format!("[{}({})] {}", file, line, msg);
26 }
27
28 let tags = match &data.metadata.tags {
29 None => vec![data.component_name().to_string()],
30 Some(tags) if tags.is_empty() => vec![data.component_name().to_string()],
31 Some(tags) => tags.clone(),
32 };
33
34 LogMessage {
35 pid: data.pid().unwrap_or(zx::sys::ZX_KOID_INVALID),
36 tid: data.tid().unwrap_or(zx::sys::ZX_KOID_INVALID),
37 time: data.metadata.timestamp,
38 severity: data.metadata.raw_severity() as i32,
39 dropped_logs: data.dropped_logs().unwrap_or(0) as _,
40 tags,
41 msg,
42 }
43 }
44}
45
46pub fn format_log_message(data: &Data<Logs>) -> String {
50 let mut msg = data.msg().unwrap_or("").to_string();
51
52 if let Some(payload) = data.payload_keys() {
53 for property in payload.properties.iter() {
54 write!(&mut msg, " {property}").expect("allocations have to fail for this to fail");
55 }
56 }
57 let file = data.metadata.file.as_ref();
58 let line = data.metadata.line.as_ref();
59 if let (Some(file), Some(line)) = (file, line) {
60 msg = format!("[{}({})] {}", file, line, msg);
61 }
62 msg
63}
64
65fn include_tag_prefix(tag: &str, tags: &HashSet<String>) -> bool {
68 if tag.contains("::") {
69 tags.iter().any(|t| {
70 tag.len() > t.len() + 2 && &tag[t.len()..t.len() + 2] == "::" && tag.starts_with(t)
71 })
72 } else {
73 false
74 }
75}
76
77pub fn filter_by_tags(log_message: &Data<Logs>, include_tags: &HashSet<String>) -> bool {
80 let reject_tags = if include_tags.is_empty() {
81 false
82 } else if log_message.tags().map(|t| t.is_empty()).unwrap_or(true) {
83 !include_tags.contains(log_message.component_name().as_ref())
84 } else {
85 !log_message
86 .tags()
87 .map(|tags| {
88 tags.iter()
89 .any(|tag| include_tags.contains(tag) || include_tag_prefix(tag, include_tags))
90 })
91 .unwrap_or(false)
92 };
93 reject_tags
94}
95
96#[cfg(fuchsia_api_level_at_least = "PLATFORM")]
98impl From<Data<Logs>> for LogMessage {
99 fn from(data: Data<Logs>) -> LogMessage {
100 LogMessage {
101 pid: data.pid().unwrap_or(zx::sys::ZX_KOID_INVALID),
102 tid: data.tid().unwrap_or(zx::sys::ZX_KOID_INVALID),
103 time: data.metadata.timestamp,
104 severity: data.metadata.raw_severity() as i32,
105 dropped_logs: data.dropped_logs().unwrap_or(0) as _,
106 msg: format_log_message(&data),
107 tags: match data.metadata.tags {
108 Some(tags) => tags,
109 None => vec![data.component_name().to_string()],
110 },
111 }
112 }
113}
114
115#[cfg(test)]
116mod test {
117 use super::*;
118 use crate::{BuilderArgs, LogsDataBuilder, Severity, Timestamp};
119 use fidl_fuchsia_diagnostics as fdiagnostics;
120
121 const TEST_URL: &str = "fuchsia-pkg://test";
122 const TEST_MONIKER: &str = "fake-test/moniker";
123
124 macro_rules! severity_roundtrip_test {
125 ($raw:expr, $expected:expr) => {
126 let severity = Severity::from(u8::from($raw));
127 let msg = LogsDataBuilder::new(BuilderArgs {
128 timestamp: Timestamp::from_nanos(0),
129 component_url: Some(TEST_URL.into()),
130 moniker: moniker::ExtendedMoniker::parse_str(TEST_MONIKER).unwrap(),
131 severity,
132 })
133 .build();
134
135 let legacy_msg: LogMessage = (&msg).into();
136 assert_eq!(
137 legacy_msg.severity,
138 i32::from($expected),
139 "failed to round trip severity for {:?} (raw {}), intermediates: {:#?}\n{:#?}",
140 severity,
141 $raw,
142 msg,
143 legacy_msg
144 );
145 };
146 }
147
148 #[fuchsia::test]
149 fn raw_severity_roundtrip_trace() {
150 severity_roundtrip_test!(
151 fdiagnostics::Severity::Trace.into_primitive() - 1,
152 fdiagnostics::Severity::Trace.into_primitive()
153 );
154 severity_roundtrip_test!(
155 fdiagnostics::Severity::Trace.into_primitive(),
156 fdiagnostics::Severity::Trace.into_primitive()
157 );
158 severity_roundtrip_test!(
159 fdiagnostics::Severity::Trace.into_primitive() + 1,
160 fdiagnostics::Severity::Debug.into_primitive()
161 );
162 }
163
164 #[fuchsia::test]
165 fn severity_roundtrip_debug() {
166 severity_roundtrip_test!(
167 fdiagnostics::Severity::Debug.into_primitive() - 1,
168 fdiagnostics::Severity::Debug.into_primitive()
169 );
170 severity_roundtrip_test!(
171 fdiagnostics::Severity::Debug.into_primitive(),
172 fdiagnostics::Severity::Debug.into_primitive()
173 );
174 severity_roundtrip_test!(
175 fdiagnostics::Severity::Debug.into_primitive() + 1,
176 fdiagnostics::Severity::Info.into_primitive()
177 );
178 }
179
180 #[fuchsia::test]
181 fn severity_roundtrip_info() {
182 severity_roundtrip_test!(
183 fdiagnostics::Severity::Info.into_primitive() - 1,
184 fdiagnostics::Severity::Info.into_primitive()
185 );
186 severity_roundtrip_test!(
187 fdiagnostics::Severity::Info.into_primitive(),
188 fdiagnostics::Severity::Info.into_primitive()
189 );
190 severity_roundtrip_test!(
191 fdiagnostics::Severity::Info.into_primitive() + 1,
192 fdiagnostics::Severity::Warn.into_primitive()
193 );
194 }
195
196 #[fuchsia::test]
197 fn severity_roundtrip_warn() {
198 severity_roundtrip_test!(
199 fdiagnostics::Severity::Warn.into_primitive() - 1,
200 fdiagnostics::Severity::Warn.into_primitive()
201 );
202 severity_roundtrip_test!(
203 fdiagnostics::Severity::Warn.into_primitive(),
204 fdiagnostics::Severity::Warn.into_primitive()
205 );
206 severity_roundtrip_test!(
207 fdiagnostics::Severity::Warn.into_primitive() + 1,
208 fdiagnostics::Severity::Error.into_primitive()
209 );
210 }
211
212 #[fuchsia::test]
213 fn severity_roundtrip_error() {
214 severity_roundtrip_test!(
215 fdiagnostics::Severity::Error.into_primitive() - 1,
216 fdiagnostics::Severity::Error.into_primitive()
217 );
218 severity_roundtrip_test!(
219 fdiagnostics::Severity::Error.into_primitive(),
220 fdiagnostics::Severity::Error.into_primitive()
221 );
222 severity_roundtrip_test!(
223 fdiagnostics::Severity::Error.into_primitive() + 1,
224 fdiagnostics::Severity::Fatal.into_primitive()
225 );
226 }
227
228 #[fuchsia::test]
229 fn severity_roundtrip_fatal() {
230 severity_roundtrip_test!(
231 fdiagnostics::Severity::Fatal.into_primitive() - 1,
232 fdiagnostics::Severity::Fatal.into_primitive()
233 );
234 severity_roundtrip_test!(
235 fdiagnostics::Severity::Fatal.into_primitive(),
236 fdiagnostics::Severity::Fatal.into_primitive()
237 );
238 severity_roundtrip_test!(
239 fdiagnostics::Severity::Fatal.into_primitive() + 1,
240 fdiagnostics::Severity::Fatal.into_primitive()
241 );
242 }
243}