127 lines
3.4 KiB
Rust
127 lines
3.4 KiB
Rust
use std::process::{Command, Stdio};
|
|
|
|
use anyhow::{Error};
|
|
use serde_json::{json, Value};
|
|
use std::io::{BufRead,BufReader};
|
|
|
|
use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
|
|
|
|
use crate::api2::types::*;
|
|
use crate::config::acl::PRIV_SYS_AUDIT;
|
|
|
|
#[api(
|
|
protected: true,
|
|
input: {
|
|
properties: {
|
|
node: {
|
|
schema: NODE_SCHEMA,
|
|
},
|
|
since: {
|
|
type: Integer,
|
|
optional: true,
|
|
description: "Display all log since this UNIX epoch. Conflicts with 'startcursor'.",
|
|
minimum: 0,
|
|
},
|
|
until: {
|
|
type: Integer,
|
|
optional: true,
|
|
description: "Display all log until this UNIX epoch. Conflicts with 'endcursor'.",
|
|
minimum: 0,
|
|
},
|
|
lastentries: {
|
|
type: Integer,
|
|
optional: true,
|
|
description: "Limit to the last X lines. Conflicts with a range.",
|
|
minimum: 0,
|
|
},
|
|
startcursor: {
|
|
type: String,
|
|
description: "Start after the given Cursor. Conflicts with 'since'.",
|
|
optional: true,
|
|
},
|
|
endcursor: {
|
|
type: String,
|
|
description: "End before the given Cursor. Conflicts with 'until'",
|
|
optional: true,
|
|
},
|
|
},
|
|
},
|
|
returns: {
|
|
type: Array,
|
|
description: "Returns a list of journal entries.",
|
|
items: {
|
|
type: String,
|
|
description: "Line text.",
|
|
},
|
|
},
|
|
access: {
|
|
permission: &Permission::Privilege(&["system", "log"], PRIV_SYS_AUDIT, false),
|
|
},
|
|
)]
|
|
/// Read syslog entries.
|
|
fn get_journal(
|
|
param: Value,
|
|
_info: &ApiMethod,
|
|
_rpcenv: &mut dyn RpcEnvironment,
|
|
) -> Result<Value, Error> {
|
|
|
|
let mut args = vec![];
|
|
|
|
if let Some(lastentries) = param["lastentries"].as_u64() {
|
|
args.push(String::from("-n"));
|
|
args.push(format!("{}", lastentries));
|
|
}
|
|
|
|
if let Some(since) = param["since"].as_str() {
|
|
args.push(String::from("-b"));
|
|
args.push(since.to_owned());
|
|
}
|
|
|
|
if let Some(until) = param["until"].as_str() {
|
|
args.push(String::from("-e"));
|
|
args.push(until.to_owned());
|
|
}
|
|
|
|
if let Some(startcursor) = param["startcursor"].as_str() {
|
|
args.push(String::from("-f"));
|
|
args.push(startcursor.to_owned());
|
|
}
|
|
|
|
if let Some(endcursor) = param["endcursor"].as_str() {
|
|
args.push(String::from("-t"));
|
|
args.push(endcursor.to_owned());
|
|
}
|
|
|
|
let mut lines: Vec<String> = vec![];
|
|
|
|
let mut child = Command::new("/usr/bin/mini-journalreader")
|
|
.args(&args)
|
|
.stdout(Stdio::piped())
|
|
.spawn()?;
|
|
|
|
if let Some(ref mut stdout) = child.stdout {
|
|
for line in BufReader::new(stdout).lines() {
|
|
match line {
|
|
Ok(line) => {
|
|
lines.push(line);
|
|
}
|
|
Err(err) => {
|
|
log::error!("reading journal failed: {}", err);
|
|
let _ = child.kill();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let status = child.wait().unwrap();
|
|
if !status.success() {
|
|
log::error!("journalctl failed with {}", status);
|
|
}
|
|
|
|
Ok(json!(lines))
|
|
}
|
|
|
|
pub const ROUTER: Router = Router::new()
|
|
.get(&API_METHOD_GET_JOURNAL);
|