1#![deny(missing_docs)]
5
6#[cfg(all(target_os = "fuchsia", fuchsia_api_level_at_least = "NEXT"))]
13mod fuchsia;
14#[cfg(all(target_os = "fuchsia", fuchsia_api_level_at_least = "NEXT"))]
15use self::fuchsia as implementation;
16
17#[cfg(all(target_os = "fuchsia", not(fuchsia_api_level_at_least = "NEXT")))]
20mod fuchsia_28;
21#[cfg(all(target_os = "fuchsia", not(fuchsia_api_level_at_least = "NEXT")))]
22use self::fuchsia_28 as implementation;
23
24#[cfg(not(target_os = "fuchsia"))]
25mod portable;
26#[cfg(not(target_os = "fuchsia"))]
27use self::portable as implementation;
28
29pub use diagnostics_log_types::Severity;
30pub use implementation::*;
31
32pub(crate) fn install_panic_hook(prefix: Option<&'static str>) {
34 let previous_hook = std::panic::take_hook();
35 std::panic::set_hook(Box::new(move |info| {
36 let message = format!("{info}");
37 let prefix = prefix.unwrap_or("PANIC");
38 log::logger().log(
39 &log::RecordBuilder::new()
40 .level(log::Level::Error)
41 .line(Some(info.location().unwrap().line()))
42 .file(Some(info.location().unwrap().file()))
43 .key_values(&[("info", message.as_str())])
44 .args(format_args!("{prefix}"))
45 .build(),
46 );
47 previous_hook(info);
48 }));
49}
50
51pub trait SeverityExt {
53 fn severity(&self) -> Severity;
55
56 fn raw_severity(&self) -> u8 {
58 self.severity() as u8
59 }
60}
61
62impl SeverityExt for log::Metadata<'_> {
63 fn severity(&self) -> Severity {
64 match self.level() {
65 log::Level::Error => Severity::Error,
66 log::Level::Warn => Severity::Warn,
67 log::Level::Info => Severity::Info,
68 log::Level::Debug => Severity::Debug,
69 log::Level::Trace => Severity::Trace,
70 }
71 }
72}
73
74pub struct PublishOptions<'t> {
78 pub(crate) publisher: PublisherOptions<'t>,
79 pub(crate) install_panic_hook: bool,
80 pub(crate) panic_prefix: Option<&'static str>,
81}
82
83impl PublishOptions<'_> {
84 pub fn install_panic_hook(mut self, enable: bool) -> Self {
88 self.install_panic_hook = enable;
89 self
90 }
91
92 #[cfg(target_os = "fuchsia")]
95 pub fn always_log_file_line(mut self) -> Self {
96 self.publisher.always_log_file_line = true;
97 self
98 }
99
100 pub fn panic_prefix(mut self, prefix: &'static str) -> Self {
102 self.panic_prefix = Some(prefix);
103 self
104 }
105}
106
107macro_rules! publisher_options {
108 ($(($name:ident, $self:ident, $($self_arg:ident),*)),*) => {
109 $(
110 impl<'t> $name<'t> {
111 pub fn tags(mut $self, tags: &'t [&'t str]) -> Self {
118 let this = &mut $self$(.$self_arg)*;
119 this.tags = tags;
120 $self
121 }
122
123 pub fn enable_metatag(mut $self, metatag: Metatag) -> Self {
127 let this = &mut $self$(.$self_arg)*;
128 this.metatags.insert(metatag);
129 $self
130 }
131
132 pub fn minimum_severity(mut $self, severity: impl Into<Severity>) -> Self {
136 let this = &mut $self$(.$self_arg)*;
137 this.interest.min_severity = Some(severity.into().into());
138 $self
139 }
140 }
141 )*
142 };
143}
144
145publisher_options!((PublisherOptions, self,), (PublishOptions, self, publisher));