]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/node/journal.rs
switch from failure to anyhow
[proxmox-backup.git] / src / api2 / node / journal.rs
CommitLineData
81cc71c0
DM
1use std::process::{Command, Stdio};
2
f7d4e4b5 3use anyhow::{Error};
81cc71c0
DM
4use serde_json::{json, Value};
5use std::io::{BufRead,BufReader};
6
68ed0c62 7use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
81cc71c0
DM
8
9use crate::api2::types::*;
68ed0c62 10use crate::config::acl::PRIV_SYS_AUDIT;
81cc71c0
DM
11
12#[api(
13 protected: true,
14 input: {
15 properties: {
16 node: {
17 schema: NODE_SCHEMA,
18 },
19 since: {
20 type: Integer,
21 optional: true,
22 description: "Display all log since this UNIX epoch. Conflicts with 'startcursor'.",
23 minimum: 0,
24 },
25 until: {
26 type: Integer,
27 optional: true,
28 description: "Display all log until this UNIX epoch. Conflicts with 'endcursor'.",
29 minimum: 0,
30 },
31 lastentries: {
32 type: Integer,
33 optional: true,
34 description: "Limit to the last X lines. Conflicts with a range.",
35 minimum: 0,
36 },
37 startcursor: {
38 type: String,
39 description: "Start after the given Cursor. Conflicts with 'since'.",
40 optional: true,
41 },
42 endcursor: {
43 type: String,
44 description: "End before the given Cursor. Conflicts with 'until'",
45 optional: true,
46 },
47 },
48 },
49 returns: {
50 type: Array,
51 description: "Returns a list of journal entries.",
52 items: {
53 type: String,
54 description: "Line text.",
55 },
56 },
68ed0c62
DM
57 access: {
58 permission: &Permission::Privilege(&[], PRIV_SYS_AUDIT, false),
59 },
81cc71c0
DM
60)]
61/// Read syslog entries.
62fn get_journal(
63 param: Value,
64 _info: &ApiMethod,
65 _rpcenv: &mut dyn RpcEnvironment,
66) -> Result<Value, Error> {
67
68 let mut args = vec![];
69
70 if let Some(lastentries) = param["lastentries"].as_u64() {
71 args.push(String::from("-n"));
72 args.push(format!("{}", lastentries));
73 }
74
75 if let Some(since) = param["since"].as_str() {
76 args.push(String::from("-b"));
77 args.push(since.to_owned());
78 }
79
80 if let Some(until) = param["until"].as_str() {
81 args.push(String::from("-e"));
82 args.push(until.to_owned());
83 }
84
85 if let Some(startcursor) = param["startcursor"].as_str() {
86 args.push(String::from("-f"));
87 args.push(startcursor.to_owned());
88 }
89
90 if let Some(endcursor) = param["endcursor"].as_str() {
91 args.push(String::from("-t"));
92 args.push(endcursor.to_owned());
93 }
94
95 let mut lines: Vec<String> = vec![];
96
97 let mut child = Command::new("/usr/bin/mini-journalreader")
98 .args(&args)
99 .stdout(Stdio::piped())
100 .spawn()?;
101
102 if let Some(ref mut stdout) = child.stdout {
103 for line in BufReader::new(stdout).lines() {
104 match line {
105 Ok(line) => {
106 lines.push(line);
107 }
108 Err(err) => {
109 log::error!("reading journal failed: {}", err);
110 let _ = child.kill();
111 break;
112 }
113 }
114 }
115 }
116
117 let status = child.wait().unwrap();
118 if !status.success() {
119 log::error!("journalctl failed with {}", status);
120 }
121
122 Ok(json!(lines))
123}
124
125pub const ROUTER: Router = Router::new()
126 .get(&API_METHOD_GET_JOURNAL);