1use crate::Result;
2
3use std::sync::Arc;
4
5#[derive(Clone, Debug)]
6pub struct Journal {
7 inner: Arc<crate::Inner>,
8}
9
10impl Journal {
11 pub(crate) fn new(inner: Arc<crate::Inner>) -> Self {
12 Self { inner }
13 }
14
15 pub async fn query(
23 &self,
24 filter: crate::types::journal::JournalFilter,
25 ) -> Result<crate::types::journal::JournalResult> {
26 #[cfg(feature = "journal-cli")]
27 {
28 return crate::journal::cli::query_journalctl(&self.inner.opts, filter).await;
29 }
30
31 #[cfg(all(not(feature = "journal-cli"), feature = "journal-sdjournal"))]
32 {
33 return crate::journal::sdjournal::query_sdjournal(&self.inner.opts, filter).await;
34 }
35
36 #[cfg(all(not(feature = "journal-cli"), not(feature = "journal-sdjournal")))]
37 {
38 let _ = filter;
39 return Err(crate::Error::BackendUnavailable {
40 backend: "journald",
41 detail: "no journald backend enabled (enable journal-cli or journal-sdjournal)"
42 .to_string(),
43 });
44 }
45 }
46
47 pub async fn diagnose_unit_failure(
51 &self,
52 unit: &str,
53 opts: crate::types::journal::DiagnosisOptions,
54 ) -> Result<crate::types::journal::Diagnosis> {
55 let unit = crate::util::canonicalize_unit_name(unit)?;
56
57 #[cfg(feature = "tracing")]
58 tracing::info!(
59 unit = %unit,
60 limit = opts.limit,
61 max_bytes = opts.max_bytes,
62 max_message_bytes = opts.max_message_bytes,
63 "diagnose_unit_failure"
64 );
65
66 let status = crate::units::Units::new(self.inner.clone())
67 .get_status(&unit)
68 .await?;
69
70 let now = std::time::SystemTime::now();
71 let since = match now.checked_sub(opts.window_before) {
72 Some(t) => t,
73 None => std::time::UNIX_EPOCH,
74 };
75 let until = now.checked_add(opts.window_after);
76
77 let filter = crate::types::journal::JournalFilter {
78 unit: Some(unit),
79 since: Some(since),
80 until,
81 after_cursor: None,
82 limit: opts.limit,
83 max_bytes: opts.max_bytes,
84 max_message_bytes: opts.max_message_bytes,
85 timeout: opts.timeout,
86 parse_error: opts.parse_error,
87 };
88
89 let res = self.query(filter).await?;
90 Ok(crate::types::journal::Diagnosis {
91 status,
92 logs: res.entries,
93 truncated: res.truncated,
94 })
95 }
96}
97
98#[cfg(feature = "journal-cli")]
99mod cli;
100
101#[cfg(all(feature = "journal-sdjournal", not(feature = "journal-cli")))]
102mod sdjournal;