cadmus_core/view/settings_editor/kinds/
telemetry.rs1use super::{SettingData, SettingIdentity, SettingKind, ToggleSettings, WidgetKind};
4use crate::fl;
5use crate::settings::Settings;
6use crate::view::{Bus, EntryId, EntryKind, Event, ToggleEvent};
7
8#[cfg(feature = "otel")]
9use super::InputSettingKind;
10#[cfg(feature = "otel")]
11use crate::view::ViewId;
12use std::str::FromStr;
13
14pub struct LoggingEnabled;
16
17impl SettingKind for LoggingEnabled {
18 fn identity(&self) -> SettingIdentity {
19 SettingIdentity::LoggingEnabled
20 }
21
22 fn label(&self, _settings: &Settings) -> String {
23 fl!("settings-telemetry-enable-logging")
24 }
25
26 fn fetch(&self, settings: &Settings) -> SettingData {
27 SettingData {
28 value: settings.logging.enabled.to_string(),
29 widget: WidgetKind::Toggle {
30 left_label: fl!("settings-general-toggle-on"),
31 right_label: fl!("settings-general-toggle-off"),
32 enabled: settings.logging.enabled,
33 tap_event: Event::Toggle(ToggleEvent::Setting(ToggleSettings::LoggingEnabled)),
34 },
35 }
36 }
37
38 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
39 if let Event::Toggle(ToggleEvent::Setting(ToggleSettings::LoggingEnabled)) = evt {
40 settings.logging.enabled = !settings.logging.enabled;
41 return Some(settings.logging.enabled.to_string());
42 }
43 None
44 }
45}
46
47pub struct LogLevel;
49
50impl LogLevel {
51 fn level_to_i18n(level: &tracing::Level) -> String {
52 match *level {
53 tracing::Level::TRACE => fl!("settings-log-level-trace"),
54 tracing::Level::DEBUG => fl!("settings-log-level-debug"),
55 tracing::Level::INFO => fl!("settings-log-level-info"),
56 tracing::Level::WARN => fl!("settings-log-level-warn"),
57 tracing::Level::ERROR => fl!("settings-log-level-error"),
58 }
59 }
60}
61
62impl SettingKind for LogLevel {
63 fn identity(&self) -> SettingIdentity {
64 SettingIdentity::LogLevel
65 }
66
67 fn label(&self, _settings: &Settings) -> String {
68 fl!("settings-telemetry-log-level")
69 }
70
71 fn fetch(&self, settings: &Settings) -> SettingData {
72 let current = tracing::Level::from_str(settings.logging.level.as_str())
73 .unwrap_or(tracing::Level::INFO);
74
75 let entries = vec![
76 EntryKind::RadioButton(
77 Self::level_to_i18n(&tracing::Level::TRACE),
78 EntryId::SetLogLevel(tracing::Level::TRACE),
79 current == tracing::Level::TRACE,
80 ),
81 EntryKind::RadioButton(
82 Self::level_to_i18n(&tracing::Level::DEBUG),
83 EntryId::SetLogLevel(tracing::Level::DEBUG),
84 current == tracing::Level::DEBUG,
85 ),
86 EntryKind::RadioButton(
87 Self::level_to_i18n(&tracing::Level::INFO),
88 EntryId::SetLogLevel(tracing::Level::INFO),
89 current == tracing::Level::INFO,
90 ),
91 EntryKind::RadioButton(
92 Self::level_to_i18n(&tracing::Level::WARN),
93 EntryId::SetLogLevel(tracing::Level::WARN),
94 current == tracing::Level::WARN,
95 ),
96 EntryKind::RadioButton(
97 Self::level_to_i18n(&tracing::Level::ERROR),
98 EntryId::SetLogLevel(tracing::Level::ERROR),
99 current == tracing::Level::ERROR,
100 ),
101 ];
102
103 SettingData {
104 value: Self::level_to_i18n(¤t),
105 widget: WidgetKind::SubMenu(entries),
106 }
107 }
108
109 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
110 if let Event::Select(EntryId::SetLogLevel(ref level)) = evt {
111 settings.logging.level = level.to_string();
112 return Some(Self::level_to_i18n(level));
113 }
114 None
115 }
116}
117
118#[cfg(feature = "otel")]
120pub struct OtlpEndpoint;
121
122#[cfg(feature = "otel")]
123impl SettingKind for OtlpEndpoint {
124 fn identity(&self) -> SettingIdentity {
125 SettingIdentity::OtlpEndpoint
126 }
127
128 fn label(&self, _settings: &Settings) -> String {
129 fl!("settings-telemetry-otlp-endpoint")
130 }
131
132 fn fetch(&self, settings: &Settings) -> SettingData {
133 let value = settings
134 .logging
135 .otlp_endpoint
136 .clone()
137 .unwrap_or_else(|| fl!("settings-general-not-set"));
138
139 SettingData {
140 value,
141 widget: WidgetKind::ActionLabel(Event::Select(EntryId::EditOtlpEndpoint)),
142 }
143 }
144
145 fn as_input_kind(&self) -> Option<&dyn InputSettingKind> {
146 Some(self)
147 }
148}
149
150#[cfg(feature = "otel")]
151impl InputSettingKind for OtlpEndpoint {
152 fn submit_view_id(&self) -> ViewId {
153 ViewId::OtlpEndpointInput
154 }
155
156 fn open_entry_id(&self) -> EntryId {
157 EntryId::EditOtlpEndpoint
158 }
159
160 fn input_label(&self) -> String {
161 fl!("settings-telemetry-otlp-endpoint")
162 }
163
164 fn input_max_chars(&self) -> usize {
165 50
166 }
167
168 fn current_text(&self, settings: &Settings) -> String {
169 settings.logging.otlp_endpoint.clone().unwrap_or_default()
170 }
171
172 fn apply_text(&self, text: &str, settings: &mut Settings) -> String {
173 let trimmed = text.trim();
174 settings.logging.otlp_endpoint = if trimmed.is_empty() {
175 None
176 } else {
177 Some(trimmed.to_string())
178 };
179 settings
180 .logging
181 .otlp_endpoint
182 .clone()
183 .unwrap_or_else(|| fl!("settings-general-not-set"))
184 }
185}
186
187#[cfg(all(feature = "test", feature = "kobo"))]
189pub struct EnableKernLog;
190
191#[cfg(all(feature = "test", feature = "kobo"))]
192impl SettingKind for EnableKernLog {
193 fn identity(&self) -> SettingIdentity {
194 SettingIdentity::EnableKernLog
195 }
196
197 fn label(&self, _settings: &Settings) -> String {
198 fl!("settings-telemetry-enable-kernel-log")
199 }
200
201 fn fetch(&self, settings: &Settings) -> SettingData {
202 SettingData {
203 value: settings.logging.enable_kern_log.to_string(),
204 widget: WidgetKind::Toggle {
205 left_label: fl!("settings-general-toggle-on"),
206 right_label: fl!("settings-general-toggle-off"),
207 enabled: settings.logging.enable_kern_log,
208 tap_event: Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableKernLog)),
209 },
210 }
211 }
212
213 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
214 if let Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableKernLog)) = evt {
215 settings.logging.enable_kern_log = !settings.logging.enable_kern_log;
216 return Some(settings.logging.enable_kern_log.to_string());
217 }
218 None
219 }
220}
221
222#[cfg(all(feature = "test", feature = "kobo"))]
224pub struct EnableDbusLog;
225
226#[cfg(all(feature = "test", feature = "kobo"))]
227impl SettingKind for EnableDbusLog {
228 fn identity(&self) -> SettingIdentity {
229 SettingIdentity::EnableDbusLog
230 }
231
232 fn label(&self, _settings: &Settings) -> String {
233 fl!("settings-telemetry-enable-dbus-log")
234 }
235
236 fn fetch(&self, settings: &Settings) -> SettingData {
237 SettingData {
238 value: settings.logging.enable_dbus_log.to_string(),
239 widget: WidgetKind::Toggle {
240 left_label: fl!("settings-general-toggle-on"),
241 right_label: fl!("settings-general-toggle-off"),
242 enabled: settings.logging.enable_dbus_log,
243 tap_event: Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableDbusLog)),
244 },
245 }
246 }
247
248 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
249 if let Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableDbusLog)) = evt {
250 settings.logging.enable_dbus_log = !settings.logging.enable_dbus_log;
251 return Some(settings.logging.enable_dbus_log.to_string());
252 }
253 None
254 }
255}
256
257#[cfg(test)]
258mod tests {
259 use super::*;
260 use crate::settings::Settings;
261 use crate::view::settings_editor::kinds::ToggleSettings;
262 use crate::view::{Bus, EntryId, Event, ToggleEvent};
263 use std::collections::VecDeque;
264
265 mod logging_enabled {
266 use super::*;
267
268 #[test]
269 fn handle_toggle_disables_when_enabled() {
270 let setting = LoggingEnabled;
271 let mut settings = Settings::default();
272 settings.logging.enabled = true;
273 let mut bus: Bus = VecDeque::new();
274 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::LoggingEnabled));
275
276 let result = setting.handle(&event, &mut settings, &mut bus);
277
278 assert!(result.is_some());
279 assert!(!settings.logging.enabled);
280 }
281
282 #[test]
283 fn handle_toggle_enables_when_disabled() {
284 let setting = LoggingEnabled;
285 let mut settings = Settings::default();
286 settings.logging.enabled = false;
287 let mut bus: Bus = VecDeque::new();
288 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::LoggingEnabled));
289
290 let result = setting.handle(&event, &mut settings, &mut bus);
291
292 assert!(result.is_some());
293 assert!(settings.logging.enabled);
294 }
295
296 #[test]
297 fn handle_returns_none_for_wrong_event() {
298 let setting = LoggingEnabled;
299 let mut settings = Settings::default();
300 let mut bus: Bus = VecDeque::new();
301
302 let result = setting.handle(&Event::Select(EntryId::About), &mut settings, &mut bus);
303
304 assert!(result.is_none());
305 }
306
307 #[test]
308 fn handle_returns_none_for_wrong_toggle() {
309 let setting = LoggingEnabled;
310 let mut settings = Settings::default();
311 let mut bus: Bus = VecDeque::new();
312
313 let result = setting.handle(
314 &Event::Toggle(ToggleEvent::Setting(ToggleSettings::SleepCover)),
315 &mut settings,
316 &mut bus,
317 );
318
319 assert!(result.is_none());
320 }
321 }
322
323 mod log_level {
324 use super::*;
325
326 #[test]
327 fn handle_set_level_updates_settings() {
328 let setting = LogLevel;
329 let mut settings = Settings::default();
330 settings.logging.level = "INFO".to_string();
331 let mut bus: Bus = VecDeque::new();
332 let event = Event::Select(EntryId::SetLogLevel(tracing::Level::WARN));
333
334 let result = setting.handle(&event, &mut settings, &mut bus);
335
336 assert!(result.is_some());
337 assert_eq!(settings.logging.level, "WARN");
338 }
339
340 #[test]
341 fn handle_can_set_all_levels() {
342 let setting = LogLevel;
343 let mut settings = Settings::default();
344 let mut bus: Bus = VecDeque::new();
345
346 for level in [
347 tracing::Level::TRACE,
348 tracing::Level::DEBUG,
349 tracing::Level::INFO,
350 tracing::Level::WARN,
351 tracing::Level::ERROR,
352 ] {
353 let event = Event::Select(EntryId::SetLogLevel(level));
354 setting.handle(&event, &mut settings, &mut bus);
355 assert_eq!(settings.logging.level, level.to_string());
356 }
357 }
358
359 #[test]
360 fn handle_returns_none_for_wrong_event() {
361 let setting = LogLevel;
362 let mut settings = Settings::default();
363 let mut bus: Bus = VecDeque::new();
364
365 let result = setting.handle(&Event::Select(EntryId::About), &mut settings, &mut bus);
366
367 assert!(result.is_none());
368 }
369 }
370
371 #[cfg(feature = "otel")]
372 mod otlp_endpoint {
373 use super::*;
374 use crate::view::settings_editor::kinds::InputSettingKind;
375
376 #[test]
377 fn apply_text_sets_endpoint() {
378 let setting = OtlpEndpoint;
379 let mut settings = Settings::default();
380
381 let display = setting.apply_text("http://otel:4317", &mut settings);
382
383 assert_eq!(display, "http://otel:4317");
384 assert_eq!(
385 settings.logging.otlp_endpoint,
386 Some("http://otel:4317".to_string())
387 );
388 }
389
390 #[test]
391 fn apply_text_trims_whitespace() {
392 let setting = OtlpEndpoint;
393 let mut settings = Settings::default();
394
395 let display = setting.apply_text(" http://otel:4317 ", &mut settings);
396
397 assert_eq!(display, "http://otel:4317");
398 assert_eq!(
399 settings.logging.otlp_endpoint,
400 Some("http://otel:4317".to_string())
401 );
402 }
403
404 #[test]
405 fn apply_text_empty_clears_endpoint() {
406 let setting = OtlpEndpoint;
407 let mut settings = Settings::default();
408 settings.logging.otlp_endpoint = Some("http://old:4317".to_string());
409
410 let display = setting.apply_text("", &mut settings);
411
412 assert_eq!(display, "Not set");
413 assert_eq!(settings.logging.otlp_endpoint, None);
414 }
415
416 #[test]
417 fn apply_text_whitespace_only_clears_endpoint() {
418 let setting = OtlpEndpoint;
419 let mut settings = Settings::default();
420 settings.logging.otlp_endpoint = Some("http://old:4317".to_string());
421
422 let display = setting.apply_text(" ", &mut settings);
423
424 assert_eq!(display, "Not set");
425 assert_eq!(settings.logging.otlp_endpoint, None);
426 }
427 }
428
429 #[cfg(feature = "test")]
430 mod enable_kern_log {
431 use super::*;
432
433 #[test]
434 fn handle_toggle_enables_when_disabled() {
435 let setting = EnableKernLog;
436 let mut settings = Settings::default();
437 settings.logging.enable_kern_log = false;
438 let mut bus: Bus = VecDeque::new();
439 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableKernLog));
440
441 let result = setting.handle(&event, &mut settings, &mut bus);
442
443 assert!(result.is_some());
444 assert!(settings.logging.enable_kern_log);
445 }
446
447 #[test]
448 fn handle_toggle_disables_when_enabled() {
449 let setting = EnableKernLog;
450 let mut settings = Settings::default();
451 settings.logging.enable_kern_log = true;
452 let mut bus: Bus = VecDeque::new();
453 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableKernLog));
454
455 let result = setting.handle(&event, &mut settings, &mut bus);
456
457 assert!(result.is_some());
458 assert!(!settings.logging.enable_kern_log);
459 }
460
461 #[test]
462 fn handle_returns_none_for_wrong_event() {
463 let setting = EnableKernLog;
464 let mut settings = Settings::default();
465 let mut bus: Bus = VecDeque::new();
466
467 let result = setting.handle(&Event::Select(EntryId::About), &mut settings, &mut bus);
468
469 assert!(result.is_none());
470 }
471
472 #[test]
473 fn handle_returns_none_for_wrong_toggle() {
474 let setting = EnableKernLog;
475 let mut settings = Settings::default();
476 let mut bus: Bus = VecDeque::new();
477
478 let result = setting.handle(
479 &Event::Toggle(ToggleEvent::Setting(ToggleSettings::LoggingEnabled)),
480 &mut settings,
481 &mut bus,
482 );
483
484 assert!(result.is_none());
485 }
486 }
487
488 #[cfg(all(feature = "test", feature = "kobo"))]
489 mod enable_dbus_log {
490 use super::*;
491
492 #[test]
493 fn handle_toggle_enables_when_disabled() {
494 let setting = EnableDbusLog;
495 let mut settings = Settings::default();
496 settings.logging.enable_dbus_log = false;
497 let mut bus: Bus = VecDeque::new();
498 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableDbusLog));
499
500 let result = setting.handle(&event, &mut settings, &mut bus);
501
502 assert!(result.is_some());
503 assert!(settings.logging.enable_dbus_log);
504 }
505
506 #[test]
507 fn handle_toggle_disables_when_enabled() {
508 let setting = EnableDbusLog;
509 let mut settings = Settings::default();
510 settings.logging.enable_dbus_log = true;
511 let mut bus: Bus = VecDeque::new();
512 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::EnableDbusLog));
513
514 let result = setting.handle(&event, &mut settings, &mut bus);
515
516 assert!(result.is_some());
517 assert!(!settings.logging.enable_dbus_log);
518 }
519
520 #[test]
521 fn handle_returns_none_for_wrong_event() {
522 let setting = EnableDbusLog;
523 let mut settings = Settings::default();
524 let mut bus: Bus = VecDeque::new();
525
526 let result = setting.handle(&Event::Select(EntryId::About), &mut settings, &mut bus);
527
528 assert!(result.is_none());
529 }
530
531 #[test]
532 fn handle_returns_none_for_wrong_toggle() {
533 let setting = EnableDbusLog;
534 let mut settings = Settings::default();
535 let mut bus: Bus = VecDeque::new();
536
537 let result = setting.handle(
538 &Event::Toggle(ToggleEvent::Setting(ToggleSettings::LoggingEnabled)),
539 &mut settings,
540 &mut bus,
541 );
542
543 assert!(result.is_none());
544 }
545 }
546}