3 use crate::api_schema
::*;
4 use crate::api_schema
::router
::*;
5 use crate::api2
::types
::*;
7 use serde_json
::{json, Value}
;
10 use lazy_static
::lazy_static
;
11 use proxmox
::tools
::common_regex
;
12 use std
::process
::{Command, Stdio}
;
19 service
: Option
<&str>,
20 ) -> Result
<(u64, Vec
<Value
>), Error
> {
22 let mut args
= vec
!["-o", "short", "--no-pager"];
24 if let Some(service
) = service { args.extend(&["--unit", service]); }
25 if let Some(since
) = since { args.extend(&["--since", since]); }
26 if let Some(until
) = until { args.extend(&["--until", until]); }
28 let mut lines
: Vec
<Value
> = vec
![];
29 let mut limit
= limit
.unwrap_or(50);
30 let start
= start
.unwrap_or(0);
31 let mut count
: u64 = 0;
33 let mut child
= Command
::new("/bin/journalctl")
35 .stdout(Stdio
::piped())
38 use std
::io
::{BufRead,BufReader}
;
40 if let Some(ref mut stdout
) = child
.stdout
{
41 for line
in BufReader
::new(stdout
).lines() {
45 if count
< start { continue }
;
46 if limit
== 0 { continue }
;
48 lines
.push(json
!({ "n": count, "t": line }
));
53 log
::error
!("reading journal failed: {}", err
);
61 let status
= child
.wait().unwrap();
62 if !status
.success() {
63 log
::error
!("journalctl failed with {}", status
);
66 // HACK: ExtJS store.guaranteeRange() does not like empty array
70 lines
.push(json
!({ "n": count, "t": "no content"}
));
79 rpcenv
: &mut dyn RpcEnvironment
,
80 ) -> Result
<Value
, Error
> {
82 let (count
, lines
) = dump_journal(
83 param
["start"].as_u64(),
84 param
["limit"].as_u64(),
85 param
["since"].as_str(),
86 param
["until"].as_str(),
87 param
["service"].as_str())?
;
89 rpcenv
.set_result_attrib("total", Value
::from(count
));
95 pub static ref SYSTEMD_DATETIME_FORMAT
: Arc
<ApiStringFormat
> =
96 ApiStringFormat
::Pattern(&common_regex
::SYSTEMD_DATETIME_REGEX
).into();
99 pub fn router() -> Router
{
101 let route
= Router
::new()
105 ObjectSchema
::new("Read server time and time zone settings.")
106 .required("node", NODE_SCHEMA
.clone())
109 IntegerSchema
::new("Start line number.")
114 IntegerSchema
::new("Max. number of lines.")
119 StringSchema
::new("Display all log since this date-time string.")
120 .format(SYSTEMD_DATETIME_FORMAT
.clone())
124 StringSchema
::new("Display all log until this date-time string.")
125 .format(SYSTEMD_DATETIME_FORMAT
.clone())
129 StringSchema
::new("Service ID.")
133 ObjectSchema
::new("Returns a list of syslog entries.")
134 .required("n", IntegerSchema
::new("Line number."))
135 .required("t", StringSchema
::new("Line text."))