1 use std
::process
::{Command, Stdio}
;
4 use serde_json
::{json, Value}
;
6 use proxmox
::{sortable, identity}
;
7 use proxmox
::api
::{ApiHandler, ApiMethod, Router, RpcEnvironment}
;
8 use proxmox
::api
::schema
::*;
10 use crate::api2
::types
::*;
17 service
: Option
<&str>,
18 ) -> Result
<(u64, Vec
<Value
>), Error
> {
20 let mut args
= vec
!["-o", "short", "--no-pager"];
22 if let Some(service
) = service { args.extend(&["--unit", service]); }
23 if let Some(since
) = since { args.extend(&["--since", since]); }
24 if let Some(until
) = until { args.extend(&["--until", until]); }
26 let mut lines
: Vec
<Value
> = vec
![];
27 let mut limit
= limit
.unwrap_or(50);
28 let start
= start
.unwrap_or(0);
29 let mut count
: u64 = 0;
31 let mut child
= Command
::new("/bin/journalctl")
33 .stdout(Stdio
::piped())
36 use std
::io
::{BufRead,BufReader}
;
38 if let Some(ref mut stdout
) = child
.stdout
{
39 for line
in BufReader
::new(stdout
).lines() {
43 if count
< start { continue }
;
44 if limit
== 0 { continue }
;
46 lines
.push(json
!({ "n": count, "t": line }
));
51 log
::error
!("reading journal failed: {}", err
);
59 let status
= child
.wait().unwrap();
60 if !status
.success() {
61 log
::error
!("journalctl failed with {}", status
);
64 // HACK: ExtJS store.guaranteeRange() does not like empty array
68 lines
.push(json
!({ "n": count, "t": "no content"}
));
77 rpcenv
: &mut dyn RpcEnvironment
,
78 ) -> Result
<Value
, Error
> {
80 let (count
, lines
) = dump_journal(
81 param
["start"].as_u64(),
82 param
["limit"].as_u64(),
83 param
["since"].as_str(),
84 param
["until"].as_str(),
85 param
["service"].as_str())?
;
87 rpcenv
.set_result_attrib("total", Value
::from(count
));
93 pub const ROUTER
: Router
= Router
::new()
96 &ApiHandler
::Sync(&get_syslog
),
98 "Read server time and time zone settings.",
100 ("node", false, &NODE_SCHEMA
),
101 ("start", true, &IntegerSchema
::new("Start line number.")
105 ("limit", true, &IntegerSchema
::new("Max. number of lines.")
109 ("since", true, &StringSchema
::new("Display all log since this date-time string.")
110 .format(&SYSTEMD_DATETIME_FORMAT
)
113 ("until", true, &StringSchema
::new("Display all log until this date-time string.")
114 .format(&SYSTEMD_DATETIME_FORMAT
)
117 ("service", true, &StringSchema
::new("Service ID.")
125 "Returns a list of syslog entries.",
127 ("n", false, &IntegerSchema
::new("Line number.").schema()),
128 ("t", false, &StringSchema
::new("Line text.").schema()),